scipy求解指派问题

1. 指派问题

1.1 问题描述

某公司准备指派 n n n个工人 X 1 , X 2 , . . . , X n X_1,X_2,...,X_n X1X2...Xn n n n件工作 Y 1 , Y 2 , . . . , Y n Y_1,Y_2,...,Y_n Y1Y2...Yn,由于每个工人完成不同工作的效率不同,公司希望在所有工作都得到完成的前提下使得效率达到最大考虑。这类指派问题也称为二部图的最小权重匹配问题(minimum weight matching in bipartite graphs)。

一个赋权的完全二部图 G = ( V 1 , V 2 , E ) G=(V_1,V_2,E) G=V1V2E,其中 V 1 = ( X 1 , X 2 , . X n ) V_1=(X_1,X2,.Xn) V1=X1X2.Xn V 2 = ( Y 1 , Y 2 , . . . , Y n ) V_2=(Y_1,Y_2,...,Y_n) V2=Y1Y2...Yn,边 ( X i , Y j ) (X_i,Y_j) (XiYj)上的权重 c i j c_{ij} cij表示工人 X i X_i Xi完成工作 Y j Y_j Yj的效率。指派问题显然等价于在该图中寻找有最小权重的完美匹配。

1.2 数学模型

指派问题可表述为如下0-1规划问题
m i n ∑ i = 1 n ∑ j = 1 n c i j x i j ∑ i = 1 n x i j = 1 , i = 1 , 2 , . . . n ∑ j = 1 n x i j = 1 , j = 1 , 2 , . . . n x i j ∈ { 0 , 1 } min\sum_{i=1}^{n}\sum_{j=1}^{n}{c_{ij} x_{ij}}\\ \sum_{i=1}^{n}x_{ij} =1, \quad i=1,2,...n\\ \sum_{j=1}^{n}x_{ij} = 1, \quad j=1,2,...n\\ x_{ij}\in{\{0,1}\} mini=1nj=1ncijxiji=1nxij=1,i=1,2,...nj=1nxij=1,j=1,2,...nxij{0,1}

2. Scipy求解

  • scipy.optimize.linear_sum_assignment求解指派问题使用的是匈牙利算法,对于数据要求比较苛刻,成本矩阵不能太大,如果是大型矩阵需要先进行稀疏处理,否则求解效率会变低。
  • Scipy官方API
scipy.optimize.linear_sum_assignment()
Solve the linear sum assignment problem.

Parameters:
cost_matrixarray
The cost matrix of the bipartite graph.

maximizebool (default: False)
Calculates a maximum weight matching if true.

Returns:
row_ind, col_indarray
An array of row indices and one of corresponding column indices giving the optimal assignment. The cost of the assignment can be computed as cost_matrix[row_ind, col_ind].sum(). The row indices will be sorted; in the case of a square cost matrix they will be equal to numpy.arange(cost_matrix.shape[0]).
  • python代码示例
import numpy as np
from scipy.optimize import linear_sum_assignment

worker_num = 10  # 员工数量
job_num = 10  # 任务数量
# 随机生成成本矩阵
cost_matrix = np.random.randint(1, 10, size=(worker_num, job_num))

# 优化求解得到最佳分配下的行列索引值
row_ind, col_ind = linear_sum_assignment(cost_matrix)

# 输出结果
print('cost_matrix=\n', cost_matrix)
for i in list(zip(row_ind + 1, col_ind + 1)):
    print(i[0], '->', i[1])
print('min_cost=', cost_matrix[row_ind, col_ind].sum())
  • 结果

请添加图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值