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吧,太方便了。

  • 相关阅读:
    Solution -「LOCAL」客星璀璨之夜
    Solution -「LOCAL」割海成路之日
    aaa
    wendang
    OSS架构
    MySQL事务
    1292分数和
    printf使用方法 (c++)
    1024与圆相关的计算
    Js 之echarts世界地图与汉化
  • 原文地址:https://www.cnblogs.com/backkom-buaa/p/11494398.html
Copyright © 2011-2022 走看看