数学建模、运筹学之整数规划(原理、例题、代码)

  • 一、何为整数规划?
  • 二、整数规划与线性规划
  • 三、分枝定界法
  • 四、0-1整数规划


一、何为整数规划?

  • 整数规划具有深远的实际应用价值,因为现实生活中的规划、最优化问题大部分不是实数范围的规划而是整数规划,比如工人的数量、所需多台机器的数量等等。而整数规划并不像看起来那么简单,单纯将线性规划最优解取整得到的甚至都不一定是可行解。因此整数规划需要区分于线性规划独立设计算法解决,目前仍未针对整数规划发现多项式级别的算法。
  • 不加特别说明的情况下,我们所说的整数规划实际上是整数线性规划。本文仍旧简称整数规划,因为整数非线性规划所能掌握的规律少之又少。
  • 想了解整数规划的定义及含义,我们就需要拿它跟一般线性规划做对比。线性规划的变量取值可以是整数也可以是小数,而整数规划的变量取值部分或者全部限制为整数。因此我们可以理解为:整数规划比一般线性规划缩小了搜索范围,一般线性规划的最优值(最大或者最小)一定等于或者优于整数规划最优值。
  • 进而根据整数规划变量取值范围的进一步限定,可以将整数规划划分为:纯整数规划(全部变量取值范围限制为整数)、混合整数规划(部分变量选取值范围限制为整数)、0-1整数规划(全部变量只可取0或1)。
  • 整数规划问题不同类型所适用的算法不同。常用求解算法如下:分枝定界法割平面法隐枚举法匈牙利法蒙特卡洛法。。。

二、整数规划与线性规划

  • 线性规划变量的取值范围是实数范围,也就是说最优解所对应的变量取值可以是整数也可以是小数。而整数规划变量的取值范围是整数范围,因此整数规划问题相较于对应的线性规划问题缩小了搜索范围。
  • 下面我们来看一下整数规划最优解与其对应的线性规划最优解之间的关系:1.如果线性规划无可行解,那么整数规划同样无可行解。2.如果线性规划最优解变量取值满足整数规划要求,整数规划的最优解同线性规划。3.如果线性规划最优解变量取值不满足整数规划要求,整数规划可能无可行解,也可能有可行解但最优解变差。

三、分枝定界法

  • 分枝定界法适用于求解完全整数规划混合整数规划,混合整数规划相比较而言更加简单,只需要针对非限定为整数的变量不分枝即可。
  • 我们首先来了解一下分枝定界法中三个基本操作的含义。分枝:将全部可行解空间分割为越来越小的子集;定界:对于分枝后的每一个子集计算目标函数值得上界与下界;剪枝:根据上下界忽略掉超出界限得部分可行解。下面我们首先通过一个例题,以手写算法得方式来感受一下算法过程。
  • 总结来说,分枝定界算法类似于一棵树得生成过程。分枝操作便是向下延申树杈,而算法的终止条件就是这棵树生长到“不能再生长”为止,也就是说树的末端长出了“叶子节点”。那么哪些情况下会生长出叶子节点呢?
  • 1.如果某个节点因为超出上下界而发生剪枝,那么该节点就生长为一个叶子节点。2.如果某个节点满足整数规划的要求,那么该节点也生长为一个叶子节点,并且判断、更新当前最大下界。3.如果某个节点无可行解,那么该节点也生长为一个叶子节点。总而言之,叶子节点就是无法再分枝的节点。
  • 总结来说,分枝定界法多次计算线性规划,缩小搜索范围,逼近整数规划的最优解。针对线性规划问题我们已经有了高效便捷的算法,因此多次计算线性规划问题解决整数规划问题同样具有效率。
  • 最开始先当作线性规划问题求解,得到的最优解作为整数规划最优值的上界。任选解中一个非整数变量,针对其进行分枝,一直分枝到整棵树无法再生长为止。途中遇到符合整数规划的情况,则作为可行解更新最优值的最大下界。当算法停止时,下界就代表整数规划的最大值,也就是此时最优值就是下界值。
  • 上图中有两个错误,第一个错误是整数规划最优值的上界不应该更新,应该始终为全局线性规划最优值。第二个错误是最后的结果不应该是由区间夹出来,而是算法停止时下界值就是最优值。
  • Lingo代码如下:
model:
max=5*x1+8*x2;
x1+x2<6;
5*x1+9*x2<45;
@gin(x1);
@gin(x2);
end

四、0-1整数规划

  • 0-1整数规划顾名思义就是线性规划问题中,变量不仅仅约束为整数,还要约束为0或1的二进制变量,故0-1整数规划也称为二进制规划
  • 0-1整数规划相较于普通的整数规划而言,搜索范围小了很多,每个变量只有0或者1两种取值,给枚举带来了可能。但python 整数规划 运筹学 运筹学excel整数规划求解_算法时间复杂度仍然无法实现大规模的完全遍历。因此我们针对0-1整数规划提出了隐枚举法(条件过滤法)
  • 隐枚举法:首先试探性求出一个可行解,以它的目标函数值添加一个过滤条件,小于该目标函数值的解直接舍弃不用审核约束条件。将所有可能的解枚举并从头开始筛选,如果某个解的目标函数值小于过滤条件则不用审核其他约束条件直接舍弃,如果某个解既满足过滤条件又满足约束条件则更新过滤条件。直至枚举所有情况算法结束。
  • 总结来说隐枚举法在枚举部分解的过程中,只检查过滤条件而不用检查约束条件。隐枚举法的约束条件分为两部分,其中一条是过滤条件,也就是目标函数知道的要求,其余的是原始约束条件。不满足过滤条件的直接舍弃;满足过滤条件但不满足原始约束条件的不是可行解;同时满足过滤条件和原始约束条件的是当前最优解,用来更新过滤条件。
  • Lingo代码如下所示:
model:
max=3*x1-2*x2+5*x3;
x1+2*x2-x3<2;
x1+4*x2+x3<4;
x1+x2<3;
4*x2+x3<6;
@bin(x1);
@bin(x2);
@bin(x3);
end