zoukankan      html  css  js  c++  java
  • 数模常用算法系列--整数线性规划(分枝定界法)、整数非线性规划(蒙特卡洛法)

    整数线性规划求解----分枝定界法

    什么是整数规划?

    ​ 线性规划中的变量(部分或全部)限制为整数时,称为整数规划。若在线性规划模型中,变量限制为整数,则称为整数线性规划。目前所流行的求解整数规划的方法,往往只适用于整数线性规划。目前还没有一种方法能有效地求解一切整数规划。

    整数规划的分类

        - 变量全限制为整数时,称(完全)整数规划
    
        - 变量部分限制为整数时,称混合整数规划			
    

    什么是分枝定界法

    ​ 原理如下:

    ​ 设有最大化的整数规划问题A,与它相应的线性规划为问题B,从解问题B开始,若其最优解不符合A的整数条件,那么B的最优目标函数必是A的最优目标函数(z^*)的上界(overline{z});而A的任意可行解的目标函数值将是 (z^*)的一个下界(underline z) ,分枝定界法就是将B的可行域分成子区域的方法。逐步减小(overline z)和增大(underline z)最终求到(z^*)

    ​ 本质就是个分治回溯,逼近最大值的算法。Matlab算法如下:(强烈警告,(不会验证)由于比较懒,并未对算法正确性验证,思路上验证了一下没问题就码上来了,如果有错,请一定联系~~)

    	% c,A,Aeq,Beq,LB,UB,是linprog函数的相关参数,知道了它们就可以求出对应的线性规划最优解,
    	% now是目前已经知道的整数解的最大值
    	function y = control(c,A,Aeq,Beq,LB,UB,now)
        	ret = 0; 
        	[x,fval] = linprog(c,A,Aeq,Beq,LB,UB); % x是最优解的解向量,fval是对应的函数值
        	if fval < now  
            	 y = fval;
            	 return;
        	end   % 如果得到的当前最优解fval小于已知的now,那说明最优整数解不在这个区间,则剪枝返回。
        	for i = 1 : length(x)
            	if rem(x(i),1) ~= 0  % rem(x,1)如果返回值不为0,则表示是小数。遍历x,找到第一个小数xi.
              	 NUB = UB; 
              	 NLB = LB;
              	 NUB(i) = floor(x(i)); % 把xi对应的上界更新为xi的向下取整。
              	 NLB(i) = ceil(x(i)); % 把xi对应的下界更新为xi的向上取整。
               	 fval1 = control(c,A,Aeq,Beq,LB,NUB,now);  %分成了两个区间, 原来下界~向下取整
                now = max(fval1,now);
              	 fval2 = control(c,A,Aeq,Beq,NLB,UB,now);  % 向上取整~原来上届
               	 ret = max(ret,fval1); % 更新得到整数最优解,并退出。
                 ret = max(ret,fval2); 
                 break
                end
                if  i == length(x)  %如果每个xi都是整数,直接退出
                    y = ret;
                    return ;
                end
            end
            if j == length(x)+1   %如果当前已经是整数最优,返回fval,否则返回ret。
                 y = fval;
            end
        
       end
    

    非线性整数规划--蒙特卡洛算法(随机取样法)

    什么是非线性规划?

    ​ 就是自变量不再是线性的规划。没错就是这个。

    蒙特卡洛算法

    ​ 对于非线 性整数规划目前尚未有一种成熟而准确的求解方法,那么找到一个相对满意的解就成了主要需求。

    ​ 蒙特卡洛算法是一种大量随机取样枚举解,以达到存在一种解,其函数值落在了我们期望的高值区不要问我什么是高值区)。

    ​ 那么具体多少次枚举合适呢?这是相对于问题而言的,举个例子:

    (0leq x_i leq 99 ,1 leq i leq 5, y = x_1^2 + x_2^2+3x_3^2+4x_4^2+2x_5^2-8x_1-2x_2-3x_3-x_4-2x_5) ,

    ​ 解空间大小为(100^5 = 10^{10}),太大了,枚举不了

    ​ 如果选择随机采样1e6,假设最优点不是孤立的奇点,并设目标函数落在可以接受的高值区的概率是0.00001,那么存在一个点落在高值区的概率为 1-(0.99999^{1000000}) (approx) 0.999954602,显然这个概率是可以接受的,也即是我们认为通过随机采样1e6,是能够得到满足期望的解。

    ​ 随机采样的算法就不写了,因为太懒了(因为不会)。

    今日感触:matlab的库函数是真的多,基础语法还是不行啊,以及数模的算法还挺有意思的,虽然高大上,其实也就那样。

    -----9.10 更新
    ~~

    规划问题还是用lingo吧,太方便了。

  • 相关阅读:
    ajax专题
    luogu P1346 电车 最短路
    luogu P1462 通往奥格瑞玛的道路 最短路
    luogu P1328 生活大爆炸版石头剪刀布
    luogu P1315 联合权值 枚举
    luogu P1156 垃圾陷阱 背包问题
    luogu P1217 回文质数 枚举
    luogu P3650 滑雪课程设计 枚举
    luogu1209 修理牛棚 贪心
    luogu P1223 排队接水 贪心
  • 原文地址:https://www.cnblogs.com/backkom-buaa/p/11494398.html
Copyright © 2011-2022 走看看