试将下述非线性的0-1规划问题转换成线性的0-1规划问题
m a x z = x 1 + x 1 x 2 − x 3 s . t . = { − 2 x 1 + 3 x 2 + x 3 ≤ 3 x j = 0 或 1 , j = 1 , 2 , 3 max z = x_1+x_1x_2-x_3\\ s.t.= \begin{cases} -2x_1 + 3x_2+x_3 \leq 3\\ x_j = 0 \text{或}1,\ \ j = 1,2,3 \end{cases} maxz=x1+x1x2−x3s.t.={−2x1+3x2+x3≤3xj=0或1, j=1,2,3
做变量替换 y = x 1 x 2 y = x_1x_2 y=x1x2,则有如下关系:
x 1 + x 2 − 1 ≤ y ≤ x 1 x 1 + x 2 − 1 ≤ y ≤ x 2 x_1+x_2-1 \leq y \leq x_1 \\ x_1 + x_2 -1 \leq y \leq x_2 x1+x2−1≤y≤x1x1+x2−1≤y≤x2
从而得到如下的线性0-1规划
m a x z = x 1 + y − x 3 s . t . = { − 2 x 1 + 3 x 2 + x 3 ≤ 3 x 1 + x 2 − 1 ≤ y ≤ x 1 x 1 + x 2 − 1 ≤ y ≤ x 2 x j = 0 或 1 , j = 1 , 2 , 3 y = 0 或 1 max z = x_1 + y - x_3\\ s.t.= \begin{cases} -2x_1 + 3x_2 + x_3 \leq 3\\ x_1 + x_2 -1 \leq y \leq x_1\\ x_1 + x_2 -1 \leq y \leq x_2\\ x_j = 0 或 1, \ \ j = 1,2,3\\ y = 0或1 \end{cases} maxz=x1+y−x3s.t.=⎩⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎧−2x1+3x2+x3≤3x1+x2−1≤y≤x1x1+x2−1≤y≤x2xj=0或1, j=1,2,3y=0或1
某市为方便小学生上学,拟在新建的8个居民小区 A 1 , A 2 , . . . , A 8 A_1,A_2,...,A_8 A1,A2,...,A8增设若干所小学,经过论证知备选校址有 B 1 , B 2 , . . . , B 6 B_1,B_2,...,B_6 B1,B2,...,B6,它们能够覆盖的居民小区如下表所示。
B 1 B_1 B1 | B 2 B_2 B2 | B 3 B_3 B3 | B 4 B_4 B4 | B 5 B_5 B5 | B 6 B_6 B6 |
---|---|---|---|---|---|
A 1 , A 5 , A 7 A_1,A_5,A_7 A1,A5,A7 | A 1 , A 2 , A 5 , A 8 A_1,A_2,A_5,A_8 A1,A2,A5,A8 | A 1 , A 3 , A 5 A_1,A_3,A_5 A1,A3,A5 | A 2 , A 4 , A 8 A_2,A_4,A_8 A2,A4,A8 | A 3 , A 6 A_3,A_6 A3,A6 | A 4 , A 6 , A 8 A_4,A_6,A_8 A4,A6,A8 |
试建立一个数学模型,确定出最小个数的建校地址,使其能够覆盖所有的居民小区
令
x i = { 1 , 在 备 选 校 址 B i 建 学 校 0 , 在 备 选 校 址 B i 不 建 学 校 x_{i} = \begin{cases} 1,\ \ \ 在备选校址B_{i}建学校\\ 0,\ \ \ 在备选校址B_{i}不建学校\\ \end{cases} xi={1, 在备选校址Bi建学校0, 在备选校址Bi不建学校
小区 A 1 A_{1} A1可以被备选校址B_1、B_2、B_3处所建的学校覆盖,则有约束条件
x 1 + x 2 + x 3 ≥ 1 x_1 + x_2 + x_3 \geq 1 x1+x2+x3≥1
依次类推,建立如下0-1整数规划模型:
m i n ∑ i = 1 6 x i s . t . = { x 1 + x 2 + x 3 ≥ 1 x 2 + x 4 ≥ 1 x 3 + x 5 ≥ 1 x 4 + x 6 ≥ 1 x 5 + x 6 ≥ 1 x 1 ≥ 1 x 2 + x 4 + x 6 ≥ 1 x i = 0 或 1 , i = 1 , 2 , . . . , 8 min \sum^{6}_{i = 1}x_i\\ s.t. = \begin{cases} x_1 + x_2 + x_3 \geq 1 \\ x_2 + x_4 \geq 1 \\ x_3 + x_5 \geq 1 \\ x_4 + x_6 \geq 1 \\ x_5 + x_6 \geq 1 \\ x_1 \geq 1\\ x_2 + x_4 + x_6 \geq 1 \\ x_{i} = 0 或 1,\ \ \ i = 1,2,...,8 \end{cases} mini=1∑6xis.t.=⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧x1+x2+x3≥1x2+x4≥1x3+x5≥1x4+x6≥1x5+x6≥1x1≥1x2+x4+x6≥1xi=0或1, i=1,2,...,8
# 决策变量
n = 8
# nonneg参数,变量是否为非负
x = cp.Variable(n,nonneg = True)
# 约束1
A1 = np.array([[1,1,1,0,0,0,0,0],
[0,1,0,1,0,0,0,0],
[0,0,1,0,1,0,0,0],
[0,0,0,1,0,1,0,0],
[0,0,0,0,1,1,0,0],
[1,0,0,0,0,0,0,0],
[0,1,0,1,0,1,0,0]])
b1 = np.array([1,1,1,1,1,1,1])
# 约束2
A2 = np.ones((8, 8))
for i in range(A2.shape[0]):
for j in range(A2.shape[1]):
if i == j:
pass
else:
A2[i, j] = A2[i, j]*0
b2 = np.array([0,0,0,0,0,0,0,0])
# 约束3
A3 = np.ones((8, 8))
for i in range(A3.shape[0]):
for j in range(A3.shape[1]):
if i == j:
pass
else:
A3[i, j] = A3[i, j]*0
b3 = np.array([1,1,1,1,1,1,1,1])
# 目标函数
c = np.array([1,1,1,1,1,1,1,1])
# 定义问题,添加约束条件
prob = cp.Problem(cp.Minimize(c.T @ x),
[A1 @ x >= b1,
A2 @ x >= b2,
A3 @ x <= b3])
# 求解
ans = prob.solve(solver=cp.GLOP)
# 输出结果
print("目标函数最小值:", ans)
# 对x向量各元素取整数后再输出
print(x.value)
输出
目标函数最小值: 3.0
[ 1. -0. 0. 1. 1. -0. -0. -0.]
某公司新购置了某种设备6台,欲分配给下属的4个企业,每个企业至少获订一台设备,已知各企业获得这种设备后年创利润如下表所示,单位为千万元。问应如何分配这些设备能使年创利润最大,最大利润是多少?
设备 | 甲 | 乙 | 丙 | 丁 |
---|---|---|---|---|
1 | 4 | 2 | 3 | 4 |
2 | 6 | 4 | 5 | 5 |
3 | 7 | 6 | 7 | 6 |
4 | 7 | 8 | 8 | 6 |
5 | 7 | 9 | 8 | 6 |
6 | 7 | 10 | 8 | 6 |
用 j = 1 , 2 , 3 , 4 j = 1,2,3,4 j=1,2,3,4分别表示甲、乙、丙、丁4个企业, c i j c_{ij} cij表示第 i ( i = 1 , 2 , . . . , 6 ) i(i= 1,2,...,6) i(i=1,2,...,6)台设备分配给第j个企业创造的利润,引进0-1变量:
x i j = { 1 , 第 i 台 设 备 分 配 给 第 j 个 企 业 0 , 第 i 台 设 备 不 分 配 给 第 j 个 企 业 x_{ij} = \begin{cases} 1,\ \ \ 第i台设备分配给第j个企业 \\ 0,\ \ \ 第i台设备不分配给第j个企业\\ \end{cases} xij={1, 第i台设备分配给第j个企业0, 第i台设备不分配给第j个企业
数学模型为:
m a x ∑ i = 1 6 ∑ j = 1 4 c i j x i j s . t . = { ∑ i = 1 6 ≥ 1 , j = 1 , 2 , 3 , 4 ∑ j = 1 4 ≥ 1 , i = 1 , 2 , . . . , 6 x i j = 0 或 1 , i = 1 , 2 , . . . 6 ; j = 1 , 2 , 3 , 4 max \sum_{i = 1}^{6} \sum_{j = 1}^{4}c_{ij}x_{ij}\\ s.t. = \begin{cases} \sum\limits^{6}_{i = 1} \geq 1,\ \ j = 1,2,3,4\\ \sum\limits^{4}_{j = 1}\geq1,\ \ i = 1,2,...,6\\ x_{ij} = 0 或 1,\ \ i = 1,2,...6;j = 1,2,3,4 \end{cases} maxi=1∑6j=1∑4cijxijs.t.=⎩⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎧i=1∑6≥1, j=1,2,3,4j=1∑4≥1, i=1,2,...,6xij=0或1, i=1,2,...6;j=1,2,3,4
multiply
,不能直接用python内置的矩阵乘法c * x
会报维度错误。函数说明参考# 决策变量
n = (6,4)
# nonneg参数,变量是否为非负
x = cp.Variable(n,nonneg = True)
# 约束1
b1 = np.ones((6,4))
c = np.array([[4,2,3,4],
[6,4,5,5],
[7,6,7,6],
[7,8,8,6],
[7,9,8,6],
[7,10,8,6]])
# 定义问题,添加约束条件
prob = cp.Problem(cp.Maximize(cp.sum(cp.sum(cp.multiply(c,x),axis = 1),axis = 0)),
[cp.sum(x,axis = 0) >= 1,
cp.sum(x,axis = 1) == 1,
x <= b1])
# 求解
ans = prob.solve(solver=cp.GLOP)
# 输出结果
print("目标函数最大值:", ans)
# 对x向量各元素取整数后再输出
print(x.value)
输出:
目标函数最大值: 44.0
[[ 0. -0. -0. 1.]
[ 1. -0. -0. -0.]
[ 0. -0. 1. -0.]
[-0. -0. 1. -0.]
[-0. 1. -0. -0.]
[-0. 1. -0. -0.]]
有一场由4个项目(高低杠、平衡木、跳马、自由体操)组成的女子体操团体赛,赛程规定:每个队最多允许10名运动员参赛,每一个项目可以有6名选手参加。每个选手参赛的成绩评分从高到低依次为10、9.9、9.8、…、0.1、0。每个代表队的总分是参赛选手所得总分之和,总分最多的代表队为优胜者。此外,还规定每个运动员只能参加全能比赛(4项全参加)与单项比赛这两类中的一类,参加单项比赛的每个运动员至多只能参加3个单项。每个队应有4人参加全能比赛,其余运动员参加单项比赛。
现某代表队的教练已经对其所带领的10名运动员参加各个项目的成绩进行了大量测试,教练发现每个运动员在每个单项上的成绩稳定在4个得分上,她们得到这些成绩的相应概率也由统计得出,试解答以下问题:
(1)每个选手的各单项得分按最悲观估算,在此前提下,请为该队排出一个出场阵容,使该队团体总分尽可能高;每个选手的各单项得分按均值估算,在此前提下,请为该队排出一个出场阵容,使该队团队总分尽可能高。
(2)若对以往的资料及近期各种信息进行分析得到:本次夺冠的团体总分估计不少于236.2分,该队为了夺冠应排出怎样的阵容?以该阵容出战,其夺冠的前景如何?得分前景又如何?它有90%的把握战胜怎样水平的对手?
boolean = True
,或整数变量integer = True
,但是需要注意的是如果使用整数变量,最后需要添加条件x >= 0,x <= 1
GLOP
求解器无法解决有布尔变量的线性规划,所以将求解器换成GLPK_MI
pip install cvxopt
,然后再使用cp.installed_solvers()
,查看已安装的求解器GLOP
时语法是prob.solve(solver=cp.GLOP)
,现在使用GLPK_MI
,语法变为prob.solve(solver='GLPK_MI')
data = np.loadtxt("../input/math-modeling/data2_4.txt")
fen = data[:,0:20:2]
gai = data[:,1:20:2]
low = np.zeros([4,10])
zhun = np.zeros([4,10])
for i in range(0,4):
for j in range(0,10):
low[i,j] = fen[4*i,j]
zhun[i,j] = fen[4*i:4*(i+1),j] @ gai[4*i:4*(i+1),j]
# 决策变量
n = (4,10)
z = 10
# nonneg参数,变量是否为非负
x = cp.Variable(n,boolean = True)
y = cp.Variable(z,boolean = True)
# 定义问题,添加约束条件
prob = cp.Problem(cp.Maximize(cp.sum(cp.sum(cp.multiply(low,x)))),
[cp.sum(x,axis = 1) == 6,
cp.sum(y,axis = 0) == 4,
4 * y <= cp.sum(x,axis = 0),
cp.sum(x,axis = 0) <= 3+y])
# 求解
ans = prob.solve(solver='GLPK_MI')
# 输出结果
print("目标函数最大值:", ans)
# 对x向量各元素取整数后再输出
print(x.value)
输出:
目标函数最大值: 212.3
[[0. 1. 0. 0. 1. 1. 1. 0. 1. 1.]
[0. 1. 0. 1. 1. 1. 0. 1. 1. 0.]
[1. 1. 0. 1. 1. 1. 0. 0. 1. 0.]
[0. 1. 1. 0. 1. 1. 0. 0. 1. 1.]]
# 定义问题,添加约束条件
prob = cp.Problem(cp.Maximize(cp.sum(cp.sum(cp.multiply(zhun,x)))),
[cp.sum(x,axis = 1) == 6,
cp.sum(y,axis = 0) == 4,
4 * y <= cp.sum(x,axis = 0),
cp.sum(x,axis = 0) <= 3+y,
x>=0,x<=1,y>=0,y<=1])
# 求解
ans = prob.solve(solver='GLPK_MI')
# 输出结果
print("目标函数最大值:", ans)
# 对x向量各元素取整数后再输出
print(x.value)
输出:
目标函数最大值: 225.1
[[0. 1. 1. 0. 0. 1. 1. 0. 1. 1.]
[0. 1. 1. 0. 1. 0. 0. 1. 1. 1.]
[1. 1. 1. 1. 0. 0. 0. 0. 1. 1.]
[0. 1. 1. 0. 1. 0. 0. 1. 1. 1.]]
将团体总分236.2作为一个约束条件,得分的概率作为目标函数,建立0-1整数规划模型。用 k = 1 , 2 , 3 , 4 k = 1,2,3,4 k=1,2,3,4记运动员参加项目得到了第 K K K种得分, a i j k a_{ijk} aijk和 b i j k b_{ijk} bijk分别表示第 j j j个运动员参加第 i i i个项目得到的第 k k k种得分值及概率。记 p i j p_{ij} pij为运动员 j j j参加第 i i i个项目的某种得分的概率。
引入0-1变量:
z i j k = { 1 , 运 动 员 j 参 加 项 目 i 得 到 a i j k 分 0 , 运 动 员 j 参 加 i 项 目 没 得 到 a i j k 分 z_{ijk} = \begin{cases} 1,\ \ \ 运动员j参加项目i得到a_{ijk}分 \\ 0,\ \ \ 运动员j参加i项目没得到a_{ijk}分\\ \end{cases} zijk={1, 运动员j参加项目i得到aijk分0, 运动员j参加i项目没得到aijk分
建立如下的整数规划模型:
m a x ∏ i = 1 4 ∏ j = 1 10 p i j x i j s . t . = { ∑ j = 1 10 x i j = 6 , i = 1 , 2 , 3 , 4 4 y j ≤ ∑ i = 1 4 x i j ≤ 3 + y j ∑ j = 1 10 y j = 4 p i j = ∑ k = 1 4 b i j k z i j k , i = 1 , 2 , 3 , 4 ; j = 1 , 2 , ⋯ , 10 c i j = ∑ k = 1 4 a i j k z i j k , i = 1 , 2 , 3 , 4 ; j = 1 , 2 , ⋯ , 10 ∑ i = 1 4 ∑ j = 1 10 c i j x i j ≥ 236.2 ∑ j = 1 4 z i j k ≤ 1 , i = 1 , 2 , 3 , 4 ; j = 1 , 2 , ⋯ , 10 x i j = ∑ k = 1 4 z i j k , i = 1 , 2 , 3 , 4 ; j = 1 , 2 , ⋯ , 10 max\ \ \prod^{4}_{i = 1}\prod^{10}_{j = 1}p_{ij}^{x_{ij}}\\ s.t. = \begin{cases} \sum\limits^{10}_{j = 1}x_{ij} = 6,\ \ i = 1,2,3,4\\ 4y_{j} \leq \sum\limits^{4}_{i = 1}x_{ij}\leq 3+y_{j}\\ \sum\limits^{10}_{j = 1}y_j = 4\\ p_{ij} = \sum\limits^{4}_{k = 1}b_{ijk}z_{ijk},\ i = 1,2,3,4;\ j = 1,2,\cdots,10\\ c_{ij} = \sum\limits^{4}_{k = 1}a_{ijk}z_{ijk},\ i = 1,2,3,4;\ j = 1,2,\cdots,10\\ \sum\limits_{i = 1}^{4}\sum\limits_{j = 1}^{10}c_{ij}x_{ij} \geq 236.2\\ \sum\limits_{j = 1}^{4}z_{ijk} \leq 1,\ i = 1,2,3,4;\ j = 1,2,\cdots,10\\ x_{ij} = \sum\limits^{4}_{k = 1}z_{ijk},\ \ i = 1,2,3,4;j = 1,2,\cdots,10 \end{cases} max i=1∏4j=1∏10pijxijs.t.=⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧j=1∑10xij=6, i=1,2,3,44yj≤i=1∑4xij≤3+yjj=1∑10yj=4pij=k=1∑4bijkzijk, i=1,2,3,4; j=1,2,⋯,10cij=k=1∑4aijkzijk, i=1,2,3,4; j=1,2,⋯,10i=1∑4j=1∑10cijxij≥236.2j=1∑4zijk≤1, i=1,2,3,4; j=1,2,⋯,10xij=k=1∑4zijk, i=1,2,3,4;j=1,2,⋯,10
某单位需要加工制作 100 100 100套钢架,每套用长为 2.9 m 2.9m 2.9m、 2.1 m 2.1m 2.1m和 1 m 1m 1m的圆钢各一根。已知原料长 6.9 m 6.9m 6.9m。(1)如何下料,使用原材料最省?(2)若下料方式不超过三种,则应如何下料,使用的原材料最省?
目标 | A | B | C | D | E | F | G |
---|---|---|---|---|---|---|---|
2.9 | 1 | 2 | 0 | 0 | 0 | 0 | 1 |
2.1 | 0 | 0 | 3 | 2 | 1 | 0 | 1 |
1 | 4 | 1 | 0 | 2 | 4 | 6 | 1 |
合计 | 6.9 | 6.8 | 6.3 | 6.2 | 6.1 | 6 | 6 |
料头 | 0 | 0.1 | 0.6 | 0.7 | 0.8 | 0.9 | 0.9 |
s = np.zeros((4,7))
temp = 0
for i in range(3):
for j in range(4):
for k in range(7):
if (2.9 * i + 2.1 * j + k > 5.9) and (2.9 * i + 2.1 * j + k <= 6.9):
s[:,temp] = np.array([i,j,k,6.9-(2.9 * i + 2.1 * j +k)]).T
temp = temp + 1
ss = s[3,:][np.argsort(s[3,:])]
idx = np.argsort(s[3,:])
s = s[:,idx]
a = s[0:3,:]
# 决策变量
n = 7
# integer,变量为整型
x = cp.Variable(n,integer = True)
# 定义问题,添加约束条件
prob = cp.Problem(cp.Minimize(cp.sum(x)),
[a @ x >= 100,x >= 0])
# 求解
ans = prob.solve(solver='GLPK_MI')
# 输出结果
print("目标函数最小值:", ans)
print(x.value)
输出:
目标函数最小值: 91.0
[14. 43. 33. 1. 0. 0. 0.]
# 决策变量
n = 7
k = 7
# integer,变量为整型
x = cp.Variable(n,integer = True)
# boolean,变量为布尔类型
y = cp.Variable(n,boolean = True)
# 定义问题,添加约束条件
prob = cp.Problem(cp.Minimize(cp.sum(x)),
[a @ x >= 100,
x >= 0,
x <= 10000 * y,
cp.sum(y) == 3])
# 求解
ans = prob.solve(solver='GLPK_MI')
# 输出结果
print("目标函数最小值:", ans)
print(x.value)
输出:
目标函数最小值: 92.0
[15. 43. 34. 0. 0. 0. 0.]
求解整数线性规划问题
m i n z = 20 x 1 + 90 x 2 + 80 x 3 + 70 x 4 + 30 x 5 s . t . = { x 1 + x 2 + x 5 ≥ 30 x 3 + x 4 ≥ 30 3 x 1 + 2 x 3 ≤ 120 3 x 2 + 2 x 4 + x 5 ≤ 48 x j ≥ 0 且 为 整 数 , j = 1 , 2 , . . . . , 5 min\ \ z = 20x_1 + 90x_2 + 80x_3+70x_4+30x_5\\ s.t. = \begin{cases} x_1 + x_2 + x_5 \geq 30\\ x_3 + x_4 \geq 30\\ 3x_1 + 2x_3 \leq 120\\ 3x_2 + 2x_4+ x_5 \leq 48\\ x_j \geq 0 且为整数,\ \ \ j = 1,2,....,5 \end{cases} min z=20x1+90x2+80x3+70x4+30x5s.t.=⎩⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎧x1+x2+x5≥30x3+x4≥303x1+2x3≤1203x2+2x4+x5≤48xj≥0且为整数, j=1,2,....,5
# 决策变量
n = 5
# integer,变量为整型
x = cp.Variable(n,integer = True)
# 约束1
A1 = np.array([[1,1,0,0,1],
[0,0,1,1,0]])
b1 = np.array([30,30])
# 约束2
A2 = np.array([[3,0,2,0,0],
[0,3,0,2,1]])
b2 = np.array([120,48])
# 定义问题,添加约束条件
c = np.array([20,90,80,70,30])
prob = cp.Problem(cp.Minimize(c.T @ x),
[A1 @ x >= b1,
A2 @ x <= b2,
x >= 0])
# 求解
ans = prob.solve(solver='GLPK_MI')
# 输出结果
print("目标函数最小值:", ans)
print(x.value)
输出:
目标函数最小值: 2760.0
[30. 0. 6. 24. 0.]
美佳公司计划制造Ⅰ、Ⅱ两种家电产品。已知各制造一件家电时分别占用的设备A和设备B的台时,调试工序时间,每天可用于这两种家电的能力,各销售一件家电的获利情况,如表所示。问该公司应制造两种家电各多少件,使获取的利润为最大。
项目 | Ⅰ | Ⅱ | 每天可用能力 |
---|---|---|---|
设备A/h | 0 | 5 | 15 |
设备B/h | 6 | 2 | 24 |
调试工序/h | 1 | 1 | 5 |
利润/元 | 2 | 1 |
# 决策变量
n = 2
# integer,变量为整型
x = cp.Variable(n,integer = True)
# 约束1
A1 = np.array([[0,5],
[6,2],
[1,1]])
b1 = np.array([15,24,5])
# 约束2
A2 = np.array([[1,0],
[0,1]])
b2 = np.array([0,0])
# 定义问题,添加约束条件
c = np.array([2,1])
prob = cp.Problem(cp.Maximize(c.T @ x),
[A1 @ x <= b1,
A2 @ x >= b2])
# 求解
ans = prob.solve(solver='GLPK_MI')
# 输出结果
print("目标函数最大值:", ans)
print(x.value)
输出:
目标函数最大值: 8.0
[4. 0.]
求解标准的指派问题,其中指派矩阵
C = [ 6 7 5 8 9 10 6 3 7 9 3 8 8 11 12 6 7 9 9 7 5 4 7 6 5 8 9 6 10 7 9 8 7 6 5 9 ] C = \begin{bmatrix} 6 & 7 & 5 & 8 & 9 & 10\\ 6 & 3 & 7 & 9 & 3 & 8\\ 8 & 11 & 12 & 6 & 7 & 9\\ 9 & 7 & 5 & 4 & 7 & 6\\ 5 & 8 & 9 & 6 & 10 & 7\\ 9 & 8 & 7 & 6 & 5 & 9\\ \end{bmatrix} C=⎣⎢⎢⎢⎢⎢⎢⎡6689597311788571259789646693771051089679⎦⎥⎥⎥⎥⎥⎥⎤
# 决策变量
n = (6,6)
# integer,变量为整型
x = cp.Variable(n,boolean = True)
c = np.array([[6,7,5,8,9,10],
[6,3,7,9,3,8],
[8,11,12,6,7,9],
[9,7,5,4,7,6],
[5,8,9,6,10,7],
[9,8,7,6,5,9]])
prob = cp.Problem(cp.Minimize(cp.sum(cp.sum(cp.multiply(c,x)))),
[cp.sum(x,axis = 0) == 1,
cp.sum(x,axis = 1) == 1])
# 求解
ans = prob.solve(solver='GLPK_MI')
# 输出结果
print("目标函数最大值:", ans)
print(x.value)
输出:
目标函数最大值: 30.0
[[0. 0. 1. 0. 0. 0.]
[0. 1. 0. 0. 0. 0.]
[0. 0. 0. 1. 0. 0.]
[0. 0. 0. 0. 0. 1.]
[1. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 1. 0.]]
已知某物质有8个配送中心可以供货,有15个部队用户需要该物资,配送中心和部队用户之间单位物质的运费、15个部队用户的物质需求量和8个配送中心的物质储备量数据。
(1)根据题目给定的数据,求最小运费调用计划。
(2)若每个配送中心,可以对某个用户配送物资,也可以不对某个用户配送物资;若配送物资,配送量要大于等于1000且小于等于2000,求此时的费用最小调用计划。
d = np.loadtxt("../input/math-modeling/data2_9_1.txt")
a = d[0:-1,-1]
b = d[-1,0:-1]
c = d[0:-1,0:-1]
# 决策变量
n = (15,8)
# integer,变量为整型
x = cp.Variable(n,integer = True)
prob = cp.Problem(cp.Minimize(cp.sum(cp.sum(cp.multiply(c,x)))),
[cp.sum(x,axis = 0) <= b,
cp.sum(x,axis = 1) == a,
x >= 0])
# 求解
ans = prob.solve(solver='GLPK_MI')
# 输出结果
print("目标函数最小值:", ans)
print(x.value)
输出:
目标函数最小值: 9244730.0
[[ 0. 0. 0. 0. 0. 3000. 0. 0.]
[ 0. 0. 0. 0. 3100. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0. 0. 2900.]
[ 0. 0. 3100. 0. 0. 0. 0. 0.]
[3100. 0. 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 3400. 0. 0. 0. 0.]
[ 0. 3500. 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 3200. 0. 0. 0. 0.]
[ 0. 3000. 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0. 0. 3100.]
[ 0. 0. 0. 0. 0. 0. 3300. 0.]
[ 0. 0. 0. 0. 0. 0. 3200. 0.]
[ 0. 0. 0. 0. 0. 0. 3300. 0.]
[ 0. 0. 0. 0. 0. 0. 0. 2900.]
[ 0. 0. 0. 0. 0. 0. 0. 3100.]]
目标函数最小值: 12682750.0
[[ 0. 0. 0. 0. 1000. 2000. 0. 0.]
[ 0. 0. 0. 0. 2000. 1100. 0. 0.]
[ 0. 0. 1000. 0. 0. 0. 0. 1900.]
[ 0. 0. 2000. 0. 1100. 0. 0. 0.]
[2000. 0. 0. 1100. 0. 0. 0. 0.]
[1400. 0. 0. 2000. 0. 0. 0. 0.]
[1500. 2000. 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 2000. 1200. 0. 0. 0.]
[1000. 2000. 0. 0. 0. 0. 0. 0.]
[ 0. 0. 1100. 0. 0. 0. 0. 2000.]
[ 0. 0. 0. 0. 0. 0. 2000. 1300.]
[ 0. 0. 0. 1200. 0. 0. 2000. 0.]
[ 0. 0. 0. 1300. 0. 0. 2000. 0.]
[ 0. 0. 1000. 0. 0. 0. 0. 1900.]
[ 0. 0. 0. 1100. 0. 0. 0. 2000.]]
有4名同学到一家公司参加3个阶段的面试:公司要求每个同学都必须首先找公司秘书初试,然后到部门主管处复试,最后到经理处参加面试,并且不允许插队(即任何一个阶段4名同学的顺序是一样的)。由于4名同学的专业背景不同,所以每人在3个阶段的面试时间也不同,如下表所示。这4名同学约定他们全部面试完以后一起离开公司。假定现在时间是早餐8:00,请问他们最早何时能离开公司?
同学 | 秘书初试 | 主管复试 | 经理面试 |
---|---|---|---|
同学甲 | 14 | 16 | 21 |
同学乙 | 19 | 17 | 10 |
同学丙 | 10 | 15 | 12 |
同学丁 | 9 | 12 | 13 |
t = np.array([[14,16,21],
[19,17,10],
[10,15,12],
[9,12,13]])
x = cp.Variable((4,3),nonneg = True)
y = cp.Variable((4,4),boolean = True)
T = cp.Variable(1)
constraints = [x[:,2] + t[:,2] <= T]
for i in range(4):
for j in range(2):
constraints += [x[i,j] + t[i,j] <= x[i,j+1]]
for i in range(3):
for j in range(3):
for k in range(i+1,4):
constraints += [x[i,j] + t[i,j] <= x[k,j] + 10000 * (1-y[i,k]),
x[k,j] + t[k,j] <= x[i,j] + 10000 * y[i,k]]
prob = cp.Problem(cp.Minimize(T),constraints)
# 求解
ans = prob.solve(solver='GLPK_MI')
# 输出结果
print("目标函数最小值:", ans)
print(x.value)
输出:
目标函数最小值: 82.0
[[ 9. 23. 39.]
[33. 54. 72.]
[23. 39. 60.]
[-0. 9. 21.]]