某公司3个工厂生产的产品供应给4个客户,各工厂生产量、各用户需求量
及从各工厂到各用户的单位产品的运输费用由下表给出.
用户 | 1 | 2 | 3 | 4 | 生产量 |
---|---|---|---|---|---|
工厂 1 | 5 | 2 | 6 | 7 | 300 |
工厂 2 | 3 | 5 | 4 | 6 | 200 |
工厂 3 | 4 | 5 | 2 | 3 | 400 |
需求量 | 200 | 100 | 450 | 250 |
(1)如果只考虑总运费最小,制定所有产品的最优运输方案.
(2)由于总生产量小于总需求量,公司经研究确定了调配方案的8项目标并规定了重要性的次序:
第一目标:用户4为重要客户,需求量必须全部满足;
第二目标:供应用户1的产品中,工厂3的产品不少于100个单位;
第三目标:每个用户的满足率不低于80% ;
第四目标:应尽量满足各用户的需求;
第五目标:总运费不超过(1)中运输方案的10% ;
第六目标:工厂2到用户4的路线应尽量避免运输任务;
第七目标:用户1和用户3的需求满足率应尽量保持平衡;
第八目标:力求减少总运费.
请列出相应的目标规划模型并进行求解.
第一问:
由于总生产量小于总需求量(相差100)个单位,因此虚设工厂4,具有100的生产力,到各用户之间的价格为0
设变量 X = [ x i j ] 3 ∗ 4 X = [x_{ij}]_{3*4} X=[xij]3∗4表示工厂 i i i向用户 j j j运送货物的量,那么针对第一问可建立模型如下
M i n z = ∑ i = 1 , j = 1 i = 3 , j = 4 x i j ∗ p r i c e i j S . T . { ∑ j = 1 j = 4 x i j < = m a k e [ i ] , i = 1 , 2 , 3 , 4 ∑ j = 1 j = 4 x i j > = n e e d [ j ] , i = 1 , 2 , 3 , 4 x i j > = 0 Min \quad z = \sum_{i=1,j=1}^{i=3,j=4}x_{ij}*price_{ij}\\ S.T.\left\{ \begin{aligned} \sum_{j=1}^{j=4}x_{ij}<=make[i],i=1,2,3,4\\ \sum_{j=1}^{j=4}x_{ij}>=need[j],i = 1,2,3,4\\ x_{ij}>=0\\ \end{aligned} \right. Minz=i=1,j=1∑i=3,j=4xij∗priceijS.T.⎩⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎧j=1∑j=4xij<=make[i],i=1,2,3,4j=1∑j=4xij>=need[j],i=1,2,3,4xij>=0
第二问:
由于总生产量小于总需求量(相差100)个单位,需求不可全部满足,因此新设置变量 b i − > = 0 b_{i}^{^-}>=0 bi−>=0与 b i + > = 0 b_{i}^{^+}>=0 bi+>=0满足 ∑ i = 1 i = 3 x i j + b j − − b j + > = n e e d [ j ] , j = 1 , 2 , 3 , 4 \sum_{i=1}^{i=3}x_{ij}+b_{j}^{^-}-b_{j}^{^+}>=need[j],\quad j=1,2,3,4 i=1∑i=3xij+bj−−bj+>=need[j],j=1,2,3,4
针对第四目标 b i − > = 0 b_{i}^{^-}>=0 bi−>=0与 b i + > = 0 b_{i}^{^+}>=0 bi+>=0分别表示不够的和超出的
针对第二目标设立松弛因子 s l a c k 2 − > = 0 , s l a c k 2 + > = 0 slack_2^{^-}>=0,slack_2^{^+}>=0 slack2−>=0,slack2+>=0
针对第三目标设立 c i − > = 0 c_{i}^{^-}>=0 ci−>=0与 c i + > = 0 c_{i}^{^+}>=0 ci+>=0
针对第五目标设立松弛因子 s l a c k 5 − > = 0 , s l a c k 5 + > = 0 slack_5^{^-}>=0,slack_5^{^+}>=0 slack5−>=0,slack5+>=0
针对第七目标设立松弛因子 s l a c k 7 − > = 0 , s l a c k 7 + > = 0 slack_7^{^-}>=0,slack_7^{^+}>=0 slack7−>=0,slack7+>=0
第一问求得总运费为 2950.0 2950.0 2950.0
那么可以构建约束条件如下
S . T . { ∑ j = 1 j = 4 x i j < = m a k e [ i ] , i = 1 , 2 , 3 ∑ i = 1 i = 3 x i j + b j − − b j + > = n e e d [ j ] , j = 1 , 2 , 3 , 4 ∑ i = 1 i = 3 x i j + c j − − c j + > = n e e d [ j ] ∗ 0.8 , j = 1 , 2 , 3 , 4 x 31 + s l a c k 2 − − s l a c k 2 + > = 100 p r i c e a l l = ∑ i = 1 , j = 1 i = 3 , j = 4 x i j ∗ p r i c e i j p r i c e a l l + s l a c k 5 − − s l a c k 5 + = 2950 ∗ 1.1 b 1 − n e e d [ 1 ] + s l a c k 7 − − s l a c k 7 + = b 3 − n e e d [ 3 ] x i j > = 0 , b j − > = 0 , b j + > = 0 S.T.\left\{ \begin{aligned} \sum_{j=1}^{j=4}x_{ij}<=make[i],i=1,2,3\\ \sum_{i=1}^{i=3}x_{ij}+b_{j}^{^-}-b_{j}^{^+}>=need[j],j = 1,2,3,4\\ \sum_{i=1}^{i=3}x_{ij}+c_{j}^{^-}-c_{j}^{^+}>=need[j]*0.8,j = 1,2,3,4\\ x_{31}+slack_2^{^-}-slack_2^{^+}>=100\\ price_{all} = \sum_{i=1,j=1}^{i=3,j=4}x_{ij}*price_{ij}\\ price_{all}+slack_5^{^-}-slack_5^{^+} =2950*1.1\\ \frac{b_{1}^{^-}}{need[1]}+slack_7^{^-}-slack_7^{^+}=\frac{b_{3}^{^-}}{need[3]}\\ x_{ij}>=0,b_{j}^{^-}>=0,b_{j}^{^+}>=0\\ \end{aligned} \right. S.T.⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧j=1∑j=4xij<=make[i],i=1,2,3i=1∑i=3xij+bj−−bj+>=need[j],j=1,2,3,4i=1∑i=3xij+cj−−cj+>=need[j]∗0.8,j=1,2,3,4x31+slack2−−slack2+>=100priceall=i=1,j=1∑i=3,j=4xij∗priceijpriceall+slack5−−slack5+=2950∗1.1need[1]b1−+slack7−−slack7+=need[3]b3−xij>=0,bj−>=0,bj+>=0
那么这几个目标可以依次表达为
( 1 ) M i n b 4 − ( 2 ) M i n s l a c k 2 − ( 3 ) M i n ∑ j = 1 j = 4 c j − ( 4 ) M i n ∑ j = 1 j = 4 b j − ( 5 ) M i n s l a c k 5 − ( 6 ) M i n x 24 ( 7 ) M i n s l a c k 7 − + s l a c k 7 + ( 8 ) M i n p r i c e a l l (1)Min\quad b_{4}^{^-}\\ (2)Min\quad slack_2^{^-}\\ (3)Min\quad \sum_{j=1}^{j=4}c_{j}^{^-}\\ (4)Min\quad \sum_{j=1}^{j=4}b_{j}^{^-}\\ (5)Min\quad slack_5^{^-}\\ (6)Min\quad x_{24}\\ (7)Min\quad slack_7^{^-}+slack_7^{^+}\\ (8)Min\quad price_{all}\\ (1)Minb4−(2)Minslack2−(3)Minj=1∑j=4cj−(4)Minj=1∑j=4bj−(5)Minslack5−(6)Minx24(7)Minslack7−+slack7+(8)Minpriceall
import gurobipy as grb
import numpy as np
from gurobipy import *
model = grb.Model()
X = model.addVars(4,4,name = 'X')
price = np.array([[5,2,6,7],
[3,5,4,6],
[4,5,2,3],
[0,0,0,0]])
make = [300,200,400,100]
need = [200,100,450,250]
model.addConstrs((X.sum(i,'*')<=make[i] for i in range(4)),name = "make")
model.addConstrs((X.sum('*',j)>=need[j] for j in range(4)),name = 'need')
# 目标函数
model.setObjective(grb.quicksum(X[i,j]*price[i,j] for i in range(4) for j in range(4)), grb.GRB.MINIMIZE)
#grb.quicksum(X[i,j]*price[i,j] for i in range(3) for j in range(4))
model.write("test.lp")
# 求解
model.optimize()
for v in model.getVars():
print(v.varName, '=', v.x)
print('目标函数值是:', model.objVal)
print("变量矩阵:\n",np.array(model.X).reshape(4,4))
Gurobi Optimizer version 9.1.2 build v9.1.2rc0 (win64)
Thread count: 4 physical cores, 8 logical processors, using up to 8 threads
Optimize a model with 8 rows, 16 columns and 32 nonzeros
Model fingerprint: 0x711bf819
Coefficient statistics:
Matrix range [1e+00, 1e+00]
Objective range [2e+00, 7e+00]
Bounds range [0e+00, 0e+00]
RHS range [1e+02, 5e+02]
Presolve time: 0.01s
Presolved: 8 rows, 16 columns, 32 nonzeros
Iteration Objective Primal Inf. Dual Inf. Time
0 0.0000000e+00 1.000000e+03 0.000000e+00 0s
9 2.9500000e+03 0.000000e+00 0.000000e+00 0s
Solved in 9 iterations and 0.02 seconds
Optimal objective 2.950000000e+03
X[0,0] = 200.0
X[0,1] = 100.0
X[0,2] = 0.0
X[0,3] = 0.0
X[1,0] = 0.0
X[1,1] = 0.0
X[1,2] = 200.0
X[1,3] = 0.0
X[2,0] = 0.0
X[2,1] = 0.0
X[2,2] = 250.0
X[2,3] = 150.0
X[3,0] = 0.0
X[3,1] = 0.0
X[3,2] = 0.0
X[3,3] = 100.0
目标函数值是: 2950.0
变量矩阵:
[[200. 100. 0. 0.]
[ 0. 0. 200. 0.]
[ 0. 0. 250. 150.]
[ 0. 0. 0. 100.]]
import gurobipy as grb
import numpy as np
from gurobipy import *
model = grb.Model()
#添加变量
X = model.addVars(3,4,vtype=grb.GRB.INTEGER,name = 'X')
b1 = model.addVars(4,lb = 0,vtype=grb.GRB.INTEGER,name = 'b+')
b2 = model.addVars(4,lb = 0,vtype=grb.GRB.INTEGER,name = 'b-')
c1 = model.addVars(4,lb = 0,vtype=grb.GRB.INTEGER,name = 'c+')
c2 = model.addVars(4,lb = 0,vtype=grb.GRB.INTEGER,name = 'c-')
slack = model.addVars(3,2,lb=0,vtype=grb.GRB.INTEGER,name = 'slack')
price_all = model.addVar(lb=0,vtype=grb.GRB.INTEGER,name='Price_all')
#3行2列变量,第一列代表slack-,第二列代表slack+。第123行分别表示模型中的slack_2,slack_5,slack_7
price = np.array([[5,2,6,7],
[3,5,4,6],
[4,5,2,3]])
make = [300,200,400]
need = [200,100,450,250]
#添加约束
model.addConstrs((X.sum(i,'*')<=make[i] for i in range(3)),name = "make")
model.addConstrs((X.sum('*',j)-b1[j]+b2[j]>=need[j] for j in range(4)),name = 'need')
model.addConstrs((X.sum('*',j)-c1[j]+c2[j]>=need[j]*0.8 for j in range(4)),name = '80% need')
model.addConstr(X[2,0]+slack[0,1]-slack[0,0]>=100,name = '工厂3的产品不少于100个单位')
model.addConstr(grb.quicksum(X[i,j]*price[i,j] for i in range(3) for j in range(4))==price_all,name = 'price_all_con')
model.addConstr(price_all+slack[1,1]-slack[1,0]==2950*1.1,'Price_con')
model.addConstr(b2[0]/need[0]+slack[2,1]-slack[2,0]==b2[2]/need[2])
#设立多个目标,根据题意采用分层型
model.setObjectiveN(b2[3],index=0,priority=8,name="目标1")
model.setObjectiveN(slack[0,1],index=1,priority=7,name="目标2")
model.setObjectiveN(c2.sum(),index=2,priority=6,name="目标3")
model.setObjectiveN(b2.sum(),index=3,priority=5,name="目标4")
model.setObjectiveN(slack[1,1],index=4,priority=4,name="目标5")
model.setObjectiveN(X[1,3],index=5,priority=3,name="目标6")
model.setObjectiveN(slack.sum(2,'*'),index=6,priority=2,name="目标7")
model.setObjectiveN(price_all,index=7,priority=1,name="目标8")
#模型写入文件
model.write("test.lp")
# 求解
model.optimize()
for i in range(model.NumObj):
model.setParam(grb.GRB.Param.ObjNumber, i)
print('Obj%d = ' % (i + 1), model.ObjNVal)
X_value = np.zeros((3,4))
for i in X.iterkeys():
X_value[i] = (X.get(i).X)
print("运输矩阵为:\n",X_value,"最小价格为:",model.ObjNVal)
Warning: constraint name "80% need[0]" has a space
Gurobi Optimizer version 9.1.2 build v9.1.2rc0 (win64)
Thread count: 4 physical cores, 8 logical processors, using up to 8 threads
Optimize a model with 15 rows, 35 columns and 75 nonzeros
Model fingerprint: 0x8b575f13
Variable types: 0 continuous, 35 integer (0 binary)
Coefficient statistics:
Matrix range [2e-03, 7e+00]
Objective range [1e+00, 1e+00]
Bounds range [0e+00, 0e+00]
RHS range [8e+01, 3e+03]
---------------------------------------------------------------------------
Multi-objectives: starting optimization with 8 objectives ...
---------------------------------------------------------------------------
Multi-objectives: applying initial presolve ...
---------------------------------------------------------------------------
Presolve removed 1 rows and 1 columns
Presolve time: 0.00s
Presolved: 14 rows and 34 columns
---------------------------------------------------------------------------
Multi-objectives: optimize objective 1 (目标1) ...
---------------------------------------------------------------------------
Found heuristic solution: objective 250.0000000
Presolve removed 7 rows and 21 columns
Presolve time: 0.00s
Presolved: 7 rows, 13 columns, 24 nonzeros
Variable types: 0 continuous, 13 integer (0 binary)
Root relaxation: objective 0.000000e+00, 3 iterations, 0.00 seconds
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
* 0 0 0 0.0000000 0.00000 0.00% - 0s
Explored 0 nodes (3 simplex iterations) in 0.08 seconds
Thread count was 8 (of 8 available processors)
Solution count 2: 0 250
Optimal solution found (tolerance 1.00e-04)
Best objective 0.000000000000e+00, best bound 0.000000000000e+00, gap 0.0000%
---------------------------------------------------------------------------
Multi-objectives: optimize objective 2 (目标2) ...
---------------------------------------------------------------------------
Loaded user MIP start with objective 100
Presolve removed 8 rows and 22 columns
Presolve time: 0.00s
Presolved: 7 rows, 12 columns, 24 nonzeros
Variable types: 0 continuous, 12 integer (0 binary)
Root relaxation: objective 0.000000e+00, 2 iterations, 0.00 seconds
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
* 0 0 0 0.0000000 0.00000 0.00% - 0s
Explored 0 nodes (2 simplex iterations) in 0.12 seconds
Thread count was 8 (of 8 available processors)
Solution count 2: 0 100
Optimal solution found (tolerance 1.00e-04)
Best objective 0.000000000000e+00, best bound 0.000000000000e+00, gap 0.0000%
---------------------------------------------------------------------------
Multi-objectives: optimize objective 3 (目标3) ...
---------------------------------------------------------------------------
Loaded user MIP start with objective 440
Presolve removed 6 rows and 16 columns
Presolve time: 0.00s
Presolved: 10 rows, 18 columns, 38 nonzeros
Variable types: 0 continuous, 18 integer (0 binary)
Root relaxation: objective 0.000000e+00, 8 iterations, 0.00 seconds
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
* 0 0 0 0.0000000 0.00000 0.00% - 0s
Explored 0 nodes (8 simplex iterations) in 0.17 seconds
Thread count was 8 (of 8 available processors)
Solution count 2: 0 440
Optimal solution found (tolerance 1.00e-04)
Best objective 0.000000000000e+00, best bound 0.000000000000e+00, gap 0.0000%
---------------------------------------------------------------------------
Multi-objectives: optimize objective 4 (目标4) ...
---------------------------------------------------------------------------
Loaded user MIP start with objective 150
Presolve removed 6 rows and 18 columns
Presolve time: 0.00s
Presolved: 11 rows, 16 columns, 39 nonzeros
Variable types: 0 continuous, 16 integer (0 binary)
Root relaxation: objective 1.000000e+02, 10 iterations, 0.00 seconds
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
0 0 100.00000 0 2 150.00000 100.00000 33.3% - 0s
H 0 0 137.0000000 100.00000 27.0% - 0s
H 0 0 100.0000000 100.00000 0.00% - 0s
0 0 100.00000 0 2 100.00000 100.00000 0.00% - 0s
Explored 1 nodes (10 simplex iterations) in 0.23 seconds
Thread count was 8 (of 8 available processors)
Solution count 3: 100 137 150
Optimal solution found (tolerance 1.00e-04)
Best objective 1.000000000000e+02, best bound 1.000000000000e+02, gap 0.0000%
---------------------------------------------------------------------------
Multi-objectives: optimize objective 5 (目标5) ...
---------------------------------------------------------------------------
Loaded user MIP start with objective 0
Explored 0 nodes (0 simplex iterations) in 0.25 seconds
Thread count was 1 (of 8 available processors)
Solution count 1: 0
Optimal solution found (tolerance 1.00e-04)
Best objective 0.000000000000e+00, best bound 0.000000000000e+00, gap 0.0000%
---------------------------------------------------------------------------
Multi-objectives: optimize objective 6 (目标6) ...
---------------------------------------------------------------------------
Loaded user MIP start with objective 200
Presolve removed 10 rows and 21 columns
Presolve time: 0.01s
Presolved: 9 rows, 13 columns, 39 nonzeros
Variable types: 0 continuous, 13 integer (0 binary)
Root relaxation: objective 0.000000e+00, 7 iterations, 0.00 seconds
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
* 0 0 0 0.0000000 0.00000 0.00% - 0s
Explored 0 nodes (7 simplex iterations) in 0.30 seconds
Thread count was 8 (of 8 available processors)
Solution count 2: 0 200
Optimal solution found (tolerance 1.00e-04)
Best objective 0.000000000000e+00, best bound 0.000000000000e+00, gap 0.0000%
---------------------------------------------------------------------------
Multi-objectives: optimize objective 7 (目标7) ...
---------------------------------------------------------------------------
Loaded user MIP start with objective 0
Explored 0 nodes (0 simplex iterations) in 0.32 seconds
Thread count was 1 (of 8 available processors)
Solution count 1: 0
Optimal solution found (tolerance 1.00e-04)
Best objective 0.000000000000e+00, best bound 0.000000000000e+00, gap 0.0000%
---------------------------------------------------------------------------
Multi-objectives: optimize objective 8 (目标8) ...
---------------------------------------------------------------------------
Loaded user MIP start with objective 3414
Presolve removed 12 rows and 21 columns
Presolve time: 0.00s
Presolved: 9 rows, 13 columns, 40 nonzeros
Variable types: 0 continuous, 13 integer (0 binary)
Root relaxation: infeasible, 14 iterations, 0.00 seconds
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
0 0 infeasible 0 3414.00000 3414.00000 0.00% - 0s
Explored 0 nodes (14 simplex iterations) in 0.37 seconds
Thread count was 8 (of 8 available processors)
Solution count 1: 3414
Optimal solution found (tolerance 1.00e-04)
Best objective 3.414000000000e+03, best bound 3.414000000000e+03, gap 0.0000%
---------------------------------------------------------------------------
Multi-objectives: solved in 0.38 seconds, solution count 7
Obj1 = 0.0
Obj2 = 0.0
Obj3 = 0.0
Obj4 = 100.0
Obj5 = 0.0
Obj6 = 0.0
Obj7 = 0.0
Obj8 = 3414.0000000000005
运输矩阵为:
[[ -0. 91. -0. 209.]
[ 72. -0. 128. -0.]
[100. -0. 259. 41.]] 最小价格为: 3414.0000000000005