6.(Python数模)游泳接力指派问题

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

运行结果

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

海绵波波107

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

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

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

打赏作者

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

抵扣说明:

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

余额充值