问题描述
我正在尝试用 Python 解决排班优化问题,该问题与本 article 中概述的问题略有不同。唯一的问题是我不能使用 pulp
包,因为它不是线性问题。
据我所知,解决我的问题的最佳方法是使用 scipy.optimize
包,但是我在将以下 problem formulation 转换为实际代码时遇到了困难。输入很简单(两个数组),目标是最小化具有约束的函数。
问题表述
- 维度:
i=1...T
(一天中的小时数),j=1...n
(一天中多小时轮班的总数) - 输入:
a[i,j]
(存储班次配置的二维数组)和d[i]
(小时i
的预期需求) - 输出:脚本必须返回每个班次所需的最佳工人数量
w[j]
- 最小化:我们希望最大限度地减少员工一天的总成本。使问题稍微复杂一点的是每小时成本
c[i]
是w[j]
的函数(如果工人太多,我们不支付相同的小时工资):min(sum c[i])
( i=1...T) 其中c[i] = d[i]^2 / sum(a[i,j]*w[j])
(j=1...n). - 约束:对于所有 i,
sum a[i,j] w[j] >= d[i]
(确保工人能够满足每小时的需求水平)
w = pulp.LpVariable.dicts("num_workers",list(range(n)),lowBound=0,cat="Integer")
pulp.lpSum([(d[i]^2 / pulp.lpSum([a[i,j] * w[j] for j in range(n)])) for i in range(T)])
类型错误:不支持 / 的操作数类型:'int' 和 'LpAffineExpression'
谁能给我一些关于如何将以下问题转化为 SciPi 可以理解的实际代码的提示?谢谢!
解决方法
是的,正如评论中所建议的,可以通过使用分段线性化来近似大多数非线性约束和目标。它显着降低了问题的计算复杂性。
但是,对于 Python 中的非线性优化,您可以考虑使用 pyomo 优化包,它完全支持开源非线性求解器(ipopt 用于连续问题,couenne 用于非凸混合整数非线性规划或 bonmin 用于凸混合整数非线性规划
,我认为你的公式有问题....
首先,一个错字:在 python
求幂中是双星号,所以这是正确的(你只是在这个命中之前弹出了一个不同的错误):
d[i]**2
其次,我认为您的成本函数 c[i]
有问题。如上所述,您雇用的工人越多,您的成本就会下降,这是荒谬的。如果您在时间段 i
内雇用了 100 万工人,那么成本将非常小。
我建议您仔细研究成本和工资之间的关系。并在此过程中重新标记一些内容以使其更易于阅读:
x: Number of workers to hire
w: Wage (indexed by either shift or hour,doesn't matter)
c: Cost (indexed by wage or hour)
将几个示例数字手工塞入这些公式中,以确保您从中得到可信的结果。
如果我误解了这一点,请回复评论......