Python解决游泳接力指派问题
该问题也属于一个线性规划问题
源代码
import pulp # 导入 pulp 库
import numpy as np
# 主程序
def main():
# 问题建模:
"""
决策变量:
x(i,j) = 0, 第 i 个人不游第 j 种姿势
x(i,j) = 1, 第 i 个人游第 j 种姿势
i=1,4, j=1,4
目标函数:
min time = sum(sum(c(i,j)*x(i,j))), i=1,4, j=1,4
约束条件:
sum(x(i,j),j=1,4)=1, i=1,4
sum(x(i,j),i=1,4)=1, j=1,4
变量取值范围:
x(i,j) = 0,1
"""
# 游泳比赛的指派问题 (assignment problem)
# 1.建立优化问题 AssignLP: 求最小值(LpMinimize)
AssignLP = pulp.LpProblem("Assignment_problem_for_swimming_relay_race", sense=pulp.LpMinimize) # 定义问题,求最小值
# 2. 建立变量
rows = cols = range(0, 4)
x = pulp.LpVariable.dicts("x", (rows, cols), cat="Binary")
# 3. 设置目标函数
scoreM = [[56,74,61,63],[63,69,65,71],[57,77,63,67],[55,76,62,62]]
AssignLP += pulp.lpSum([[x[row][col]*scoreM[row][col] for row in rows] for col in cols])
# 4. 施加约束
for row in rows:
AssignLP += pulp.lpSum([x[row][col] for col in cols]) == 1 # sum(x(i,j),j=1,4)=1, i=1,4
for col in cols:
AssignLP += pulp.lpSum([x[row][col] for row in rows]) == 1 # sum(x(i,j),i=1,4)=1, j=1,4
# 5. 求解
AssignLP.solve()
# 6. 打印结果
print(AssignLP.name)
member = ["队员A","队员B","队员C","队员D"]
style = ["自由泳","蛙泳","蝶泳","仰泳"]
if pulp.LpStatus[AssignLP.status] == "Optimal": # 获得最优解
xValue = [v.varValue for v in AssignLP.variables()]
# [0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
xOpt = np.array(xValue).reshape((4, 4)) # 将 xValue 格式转换为 4x4 矩阵
print("最佳分配:" )
for row in rows:
print("{}\t{} 参加项目:{}".format(xOpt[row],member[row],style[np.argmax(xOpt[row])]))
print("预测最好成绩为:{}".format(pulp.value(AssignLP.objective)))
return
if __name__ == '__main__':
main()
要注意的是,在pulp库中,可以使用pulp.lpsum()函数来对线性表达式求和,例如pulp.lpSum([x[row][col] for col in cols]) == 1