03 Monte Carlo方法求解非线性规划(01)


0.说明

  • 本文是鸡年新年计划的内容之一:每周学习一个数学模型,写一篇总结,记录自己学到的东西和遇到的问题。
  • 这些文章并不是相关模型的全面介绍,也不是从最基础的开始,所以不一定适合数学模型的beginner,但都是些很实际的技术,希望能帮到你。
  • 本文的重点是使用Monte Carlo方法求解非线性规划。

1.向大家求助的问题

关于下面的这些问题,我迫切的需要你的帮助,哪怕是一些网址和信息,所以,感谢你给我发邮件[email protected]或直接加我QQ好友:117829132(请一定注明“帮助你”)或直接在评论中留言。

1.Monte Carlo方法求解非线性规划,取多少个点是至关重要的,欢迎你告诉我更多实用的、确定点数的方法。

2.一个线性规划模型记为M,限制其中某些(或全部)决策变量只能取整数后得到一个整数线性规划,记为M’。即使M有最优解,M’也有可能甚至没有可行解,为什么?

2. 用Monte Carlo 方法求解如下非线性整数规划

minz=x21+x22+3x23+4x24+2x258x12x23x3x42x5

s.t.5i=1xi400x1+2x2+2x3+x4+6x58002x1+x2+6x3200x3+x4+5x52000xi99,i=1,,5

使用MATLAB编写程序求解,需要编写两个程序:

计算给定点的目标函数值和约束条件值的程序如下:

function [ f, g ] = ex2_6( x )
f = [1 1 3 4 2] * (x.^2)' - [8 2 3 1 2] * x';
g = [ sum(x) - 400
    [1 2 2 1 6] * x' - 800
    [2 1 6 0 0] * x' - 200
    [0 0 1 1 5] * x' - 200];

随机选取点进行验证和统计的程序如下:

fix(clock)  %显示当前时刻,也就是程序开始运行的时刻
x00=[];p00=[];t=[];%初始化三个变量,用于存放最优解(x00)、最优值(p00)和每个单次(取10^6个点)进行计算的时间,用于后续的分析
for k=1:3000    %为了测试性能和保证准确性,进行3000个单次的循环
rand( 'state', sum(clock)); %初始化随机数的种子
tic;        %开始计时
p0 = 0; x0 = 0; %初始化这个单次的最优值和最优解
for i = 1:10^6  %共选取10^6个点
    x = randi(99, 1, 5);    %随时生成一个1行5列的x,每个元素是1至99之间的整数
    [f, g] = ex2_6(x);      %计算目标函数和约束条件的值
    if all(g <= 0)          %如果约束条件全部满足
        if f>p0
            p0 = f; x0 = x; %如果该值处的目标函数值比当前的最优值还大,那么更新最优值和最优解
        end
    end
end
%x0, p0
x00(k, :) = x0;     %记录每个单次的最优解
p00(k, :) = p0;     %记录每个单次的最优值
t(k)=toc;           %记录每个单次的运行时间
end
x00
p00
fix(clock)          %显示全部程序结束的时刻
t

上述程序共运行3000个单次,每个单次选择10^6个点进行验证。3000个单次共耗时36815秒、合计613.5793分钟、10.2263小时,比事前预估的时间少30几分钟。

用Monte Carlo方法找到的最优解是[41 99 3 99 17],最优值是,50623

该问题也可以用Lingo精确求解,准确的最优解是:[50 99 0 99 20],最优值是51568。
二者之间的差约为1.83%,对于很多问题而言,精度已经足够了。

2.关于randi函数和randint函数的异同

第一版的程序中,我使用的是randint函数来生成随机数,每个单次运行时间大约1400多秒,合计24分钟左右。每个单次选取10^6个点进行验证。

随后,按照MATLAB的提示,我换成randi函数,则每个单次的运行时间剧减为13至14秒之间。

开始我以为是对于程序的其他修改导致的,于是,我做了两个版本的程序,这两个版本之间只有该函数不同。尝试运行后randi版本的时间仍然是14秒左右。

为了保险起见,我还在重启电脑前后测试了randi版本的运行时间,结果是没有变化,也就是说,可以排除之前运行的程序可能残留的初值导致的运行时间的减少。

所以,我的结论是,使用randi函数生成随机整数,运行时间是使用较早版本MATLAB中的randint的时间1.1%,可以大幅度的提高仿真效率!!

3. 如何确定选取多少点

用Monte Carlo方法求解非线性规划时,一个非常重要的任务就是要确定选取多少点,点数过多则计算时间过长;点数太少则结果的准确性就会较差,如何取点是非常重要的。上述问题是纯整数规划,每个x可以取0至99共100个点,所以,全部验证所有可能性需要(100)^5=10^10个点,需要耗费大量的时间。

本文给出的,是验证10^6个点,下面粗略的说明,为什么验证10^6个点就足够了?(不失一般性,可以建设最优值点不是孤立的奇点)

假设每个点处的函数值落在高值区的可能性为0.01和0.00001,则当验证10^6个点后,至少有一个点落在高值区的概率为

10.9910000000.999910010.9999910000000.999954602

可见,我们验证10^6个点就可以在高值区找到一个点的可能性还是非常高的。

需要注意的是,上述叙述中使用的是“高值区”,而不是最优点,这二者是不同的,请仔细区分。

未完待续

猜你喜欢

转载自blog.csdn.net/cgch_cn/article/details/55253796
今日推荐