了解如何使用Google OR工具设置软约束

时间:2019-06-27 09:08:56

标签: python or-tools

我一直在使用Google OR工具,并尝试按照其示例来安排问题。但是,有时有时很难遵循python文档,而且对较复杂的示例(https://github.com/google/or-tools/blob/master/examples/python/shift_scheduling_sat.py)的描述也不够好。

我希望能够对员工的工作班次设置硬性约束和软性约束。在上面的示例中,我相信函数add_soft_sum_constraint()(我在下面给出了确切的代码)可以完成我想做的事情。我想复制它的功能,但我不知道它的功能。

在2个if语句中,我不确定deltaexcess变量的含义,以及它们为何添加更多约束的原因,而不仅是在将要使用的两个成本列表中添加更多约束稍后将目标最小化。

如果有人对此示例有任何见解,我将不胜感激。

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

1 个答案:

答案 0 :(得分:4)

对于soft_min:

  • 增量: 距soft_min soft_min - sum_var的距离,如果为负,则意味着我们在soft_constraint之上,因此惩罚应该为0,model.AddMaxEquality(excess, [delta, 0])

  • 过多: 我们距用来丢弃负增量的soft_min有多远,这就是我们将乘以min_cost的乘积。

对于soft_max:

几乎相同,但是相反。

  • 增量: 距soft_max sum_var - soft_max的距离,如果为负,则表示我们低于该soft_constraint,因此惩罚应为0,model.AddMaxEquality(excess, [delta, 0])

  • 过多: 我们距用于丢弃负增量的soft_max有多远,这就是我们将乘以max_cost的乘积。

返回:

它返回系数和变量,例如:

假设soft_min为3,min_cost为2:

  • 如果某人工作2天,超出部分为1,费用为1 * 2。
  • 如果某人工作1天,超出部分为2,费用为2 * 2。

我们也可以说soft_max为5,max_cost为3:

  • 如果某人工作了6天,则超出部分为1,费用为1 * 3。

我们的变量为[1、2、1],其系数为[2、2、3]。