You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Python PuLP的多向换班线性规划:限制最大参与人数

解决方案:限制换班参与人数/环大小

要限制换班为最多三方参与(即形成的环大小不超过3),可以通过添加线性规划约束实现,以下是两种简洁的实现方式:

方法1:限制换班总次数

换班的总次数等于参与换班的人数(每个环的换班次数等于环内人数),因此直接约束总换班次数不超过3即可避免四方环:

import pulp

participants = ['Alice', 'Bob', 'Charlie', 'David']
weights = {'Alice': 1, 'Bob': 3, 'Charlie': 2, 'David': 1}
allowed_swaps = [('Alice', 'Bob'), ('Bob', 'Alice'), ('Bob', 'Charlie'), ('Charlie', 'David'),
                 ('Charlie', 'Alice'), ('Charlie', 'Bob'), ('David', 'Alice')]

swaps = pulp.LpVariable.dicts('Swap', allowed_swaps, cat='Binary')
model = pulp.LpProblem("DutySwap", pulp.LpMaximize)

# 目标函数
model += pulp.lpSum((1000 + weights[p1] + weights[p2]) * swaps[(p1, p2)] for (p1, p2) in allowed_swaps)

# 原有基础约束
for p in participants:
    model += pulp.lpSum(swaps[(p1, p2)] for (p1, p2) in allowed_swaps if p1 == p) <= 1
    model += pulp.lpSum(swaps[(p1, p2)] for (p1, p2) in allowed_swaps if p2 == p) <= 1
    model += (pulp.lpSum(swaps[(p1, p2)] for (p1, p2) in allowed_swaps if p1 == p)
              == pulp.lpSum(swaps[(p1, p2)] for (p1, p2) in allowed_swaps if p2 == p))

# 新增约束:最多3次换班(对应最多3人参与的环)
model += pulp.lpSum(swaps[(p1, p2)] for (p1, p2) in allowed_swaps) <= 3

status = model.solve()
for (p1, p2) in allowed_swaps:
    if pulp.value(swaps[(p1, p2)]) == 1:
        print(f"{p1}'s duty goes to {p2}")

方法2:明确限制参与人数

通过新增二进制变量标记参与者是否参与换班,直接约束参与人数上限:

import pulp

participants = ['Alice', 'Bob', 'Charlie', 'David']
weights = {'Alice': 1, 'Bob': 3, 'Charlie': 2, 'David': 1}
allowed_swaps = [('Alice', 'Bob'), ('Bob', 'Alice'), ('Bob', 'Charlie'), ('Charlie', 'David'),
                 ('Charlie', 'Alice'), ('Charlie', 'Bob'), ('David', 'Alice')]

swaps = pulp.LpVariable.dicts('Swap', allowed_swaps, cat='Binary')
# 新增变量:标记参与者是否参与换班
in_swap = pulp.LpVariable.dicts('InSwap', participants, cat='Binary')

model = pulp.LpProblem("DutySwap", pulp.LpMaximize)

# 目标函数
model += pulp.lpSum((1000 + weights[p1] + weights[p2]) * swaps[(p1, p2)] for (p1, p2) in allowed_swaps)

# 原有基础约束
for p in participants:
    model += pulp.lpSum(swaps[(p1, p2)] for (p1, p2) in allowed_swaps if p1 == p) <= 1
    model += pulp.lpSum(swaps[(p1, p2)] for (p1, p2) in allowed_swaps if p2 == p) <= 1
    model += (pulp.lpSum(swaps[(p1, p2)] for (p1, p2) in allowed_swaps if p1 == p)
              == pulp.lpSum(swaps[(p1, p2)] for (p1, p2) in allowed_swaps if p2 == p))
    # 关联参与状态与换班行为:参与换班则发起1次换班,否则0次
    model += pulp.lpSum(swaps[(p1, p2)] for (p1, p2) in allowed_swaps if p1 == p) == in_swap[p]

# 新增约束:最多3人参与换班
model += pulp.lpSum(in_swap[p] for p in participants) <= 3

status = model.solve()
for (p1, p2) in allowed_swaps:
    if pulp.value(swaps[(p1, p2)]) == 1:
        print(f"{p1}'s duty goes to {p2}")

效果说明

两种方法都会让模型优先选择权重总和最高的三方换班环(即Alice→Bob→Charlie→Alice),因为该方案的目标函数得分远高于其他小环组合,同时避免了四方环的生成。如果需要强制恰好3人参与,可将约束中的<=3改为==3(需确保存在可行的三方环)。

内容的提问来源于stack exchange,提问作者Oehoe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 08:29:50