zoukankan      html  css  js  c++  java
  • 分支定界法

    1、定义

    分支定界法(branch and bound)是一种求解整数规划问题的最常用算法。这种方法不但可以求解纯整数规划,还可以求解混合整数规划问题。

    2、算法步骤

    第1步:放宽或取消原问题的某些约束条件,如求整数解的条件。如果这时求出的最优解是原问题的可行解,那么这个解就是原问题的最优解,计算结束。否则这个解的目标函数值是原问题的最优解的上界。
    第2步:将放宽了某些约束条件的替代问题分成若干子问题,要求各子问题的解集合的并集要包含原问题的所有可行解,然后对每个子问题求最优解。这些子问题的最优解中的最优者若是原问题的可行解,则它就是原问题的最优解,计算结束。否则它的目标函数值就是原问题的一个新的上界。另外,各子问题的最优解中,若有原问题的可行解的,选这些可行解的最大目标函数值,它就是原问题的最优解的一个下界。
    第3步:最优解目标函数值已小于这个下界的子问题,其可行解中必无原问题的最优解,可以放弃。对最优解(不是原问题的可行解)的目标函数值大于这个下界的子问题,都先保留下来,进入第4步。
    第4步:在保留下的所有子问题中,选出最优解目标函数值最大的一个,重复第1步和第2步。如果已经找到该子问题的最优可行解,那么其目标函数值与前面保留的其他问题在内的所有子问题的可行解中目标函数值最大者,将它作为新的下界,重复第3步,直到求出最优解。

    3、我的理解

    • 放宽条件;各分支问题最优解最优者定上界,各分支问题最优可行解最优者定下界;选一个最优解中不符合限制条件的x值,根据x值对该子问题分支,继续求。最优解最优者=最优可行解最优者(最优解最优者符合限制条件),即终结。
    • 始终从最优解最大的一个子问题开始分支、定界……
    • 始终维护更新一个子问题集合。
    • 终结条件:
      • 最优解最优者=最优可行解最优者(最优解最优者符合限制条件),即终结。
      • 各个子问题的最优解<下界,子问题终结,被放弃。
      • 松弛问题没有可行解,原问题也没有可行解
      • 所有子问题已处理完,没有找到,原问题没有可行解。
    • 算法思想如下:
    • /****
      设min<=目标函数值G<=max,flag表示某子问题是否已解(初始值为0),数组P[ ]存放当前所有子问题,数组B[ ]暂存每轮求解的问题的最优解。
      ****/
      
      1、将问题放入P[ ]。
      2、对P[ ]中的每个未解问题:
         计算最优解,存入B[ ];
         若该最优解<min,则从P[ ]中删掉该问题,continue;  //减枝
         //判断最优解是否是可行解,
          若是,则是该问题的最优可行解,
              若该问题是原问题,则得解,return;
              置flag=1;
              若该解>min,
          则min=当前解。
                  若max==min,则得解,return3、寻找B[ ]中的最优值。
         若该最优值>max,则max=当前最优值。
      4、分解该最优值问题为n个子问题,将这n个子问题加入P[ ],并置相应flag=0,执行2~4.
      5、若P中不存在未解问题,则问题无解。
    • 算法描述如下:
       1 /***********
       2     设min<=目标函数值G<=max,
       3     flag表示某子问题是否已解,
       4     数组P[ ]存放当前所有子问题.
       5     数组B[]暂存每一轮求解中的最优解。
       6 ************/
       7 
       8 BranchAndBound()
       9 {
      10     将问题放入P[ ]。
      11     while( P[]中有未解问题 )
      12     {
      13         定义数组B[];
      14 
      15         for( ;P[ ]中的每个未解问题; )    //一轮一轮求解
      16         {
      17 
      18             计算最优解;
      19             if( 该放松问题无可行解 )     //剪枝
      20             {
      21                 if( 该问题是原问题 )
      22                     return//出口1:无解
      23                 从P中删除此问题;
      24                 continue;
      25             }
      26             保存最优解到B[]中;
      27 
      28             if(最优解<min)               //剪枝
      29             {
      30                 从P[ ]中删掉该问题;
      31                 continue32             }
      33 
      34             if( 最优解是可行解 )
      35             {
      36                 if( 该问题是原问题 )    //出口2:有解
      37                 {
      38                     得解;
      39                     return;
      40                 }
      41                 置flag=142                 if( 该解>min )          //更新下界
      43                 {
      44                     min=当前解。
      45                     if( max==min )      //出口3:有解
      46                     {
      47                         得解;
      48                         return;
      49                     }
      50                 }
      51             }
      52         }
      53 
      54         寻找B[ ]中的最最优值。
      55         if( 该最优值>max )              //更新上界
      56             max = 该最优值。
      57         分解该最优值问题为n个子问题,将这n个问题加入到P[]中。   //分支
      58     }
      59     return;   //P中不存在未解问题,问题无解。出口4:无解
      60 }
    • 例子:
  • 相关阅读:
    守护线程与普通线程
    Java中实现多线程的两种方式之间的区别
    Python os.dup() 方法
    Python os.closerange() 方法
    Python os.close() 方法
    Python os.chroot() 方法
    Python os.chmod() 方法
    JavaScript——基本包装类型
    javascript——function类型(this关键字)
    常用的正则
  • 原文地址:https://www.cnblogs.com/hf-cherish/p/3468205.html
Copyright © 2011-2022 走看看