我一直在使用Google OR工具,并尝试按照其示例来安排问题。但是,有时有时很难遵循python文档,而且对较复杂的示例(https://github.com/google/or-tools/blob/master/examples/python/shift_scheduling_sat.py)的描述也不够好。
我希望能够对员工的工作班次设置硬性约束和软性约束。在上面的示例中,我相信函数add_soft_sum_constraint()
(我在下面给出了确切的代码)可以完成我想做的事情。我想复制它的功能,但我不知道它的功能。
在2个if语句中,我不确定delta
和excess
变量的含义,以及它们为何添加更多约束的原因,而不仅是在将要使用的两个成本列表中添加更多约束稍后将目标最小化。
如果有人对此示例有任何见解,我将不胜感激。
def add_soft_sum_constraint(model, works, hard_min, soft_min, min_cost,
soft_max, hard_max, max_cost, prefix):
cost_variables = []
cost_coefficients = []
sum_var = model.NewIntVar(hard_min, hard_max, '')
# This adds the hard constraints on the sum.
model.Add(sum_var == sum(works))
# Penalize sums below the soft_min target.
if soft_min > hard_min and min_cost > 0:
delta = model.NewIntVar(-len(works), len(works), '')
model.Add(delta == soft_min - sum_var)
# TODO(user): Compare efficiency with only excess >= soft_min - sum_var.
excess = model.NewIntVar(0, 7, prefix + ': under_sum')
model.AddMaxEquality(excess, [delta, 0])
cost_variables.append(excess)
cost_coefficients.append(min_cost)
# Penalize sums above the soft_max target.
if soft_max < hard_max and max_cost > 0:
delta = model.NewIntVar(-7, 7, '')
model.Add(delta == sum_var - soft_max)
excess = model.NewIntVar(0, 7, prefix + ': over_sum')
model.AddMaxEquality(excess, [delta, 0])
cost_variables.append(excess)
cost_coefficients.append(max_cost)
return cost_variables, cost_coefficients
答案 0 :(得分:4)
增量:
距soft_min soft_min - sum_var
的距离,如果为负,则意味着我们在soft_constraint之上,因此惩罚应该为0,model.AddMaxEquality(excess, [delta, 0])
。
过多:
我们距用来丢弃负增量的soft_min有多远,这就是我们将乘以min_cost
的乘积。
几乎相同,但是相反。
增量:
距soft_max sum_var - soft_max
的距离,如果为负,则表示我们低于该soft_constraint,因此惩罚应为0,model.AddMaxEquality(excess, [delta, 0])
过多:
我们距用于丢弃负增量的soft_max有多远,这就是我们将乘以max_cost
的乘积。
它返回系数和变量,例如:
假设soft_min为3,min_cost为2:
我们也可以说soft_max为5,max_cost为3:
我们的变量为[1、2、1],其系数为[2、2、3]。