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

如何编写基于DataFrame的Pulp优化函数?求无循环实现方案

解决Pulp优化问题(无显式for循环实现约束)

首先把时间转换为小时数值便于计算,然后利用Pandas的结构和Pulp的批量约束添加能力,避免显式for循环实现所有约束:

import pulp
import pandas as pd

# 1. 预处理数据:转换时间为小时数
df = pd.DataFrame({
    'seniority': [3,4,1],
    'target': [6,6,6],
    'morning_out': ['08:50', '08:20', '08:40'],
    'afternoon_in': ['14:30', '15:20', '13:00']
})

def time_to_hours(time_str):
    h, m = map(int, time_str.split(':'))
    return h + m/60

# 转换已知时间列为小时数
df['morning_out_h'] = df['morning_out'].apply(time_to_hours)
df['afternoon_in_h'] = df['afternoon_in'].apply(time_to_hours)

# 2. 创建优化问题与变量
prob = pulp.LpProblem("Shift_Optimization", pulp.LpMinimize)
# 约束1要求所有行的morning_in和afternoon_out相同,因此定义全局变量即可
morning_in = pulp.LpVariable("morning_in", lowBound=0, upBound=24)
afternoon_out = pulp.LpVariable("afternoon_out", lowBound=0, upBound=24)

# 3. 添加约束(无显式for循环)
# 约束2:每行工作时长等于target,用列表推导式批量添加
prob += [
    (row.morning_out_h - morning_in) + (afternoon_out - row.afternoon_in_h) == row.target
    for _, row in df.iterrows()
]

# 约束3:按seniority定义morning_in的范围,基于唯一seniority值批量添加
seniority_bounds = {1: (7, 8), 3: (6.5, 7.5), 4: (6, 7)}
prob += [morning_in >= seniority_bounds[s][0] for s in df.seniority.unique()]
prob += [morning_in <= seniority_bounds[s][1] for s in df.seniority.unique()]

# 约束4:afternoon_out的时间范围
prob += (afternoon_out >= 16) & (afternoon_out <= 19)

# 4. 求解并输出结果
prob.solve()
print(f"求解状态: {pulp.LpStatus[prob.status]}")
if pulp.LpStatus[prob.status] == 'Optimal':
    def hours_to_time(hours):
        h = int(hours)
        m = int((hours - h)*60)
        return f"{h}:{m:02d}"
    print(f"统一morning_in: {hours_to_time(pulp.value(morning_in))}")
    print(f"统一afternoon_out: {hours_to_time(pulp.value(afternoon_out))}")

关键说明:

  • 约束1实现:通过定义全局变量morning_in和afternoon_out,所有行共用这两个变量,自动满足“所有行值相同”的要求,无需额外约束。
  • 约束2实现:用列表推导式替代显式for循环,批量生成每行的时长等式约束。
  • 约束3实现:基于df.seniority.unique()获取唯一职级,避免遍历所有行,批量添加范围约束。
  • 约束4实现:直接添加范围约束,无需循环。

注:你提供的样本数据中,不同行的时长约束会推导出矛盾的afternoon_out - morning_in值,因此实际求解会显示Infeasible(无解),这属于数据逻辑问题,而非代码实现问题。

内容的提问来源于stack exchange,提问作者Mikić Danko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 14:27:03