声明(求解方式):
-
python🍉
-
lingo
-
matlab
-
6.1 某公司有5个项目被列入投资计划,各项目的投资额和期望的投资收益如表6.6所示.
项目 投资额/百万元 投资收益/百万元 1 210 150 2 300 210 3 100 60 4 130 80 5 260 180 该公司只有600万资金可用于投资,由于技术上的原因投资收到下列约束:
- 在项目1,2和3中有且仅有一项被选中
- 项目3,4只能选中一项
- 项目5被选中的前提是项目1必须被选中
如何在上述条件下选择一个最好的投资方案,使投资收益最大?
分析:
-
每个项目的投资都有相应的门槛(投资额),且每个项目只能投资一次(假设),所以决策变量为:
x i = { 1 , 投资 i 项目 0 , 不投资 i 项目 i = 1 , 2 , 3 , 4 , 5 x_i= \left\{ \begin{aligned} & 1,投资i项目\\ &0 ,不投资i项目\\ \end{aligned} \right.~~~~~~i=1,2,3,4,5 xi={ 1,投资i项目0,不投资i项目 i=1,2,3,4,5 -
建立整数规划模型:
m a x z = [ 150 , 210 , 60 , 80 , 180 ] T [ x 1 , x 2 , x 3 , x 4 , x 5 ] { x 1 + x 2 + x 3 = 1 , x 3 + x 4 = 1 , x 5 ≤ M x 1 210 x 1 + 300 x 2 + 100 x 3 + 130 x 4 + 260 x 5 ≤ 600 x i = 0 或 1 , i = 1 , 2 , 3 , 4 , 5 max~~z=[150,210,60,80,180]^T[x_1,x_2,x_3,x_4,x_5]\\ \left\{ \begin{aligned} &x_1+x_2+x_3=1,\\ &x_3+x_4=1,\\ &x_5\le Mx_1\\ &210x_1+300x_2+100x_3+130x_4+260x_5\le600\\ &x_{i}=0或1,~i=1,2,3,4,5 \end{aligned} \right. max z=[150,210,60,80,180]T[x1,x2,x3,x4,x5]⎩ ⎨ ⎧x1+x2+x3=1,x3+x4=1,x5≤Mx1210x1+300x2+100x3+130x4+260x5≤600xi=0或1, i=1,2,3,4,5- 其中对于互斥条件,只需要使之和等于1,这样就只能选一个使得等式成立
- 对于条件3(必要条件),取M为一个极大的正数,若 x 5 = 1 , 而此时 x 1 ≠ 1 ,即 x 1 = 0 , 那么 0 ≤ x 5 ≤ 0 , x 5 = 0 x_5=1,而此时x_1\neq1,即x_1=0,那么0\le x_5\le0,x_5=0 x5=1,而此时x1=1,即x1=0,那么0≤x5≤0,x5=0 这样就会产生矛盾,所以条件3必须成立。(反之 x 1 = 1 , x 5 x_1=1,x_5 x1=1,x5 未必为1)
-
这里使用matlab 构造矩阵反而麻烦,不够直观
-
lingo
sets: fac/1..5/:x,c,b; endsets data: c=150,210,60,80,180; b=210,300,100,130,260; enddata max=@sum(fac(i):c(i)*x(i)); x(1)+x(2)+x(3)=1; x(3)+x(4)=1; x(5)<1000000*x(1); @sum(fac(i):x(i)*b(i))<600; @for(fac(i):@bin(x(i))); # X1=1,X2=0,X3=0,X4=1,X5=1; #最大值为410
- python
import cvxpy as cp import numpy as np M=1000000 c=np.array([150,210,60,80,180]) beq=np.array([210,300,100,130,260]) x=cp.Variable(5,integer=True) obj=cp.Maximize(cp.sum(cp.multiply(c,x))) con=[x[0]+x[1]+x[2]==1,x[2]+x[3]==1,x[4]<=M*x[0], cp.sum(cp.multiply(beq,x))<=600,x<=1