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

如何用SciPy Optimize实现工人排班工资最小化及代码报错解决

工人排班工资最小化问题的代码修正

错误原因分析

你遇到的TypeError: 'DataFrame' object cannot be interpreted as an integer(及后续代码中数组转整数的同类错误),核心问题包括:

  • 错误将DataFrame/NumPy数组传入range()函数,range()仅接受整数参数用于指定循环次数
  • 约束条件格式不符合scipy.optimize.minimize的要求,且未定义目标函数
  • 变量维度理解偏差:优化变量应为每个班次的工人数(共4个变量),而非每个时段的数值

修正后的完整代码

import pandas as pd
import numpy as np
import scipy.optimize as sco
from io import StringIO

# 读取排班数据
with StringIO(
'''Time Windows,Shift 1,Shift 2,Shift 3,Shift 4,Workers Required
    6:00 - 9:00,      1,      0,      0,      1,            55.0
   9:00 - 12:00,      1,      0,      0,      0,            46.0
  12:00 - 15:00,      1,      1,      0,      0,            59.0
  15:00 - 18:00,      0,      1,      0,      0,            23.0
  18:00 - 21:00,      0,      1,      1,      0,            60.0
  21:00 - 24:00,      0,      0,      1,      0,            38.0
   24:00 - 3:00,      0,      0,      1,      1,            20.0
    3:00 - 6:00,      0,      0,      0,      1,            30.0
      Wage_Rate,    135,    140,    190,    188,             0.0''') as f:
    df = pd.read_csv(f, skipinitialspace=True, index_col='Time Windows')

is_shift = df.columns.str.startswith('Shift')
is_wage = df.index == 'Wage_Rate'
# 班次覆盖矩阵:行=时段,列=班次,值为1表示该班次覆盖对应时段
shift_matrix = df.loc[~is_wage, is_shift].values
# 各班次工资率数组
wage_rates = df.loc[is_wage, is_shift].squeeze().values
# 各时段所需最小工人数数组
required_workers = df.loc[~is_wage, 'Workers Required'].values

# 1. 定义目标函数:总工资支出最小化
def total_wages(x):
    # x为每个班次的工人数数组,总工资=班次人数×对应工资率的总和
    return np.sum(x * wage_rates)

# 2. 定义约束条件:每个时段的在岗工人总数≥所需人数
constraints = [{
    'type': 'ineq',
    'fun': lambda x: np.dot(shift_matrix, x) - required_workers
}]

# 3. 定义变量边界:每个班次的工人数≥0(无强制上限)
num_shifts = len(wage_rates)
bounds = tuple((0, None) for _ in range(num_shifts))

# 4. 初始化变量猜测值:按时段需求均值初始化
x0 = np.ones(num_shifts) * np.mean(required_workers)

# 执行优化计算
result = sco.minimize(
    fun=total_wages,
    x0=x0,
    method='SLSQP',
    bounds=bounds,
    constraints=constraints
)

# 输出优化结果
print("优化状态:", "成功" if result.success else "失败")
print("最小总工资支出:", round(result.fun, 2))
print("各班次最优工人数:", np.round(result.x, 2))

关键修正点说明

  • 目标函数:明确总工资计算逻辑,将班次人数与对应工资率相乘后求和
  • 约束条件:采用scipy要求的字典格式,通过矩阵乘法快速计算每个时段的在岗总人数,确保满足时段需求
  • 边界设置:根据班次数量生成边界,保证每个班次工人数非负
  • 变量维度:优化变量与班次数量对齐(4个变量对应4个班次),符合线性规划的变量定义逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 01:37:54