数学规划-指派问题

问题:

某公司指派n个员工到n个城市工作(每个城市单独一人),希望使所花费的总电话费用
尽可能少.n个员工两两之间每个月通话的时间表示在下面的矩阵的上三角形部分(假
设通话的时间矩阵是对称的,没有必要写出下三角形部分),n个城市两两之间通话费率
表示在下面的矩阵的下三角形部分(同样道理,假设通话的费率矩阵是对称的,没有必
要写出上三角形部分).试求解该二次指派问题.(如果你的软件解不了这么大规模的
问题.那就只考虑最前面的若干员工和城市.)

[0 , 5 , 3 , 7 ,  9 , 3 , 9 , 2 , 9 , 0 ]
[7 , 0 , 7 , 8 ,  3 , 2 , 3 , 3 , 5 , 7 ]
[4 , 8 , 0 , 9 ,  3 , 5 , 3 , 3 , 9 , 3 ]
[6 , 2 , 10, 0 ,  8 , 4 , 1 , 8 , 0 , 4 ]
[8 , 6 , 4 , 6 ,  0 , 8 , 8 , 7 , 5 , 9 ]
[8 , 5 , 4 , 6 ,  6 , 0 , 4 , 8 , 0 , 3 ]
[8 , 6 , 7 , 9 ,  4 , 3 , 0 , 7 , 9 , 5 ]
[6 , 8 , 2 , 3 ,  8 , 8 , 6 , 0 , 5 , 5 ]
[6 , 3 , 6 , 2 ,  8 , 3 , 7 , 8 , 0 , 5 ]
[5 , 6 , 7 , 6 ,  6 , 2 , 8 , 8 , 9 , 0 ]

设0-1变量 x i j x_{ij} xij若为1则代表将第i个员工派向第j个城市,若为0则代表未指派 t i m e i m time_{im} timeim表示第i个和第m个员工之间的通话和时间, p r i c e j n price_{jn} pricejn表示j和n城之间的通话费率,那么即可建立模型如下
M i n q q u a d y = ∑ i , j , m , n = 1 i , j , m , n = 10 x i j ∗ x m n ∗ t i m e i m ∗ p r i c e j n 2 S . T . { ∑ i = 1 i = 10 x i j = = 1 ∑ j = 1 j = 10 x i j = = 1 x i j = { 1 0 Min \\qquad y =\frac{\sum_{i,j,m,n=1}^{i,j,m,n=10} x_{ij}*x_{mn}*time_{im}*price_{jn}}{2}\\ S.T.\left\{ \begin{aligned} \sum_{i=1}^{i=10}x_{ij}==1\\ \sum_{j=1}^{j=10}x_{ij}==1\\ x_{ij}=\left\{ \begin{aligned} 1 \\ 0 \\ \end{aligned} \right. \end{aligned} \right. Minqquady=2i,j,m,n=1i,j,m,n=10xijxmntimeimpricejnS.T.i=1i=10xij==1j=1j=10xij==1xij={10

import numpy as np
import gurobipy as grb
from gurobipy import *

rec = np.array([[0 , 5 , 3 , 7 ,  9 , 3 , 9 , 2 , 9 , 0 ]
               ,[7 , 0 , 7 , 8 ,  3 , 2 , 3 , 3 , 5 , 7 ]
               ,[4 , 8 , 0 , 9 ,  3 , 5 , 3 , 3 , 9 , 3 ]
               ,[6 , 2 , 10, 0 ,  8 , 4 , 1 , 8 , 0 , 4 ]
               ,[8 , 6 , 4 , 6 ,  0 , 8 , 8 , 7 , 5 , 9 ]
               ,[8 , 5 , 4 , 6 ,  6 , 0 , 4 , 8 , 0 , 3 ]
               ,[8 , 6 , 7 , 9 ,  4 , 3 , 0 , 7 , 9 , 5 ]
               ,[6 , 8 , 2 , 3 ,  8 , 8 , 6 , 0 , 5 , 5 ]
               ,[6 , 3 , 6 , 2 ,  8 , 3 , 7 , 8 , 0 , 5 ]
               ,[5 , 6 , 7 , 6 ,  6 , 2 , 8 , 8 , 9 , 0 ]])
triu = np.triu(rec)#取出矩阵的上三角部分
tril = np.tril(rec)#取出矩阵的下三角部分
time = triu+triu.T
price = tril+tril.T
print("各员工通话时间为:\n",time,"\n","各城市通话单价为:\n",price)

model = grb.Model("Company")
x = model.addVars(10,10,vtype=grb.GRB.BINARY,name = "是否指派")
objective = grb.quicksum(x[i,j] * x[m,n] * time[i,m] * price[j,n] for i in range(10) for j in range(10) for m in range(10) for n in range(10))
#设置目标函数
model.setObjective(objective/2,grb.GRB.MINIMIZE)
#添加约束
model.addConstrs((x.sum(i,'*')==1 for i in range(10)),"行")
model.addConstrs((x.sum('*',i)==1 for i in range(10)),"列")
# 求解
model.optimize()
print('目标函数值是:', model.objVal)
if model.status == GRB.OPTIMAL:
    model.printAttr('X')
    model.printAttr('Slack')
    print("指派矩阵为:\n",np.array(model.X).reshape(10,10))
各员工通话时间为:
 [[0 5 3 7 9 3 9 2 9 0]
 [5 0 7 8 3 2 3 3 5 7]
 [3 7 0 9 3 5 3 3 9 3]
 [7 8 9 0 8 4 1 8 0 4]
 [9 3 3 8 0 8 8 7 5 9]
 [3 2 5 4 8 0 4 8 0 3]
 [9 3 3 1 8 4 0 7 9 5]
 [2 3 3 8 7 8 7 0 5 5]
 [9 5 9 0 5 0 9 5 0 5]
 [0 7 3 4 9 3 5 5 5 0]] 
 各城市通话单价为:
 [[ 0  7  4  6  8  8  8  6  6  5]
 [ 7  0  8  2  6  5  6  8  3  6]
 [ 4  8  0 10  4  4  7  2  6  7]
 [ 6  2 10  0  6  6  9  3  2  6]
 [ 8  6  4  6  0  6  4  8  8  6]
 [ 8  5  4  6  6  0  3  8  3  2]
 [ 8  6  7  9  4  3  0  6  7  8]
 [ 6  8  2  3  8  8  6  0  8  8]
 [ 6  3  6  2  8  3  7  8  0  9]
 [ 5  6  7  6  6  2  8  8  9  0]]
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 20 rows, 100 columns and 200 nonzeros
Model fingerprint: 0xc0a57822
Model has 3780 quadratic objective terms
Variable types: 0 continuous, 100 integer (100 binary)
Coefficient statistics:
  Matrix range     [1e+00, 1e+00]
  Objective range  [0e+00, 0e+00]
  QObjective range [4e+00, 2e+02]
  Bounds range     [1e+00, 1e+00]
  RHS range        [1e+00, 1e+00]
Found heuristic solution: objective 1397.0000000
Presolve time: 0.01s
Presolved: 20 rows, 100 columns, 200 nonzeros
Presolved model has 3880 quadratic objective terms
Variable types: 0 continuous, 100 integer (100 binary)

Root relaxation: objective -3.181574e+03, 120 iterations, 0.02 seconds

    Nodes    |    Current Node    |     Objective Bounds      |     Work
 Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time

H    0     0                    1329.0000000    0.00000   100%     -    0s
     0     0   -0.00000    0  100 1329.00000    0.00000   100%     -    0s
H    0     0                    1306.0000000    0.00000   100%     -    0s
H    0     0                    1267.0000000    0.00000   100%     -    0s
     0     0   -0.00000    0  100 1267.00000    0.00000   100%     -    0s
H    0     0                    1264.0000000    0.00000   100%     -    0s
     0     2   -0.00000    0  100 1264.00000    0.00000   100%     -    0s
H   37    40                    1261.0000000    0.00000   100%   3.3    0s
H   71    88                    1252.0000000    0.00000   100%   3.1    0s
H 1173   816                    1249.0000000    2.00000   100%   7.3    1s
*15853  7601              56    1239.0000000  230.86615  81.4%  10.7    4s
 18849  8805  536.85272   46   27 1239.00000  248.95813  79.9%  10.6    5s
 30142 13049  321.91415   39  150 1239.00000  321.91415  74.0%  10.2   10s
H30176 12420                    1236.0000000  321.91415  74.0%  10.2   11s
*31767 12255              71    1235.0000000  425.65511  65.5%  11.1   12s
H32185 11796                    1231.0000000  434.92542  64.7%  11.3   12s
H35370 11959                    1225.0000000  626.06833  48.9%  12.3   13s
 37995 12792 1082.77385   59   43 1225.00000  646.16346  47.3%  12.9   15s
*49553 13460              61    1210.0000000  804.21558  33.5%  14.3   18s
*51315 12861              57    1194.0000000  814.04601  31.8%  14.3   18s
*54842 11950              58    1181.0000000  825.96584  30.1%  14.5   19s
 57575 11873 1068.54293   56   46 1181.00000  835.93457  29.2%  14.6   20s
 81670 17253 1178.88719   59   31 1181.00000  888.77588  24.7%  15.2   25s
 107671 20010 1113.69678   61   38 1181.00000  991.67959  16.0%  15.2   30s
H109601 16775                    1142.0000000  994.64106  12.9%  15.2   30s
 132285  8001     cutoff   56      1142.00000 1054.99461  7.62%  15.1   35s

Cutting planes:
  Gomory: 4
  Implied bound: 15
  MIR: 15
  StrongCG: 1
  Flow cover: 103
  Zero half: 1

Explored 143305 nodes (2134002 simplex iterations) in 36.46 seconds
Thread count was 8 (of 8 available processors)

Solution count 10: 1142 1181 1194 ... 1249

Optimal solution found (tolerance 1.00e-04)
Best objective 1.142000000000e+03, best bound 1.142000000000e+03, gap 0.0000%
目标函数值是: 1142.0

    Variable            X 
-------------------------
   /&>[0,8]            1 
   /&>[1,0]            1 
   /&>[2,7]            1 
   /&>[3,2]            1 
   /&>[4,5]            1 
   /&>[5,6]            1 
   /&>[6,1]            1 
   /&>[7,4]            1 
   /&>[8,3]            1 
   /&>[9,9]            1 

  Constraint        Slack 
-------------------------
指派矩阵为:
 [[0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]
 [0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
 [0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]]
  • 6
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kilig*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值