【数学建模笔记 02】数学建模的整数规划

02. 整数规划

定义

规划中的变量 (部分或全部) 限制为整数时,称为整数规划。

若在线性规划模型中变量限制为整数,则称为整数线性规划。

分类:

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

求解方法

分枝定界法

思路:将可行解空间分割为越来越小的子集,对每个子集内的解集计算目标下界,超出已知可行解集目标值的子集不再进一步分枝。

步骤
  1. **分枝:**在问题中任选一个不符合整数条件的变量 x j = b j x_j=b_j xj=bj,取小于 b j b_j bj 的最大整数和大于 b j b_j bj 的最小整数,构造新的约束条件
    x j ≤ [ b j ] , x j ≥ [ b j ] + 1 x_j\le[b_j],x_j\ge[b_j]+1 xj[bj],xj[bj]+1
    将约束条件加入原问题,构造两个新问题;

  2. **定界:**对于新问题的解,从符合整数条件的分枝中,找出目标函数值最大作为新的下界;

  3. **比较与剪枝:**若分枝的解小于下界,则去除该分枝;若分枝的解大于下界且不符合整数条件,重复步骤 1,直到解等于下界。

例子

max ⁡ z = 40 x 1 + 90 x 2 \max z=40x_1+90x_2 maxz=40x1+90x2

{ 9 x 1 + 7 x 2 ≤ 56 7 x 1 + 20 x 2 ≤ 70 x 1 , x 2 ≥ 0 x 1 , x 2 ∈ Z \left\{\begin{aligned} & 9x_1+7x_2\le56 \\ & 7x_1+20x_2\le70 \\ & x_1,x_2\ge0 \\ & x_1,x_2\in Z \end{aligned}\right. 9x1+7x2567x1+20x270x1,x20x1,x2Z

1. 求解与定界

记问题 B B B,首先不考虑整数限制,得
x 1 = 4.8092 , x 2 = 1.8168 , z = 355.8779 x_1=4.8092,x_2=1.8168,z=355.8779 x1=4.8092,x2=1.8168,z=355.8779

x 1 = 0 , x 2 = 0 x_1=0,x_2=0 x1=0,x2=0 z = 0 z=0 z=0,则为 z ∗ z^* z 的下界,记 z ‾ \underline{z} z


z ‾ = 0 \underline{z}=0 z=0

2. 分枝再求解

x 1 , x 2 x_1,x_2 x1,x2 任选一个进行分枝,设选 x 1 x_1 x1 分枝,有:
x 1 ≤ [ 4.8092 ] = 4 , x 1 ≥ [ 4.8092 ] + 1 = 5 x_1\le[4.8092]=4,x1\ge[4.8092]+1=5 x1[4.8092]=4,x1[4.8092]+1=5

对于 x 1 ≤ 4 x_1\le4 x14​,构成新的约束条件,记问题 B 1 B_1 B1
{ 9 x 1 + 7 x 2 ≤ 56 7 x 1 + 20 x 2 ≤ 70 0 ≤ x 1 ≤ 4 x 2 ≥ 0 \left\{\begin{aligned} & 9x_1+7x_2\le56 \\ & 7x_1+20x_2\le70 \\ & 0\le x_1\le4 \\ & x_2\ge0 \end{aligned}\right. 9x1+7x2567x1+20x2700x14x20
解得
x 1 = 4 , x 2 = 2.1 , z = 349 x_1=4,x_2=2.1,z=349 x1=4,x2=2.1,z=349
对于 x 1 ≥ 5 x_1\ge5 x15​,构成新的约束条件,记问题 B 2 B_2 B2​:
{ 9 x 1 + 7 x 2 ≤ 56 7 x 1 + 20 x 2 ≤ 70 x 1 ≥ 5 x 2 ≥ 0 \left\{\begin{aligned} & 9x_1+7x_2\le56 \\ & 7x_1+20x_2\le70 \\ & x_1\ge5 \\ & x_2\ge0 \end{aligned}\right. 9x1+7x2567x1+20x270x15x20
解得
x 1 = 5 , x 2 = 1.57 , z = 341.4 x_1=5,x_2=1.57,z=341.4 x1=5,x2=1.57,z=341.4

3. 再定界

B 1 , B 2 B_1,B_2 B1,B2 的解均不满足整数条件,下界不变,即
z ‾ = 0 \underline{z}=0 z=0

两个问题的解均不等于下界,继续分枝。

4. 再分枝再求解

对问题 B 1 B_1 B1 再分枝,由于 x 1 x_1 x1 满足整数条件,选 x 2 x_2 x2
x 2 ≤ [ 2.1 ] = 2 , x 2 ≥ [ 2.1 ] + 1 = 3 x_2\le[2.1]=2,x_2\ge[2.1]+1=3 x2[2.1]=2,x2[2.1]+1=3
分别构成问题 B 11 , B 12 B_{11},B_{12} B11,B12​。

最优解分别为:

  • B 11 : x 1 = 4 , x 2 = 2 , z = 340 B_{11}: x_1=4,x_2=2,z=340 B11:x1=4,x2=2,z=340
  • B 12 : x 1 = 1.43 , x 2 = 3 , z = 327.14 B_{12}: x_1=1.43,x_2=3,z=327.14 B12:x1=1.43,x2=3,z=327.14

同样对问题 B 2 B_2 B2​ 再分枝,有:

  • B 21 : x 1 = 5.44 , x 2 = 1 , z = 308 B_{21}: x_1=5.44,x_2=1,z=308 B21:x1=5.44,x2=1,z=308

  • B 22 B_{22} B22​ 无可行解

5. 再定界

B 11 , B 12 , B 21 , B 22 B_{11},B_{12},B_{21},B_{22} B11,B12,B21,B22 中, B 11 B_{11} B11 满足整数条件,作为下界,即
z ‾ = 340 \underline{z}=340 z=340
其余分枝解均小于下界,被剪枝,保留 B 11 B_{11} B11

B 11 B_{11} B11 满足整数条件,无需继续分枝,作为最终解,即
x 1 = 4 , x 2 = 2 , z = 340 x_1=4,x_2=2,z=340 x1=4,x2=2,z=340

过滤隐枚举法

思路:排除掉不可能的变量取值集合,只检查变量取值组合的一部分,就能求到问题的最优解。

过滤隐枚举法是解 0-1 型整数规划的一种解法。

步骤
  1. 试探求一个可行解 x = ( x 1 , x 2 , … , x n ) x=(x1,x2,\dots,x_n) x=(x1,x2,,xn),代入得 z = j 1 z=j_1 z=j1​;
  2. 增加约束条件 z ≥ j 1 z\ge j_1 zj1
  3. 继续试探求解并更新约束条件,从而抬高过滤门槛,减少计算量。

蒙特卡洛法

对可行解集进行随机取样,选取部分解集代入计算。

Python 代码

利用 cvxpy 包可以直接进行整数规划的求解。

对于问题:
min ⁡ x 1 , x 2 z = 40 x 1 + 90 x 2 \min_{x_1,x_2}z=40x_1+90x_2 x1,x2minz=40x1+90x2

s . t . { 9 x 1 + 7 x 2 ≤ 56 , 7 x 1 + 20 x 2 ≥ 70 , x 1 , x 2 ≥ 0 , x 1 , x 2 ∈ Z . s.t.\left\{\begin{aligned} & 9x_1+7x_2\le56,\\ & 7x_1+20x_2\ge70,\\ & x_1,x_2\ge0,\\ & x_1,x_2\in Z. \end{aligned}\right. s.t.9x1+7x256,7x1+20x270,x1,x20,x1,x2Z.

代码如下:

# %%

import numpy as np
import cvxpy as cp

# %%

# 目标函数形如 min c^T·x
c = np.array([40, 90])

# 约束形如 a·x <= b
a = np.array([[9, 7],
              [-7, -20]])
b = np.array([56, -70])

# 两个整数决策变量
x = cp.Variable(2, integer=True)

# 目标函数
z = cp.Minimize(c * x)

# 约束条件
cons = [a * x <= b,
        x >= 0]

# 问题模型
prob = cp.Problem(z, cons)
prob.solve(solver='GLPK_MI', verbose=True)

# %%

print('best z =', prob.value)
print('best x =', x.value)

输出:

best z = 350.0
best x = [2. 3.]

因此有最优解
x 1 = 2 , x 2 = 3 x_1=2,x_2=3 x1=2,x2=3
时, z z z 取得最小值 350.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值