蒙特卡洛模拟(3)————求解有约束的非线性规划问题

前言

在人们的生产实践中,经常会遇到如何利用现有资源来安排生产,以取得最大经济效益的问题。此类问题构成了运筹学的一个重要分支--数学规划
如果目标函数或约束条件中包含非线性函数,就称这种规划问题为非线性规划问题。一般说来,解非线性规划要比解线性规划问题困难得多,也不像线性规划有单纯形法这一通用方法,非线性规划目前还没有适于各种问题的一般算法,各个方法都有自己特定的适用范围。
本章来介绍用计算机生成随机数的方法来求解非线性规划问题

一、问题提出

二、蒙特卡罗模拟的大体思路

1.求出每个变量的大致范围

2.生成随机数进行模拟试验

在试验中,由于我们求的只是一个大致范围,因此我们需要先判断随机数是否满足精确的约束。
在满足的前提下,再将这个随机数带入表达式,判断其是否是最大的

三、手动计算每个变量的大致范围

1.处理等式问题————进行降维

由x1-x2=10,得到x2=x1-10,那么原函数就可以转化为f(x)=x1(x1-10)x3,相当于降了一维。但是在代码部分,这一步的降维体现在不用再生成一个新的随机数

2.处理不等式问题————得到大致范围

(1)先处理简单的约束,得到变量范围

因为 10<=x2<=20,则20<=x1<=30(由x1-x2=10)

(2)对复杂的约束进行放缩,得到变量范围

四、代码求解————进行计算机模拟

1.设置数字格式

format long g
matlab默认会将数字保留四位小数,若太大会用科学计数法来表示,但是在我们的规划问题中,我们想要得到具体的数值,因此输入此命令可以将Matlab的计算结果显示为一般的长数字格式

2.生成随机数与变量初始化

n=10000000; %生成的随机数组数
x1=unifrnd(20,30,n,1);  % 生成在[20,30]之间均匀分布的随机数组成的n行1列的向量构成x1
x2=x1 - 10;
x3=unifrnd(-10,16,n,1);  % 生成在[-10,16]之间均匀分布的随机数组成的n行1列的向量构成x3
fmax=-inf; % 初始化函数f的最大值为负无穷(后续只要找到一个比它大的我们就对其更新)

3.输入循环进行模拟

在此步中,我们将x1,x2,x3的数值构造乘了一个新的x向量,这样每次循环都可以生成一个3个数的向量,代表这一次循环的x1,x2,x3
然后,判断是否满足条件,如果满足条件就计算函数值,进行迭代最大值

for i=1:n
    x = [x1(i), x2(i), x3(i)];  %构造x向量, 这里千万别写成了:x =[x1, x2, x3]
    if (-x(1)+2*x(2)+2*x(3)>=0)  &  (x(1)+2*x(2)+2*x(3)<=72)     % 判断是否满足条件
        result = x(1)*x(2)*x(3);  % 如果满足条件就计算函数值
        if  result  > fmax  % 如果这个函数值大于我们之前计算出来的最大值
            fmax = result;  % 那么就更新这个函数值为新的最大值
            X = x;  % 并且将此时的x1 x2 x3保存到一个变量中
        end
    end
end

4.输出结果

disp(strcat('蒙特卡罗模拟得到的最大值为',num2str(fmax)))
disp('最大值处x1 x2 x3的取值为:')
disp(X)

五、缩小范围重新模拟得到更加精确的取值

我们上一步得到了最大值处x1 x2 x3的取值为:22.5897459433039 12.5897459433039 12.1153738601129
因此我们可以将x1的下界从20提高到22,x3的确界从[-10,16],缩小到[11,13],然后进行再次进行循环与模拟

x1=unifrnd(22,23,n,1);  % 生成在[22,23]之间均匀分布的随机数组成的n行1列的向量构成x1
x2=x1 - 10;
x3=unifrnd(11,13,n,1);  % 生成在[11,13]之间均匀分布的随机数组成的n行1列的向量构成x3
posted @ 2024-08-04 16:30  卢宇博  阅读(74)  评论(0编辑  收藏  举报