小白自学数学建模丨M002 - 整数规划(ILP)

M002 - 整数规划 (ILP)

定义

数学规划中二点变量(部分或全部)限制位整数时,称为整数规划。
若在线性规划模型中,变量限制为整数,则称为整数线性规划。

分类

  1. 变量全限制为整数时,称纯(完全)整数规划。
  2. 变量部分限制为整数的,称混合整数规划。

特点

  1. 原线性规划有最优解,当自变量限制为整数后,其整数规划解出现下述情况
    • 原线性规划最优解全是整数,则整数规划最优解与线性规划最优解一致。
    • 整数规划无可行解。
    • 有可行解(当然就存在最优解),但最优解值变差。
  2. 整数规划最优解不能按照实数最优解简单取整而获得。

相关问题

e.g. 合理下料

e.g. 建厂问题

e.g. 指派问题

e.g. 投资问题

e.g. 互斥约束问题

e.g. 固定费用问题

具体分析

依照决策变量取整要求的不同, 整数规划可分为

  • 纯整数规划: 所有决策变量要求取非负整数(这时引进的松弛变量和剩余变量可以不要求取整数)。
  • 全整数规划: 除了所有决策变量要求取非负整数外,系数\(a_{ij}\)和常数\(b_i\)也要求取整数(这时引进的松弛变量和剩余变量也必须是整数)。
  • 混合整数规划: 只有一部分的决策变量要求取非负整数,另一部分可以取非负实数。
  • 0-1整数规划: 所有决策变量只能取 0 或 1 两个整数。

整数规划与线性规划的关系

整数规划可行解是松弛问题可行域中的整数格点;
ILP最优值小于或等于松弛问题的最优值;
松弛问题无可行解, 则整数规划无可行解;
松弛问题最优解满足整数要求, 则该最优解为整数规划最优解;

整数线性规划的求解方法

从数学模型上看整数规划似乎是线性规划的一种特殊形式,
求解只需要在线性规划的基础上通过舍入取整,寻求满足整数要求的解即可。

分支定界算法

不考虑整数限制先求出相应松弛问题的最优解,

  • 若松弛问题无可行解, 则ILP无可行解;
  • 若求得的松弛问题最优解符合整数要求, 则是ILP的最优解;
  • 若不满足整数条件, 则任选一个不满足整数条件的变量\(x_{i}^{0}\)
    来构造新的约束添加到松弛问题中形成两个子问题\(x_i \le [x_{i}^{0}] \ ;\ x_i \ge [x_{i}^{0}] + 1\)
  • 依次在缩小的可行域中求解新构造的线性规划的最优解,并重复上述过程,直到子问题无解或有整数最优解(被查清)。

割平面算法

  • 如果松弛问题(P0)无解, 则(P)无解;
  • 如果(P0)的最优解为整数向量,则也是(P)的最优解;
  • 如果(P0)的解含有非整数分量,则对(P0)增加割平面条件:即对(P0)增加一个线性约束,将(P0)的可行区域割掉一块,使得非整数解恰好在割掉的一块中,但又没有割掉原问题(P)的可行解,得到问题(P1),重复上述的过程。

割平面算法基本步骤

  1. 求解线性规划最优解

\[x_i + \sum a_{ik}x_k = b_i \]

\[a_{ik} = [a_{ik}] + (a_{ik} - La_{ik}) = [a_{ik}] + f_{ik} \]

\[b_i = [b_i] + (b_i - Lb_i) = [b_i] + f_i \]

\[x_i + \sum [a_{ik}]x_k + \sum [f_{ik}]x_k = [b_i] + f_i \]

\[x_i + \sum [a_{ik}x_k - [b_i] = - \sum [f_{ik}]x_k + f_i \]

互斥约束的推广

从下述p个约束条件中恰好选择q个约束条件\(\displaystyle\sum_{j=1}^{n} a_{ij}x_j \le b_i (i = 1, 2, \cdots, p)\)

\[\begin{cases} \displaystyle\sum_{j=1}^{n} a_{ij}x_j \le b_i + My_i \\ \displaystyle\sum_{i=1}^{p} y_i = p - q \end{cases} (i = 1, 2, \cdots, p) \]

指派问题的标准形式

有n个人和n项工作,已知第i个人做第j项工作的代价为\(c_{ij} (i, j=1, \cdots, n)\),
要求每项工作只能交与其中一人完成,每个人只能完成其中一项工作,问如何分配可使总代价最少?
指派问题的系数矩阵:

\[C = (c_{ij})_{n \times n} = \begin{bmatrix} {c_{11}}&{c_{12}}&{\cdots}&{c_{1n}}\\ {c_{21}}&{c_{22}}&{\cdots}&{c_{2n}}\\ {\vdots}&{\vdots}&{\ddots}&{\vdots}\\ {c_{n1}}&{c_{n2}}&{\cdots}&{c_{nn}}\\ \end{bmatrix} \]

i行元素 —— 第i个人完成各项任务的代价
j列元素 —— 各人完成第j项工作的代价

指派问题的数学模型

\[x_{ij} = \begin{cases} 1 \quad 第i个人做第j项工作 \\ 0 \quad 第i个人不做第j项工作 \end{cases} \\ (i, \quad j = 1, \cdots, n) \]

指派问题的解矩阵

\[X = (x_{ij})_{n \times n} = \begin{bmatrix} {c_{11}}&{c_{12}}&{\cdots}&{c_{1n}}\\ {c_{21}}&{c_{22}}&{\cdots}&{c_{2n}}\\ {\vdots}&{\vdots}&{\ddots}&{\vdots}\\ {c_{n1}}&{c_{n2}}&{\cdots}&{c_{nn}}\\ \end{bmatrix} \]

\[min z = \displaystyle\sum_{i=1}^n \displaystyle\sum_{j=1}^n c_{ij}x_{ij} \]

\[s.t. \begin{cases} \displaystyle\sum_{j=1}^n x_{ij} = 1 \quad (i = 1, \cdots, n) \\ \displaystyle\sum_{i=1}^n x_{ij} = 1 \quad (i = 1, \cdots, n) \\ x_{ij} = 0或1 \quad (i, j = 1, \cdots. n) \end{cases} \]

指派问题可行解中,每行每列有且仅有一个1

非标准形式的指派问题

  1. 最大化指派问题
    \(C = (c_{ij})_{n \times n}\)中最大元素为m,令\(B=(b_{ij})_n \times n = (m - c_{ij})_{n \times n}\)
  2. 人数和工作数不等
    人多工作少: 添加虚拟的'人',代价为0
    人少工作多: 添加虚拟的'工作',代价为0
  3. 一个人可以做多件工作
    该人可化为几个相同的'人'
  4. 某工作一定不能由某人做
    该人做该工作的相应代价取足够大M

指派问题的匈牙利算法的一般步骤

  1. 变换指派问题的系数(也称效率)矩阵(\(c_{ij}\))为(\(b_{ij}\)),使在(\(b_{ij}\))的各行各列中都出现0元素,即
    (1) 从(\(c_{ij}\))的每行元素都减去该行的最小元素;
    (2) 再从所得新系数矩阵的每列元素中减去该列的最小元素。
  2. 进行试指派,以寻求最优解。
    在(\(b_{ij}\))中找尽可能多的独立0元素,若能找出n个独立0元素,就以这n个独立0元素对应解矩阵(\(x_{ij}\))中的元素为1,其余为0,这就得到最优解。找独立0元素,常用的步骤为:
    (1) 从只有一个0元素的行(列)开始,给这个0元素加圈,记作◎。然后划去◎ 所在列(行)的其它0元素,记作Ø;这表示这列所代表的任务已指派完,不必再考虑别人了。
    (2) 给只有一个0元素的列(行)中的0元素加圈,记作◎;然后划去◎所在行的0元素,记作Ø;
    (3) 反复进行(1),(2)两步,直到尽可能多的0元素都被圈出和划掉为止。
    (4) 若仍有没有划圈的0元素,且同行(列)的0元素至少有两个,则从剩有0元素最少的行(列)开始,比较这行各0元素所在列中0元素的数目,选择0元素少的那列的这个0元素加圈(表示选择性多的要“礼让”选择性少的)。 然后划掉同行同列的其它0元素。可反复进行,直到所有0元素都已圈出和划掉为止。
    (5) 若◎元素的数目m 等于矩阵的阶数n,那么这指派问题的最优解已得到。若m < n,则转入下一步。
  3. 作最少的直线覆盖所有0元素。
    (1)对没有◎的行打√号;
    (2)对已打√号的行中所有含Ø元素的列打√号;
    (3)再对打有√号的列中含◎ 元素的行打√号;
    (4)重复(2),(3)直到得不出新的打√号的行、 列为止;
    (5)对没有打√号的行画横线,有打√号的列画纵线,这就得到覆盖所有0元素的最少直线数1。1应等于m,若不相等,说明试指派过程有误,回到第二步(4),另行试指派;若1 = m < n,须再变换当前的系数矩阵,以找到n个独立的0元素,为此转第四步。
  4. 变换矩阵(bij)以增加0元素。
    在没有被直线覆盖的所有元素中找出最小元素,然后打√各行都减去这最小元素;打√各列都加上这最小元素(以保证系数矩阵中不出现负元素)。新系数矩阵的最优解和原问题仍相同。转回第二步。

指派问题的计算机解法

c = [3 8 2 10 3; 8 7 2 9 7; 6 4 2 7 5; 8 4 2 3 5; 9 10 6 9 10];
c = c(:)   % 把矩阵c转化为向量
a = zeros(10, 25) % 10行25列
for i = 1:5
    a(i, (i-1)*5 + 1:5*1) = 1;
    a(5+i, i:5:25) = 1
end        % 此循环把指派问题转化为线性规划问题
b = ones(10, 1)
[x, y] = linprog(c, [], [], a, b, zeros(25, 1), ones(25, 1));
X = reshape(x, 5, 5)
opt = y

求得最优指派方案为\(x_{15} = x_{23} = x_{32} = x_{44} = x_{51} = 1\), 最优值为21

posted @ 2023-02-25 10:01  YHVH  阅读(1041)  评论(0)    收藏  举报