Understanding how to set soft constraints using Google OR -tools

大城市里の小女人 提交于 2021-02-07 08:55:23

问题


I have been using Google OR-tools and trying to follow along with their examples for scheduling problems. However, the python documentation is sometimes hard to follow, and the more complex example ( https://github.com/google/or-tools/blob/master/examples/python/shift_scheduling_sat.py) is not described well.

I want to be able to set hard and soft constraints on the amount of shifts employees work. In the above example I believe the function add_soft_sum_constraint() (I've put its exact code below) does what I want to do. I would like to replicate its functionality but I don't understand how it is doing it.

In the 2 if statements Im unsure what the delta and excess variables represent, and why they are adding more constraints, rather than just add more to the 2 cost lists which will be used when they minimize the objective later.

If anyone has any insight into this example I would be grateful, thanks.

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:


For soft_min:

  • delta: distance to the soft_min soft_min - sum_var, if it is negative it means that we are above that soft_constraint so the penalty should be 0, model.AddMaxEquality(excess, [delta, 0]).

  • excess: how far are we from the soft_min, used to discard negative deltas, this is what we will multiply by min_cost.

For soft_max:

It is pretty much the same but reversed.

  • delta: distance to the soft_max sum_var - soft_max, if it is negative it means that we are below that soft_constraint so the penalty should be 0, model.AddMaxEquality(excess, [delta, 0])

  • excess: how far are we from the soft_max, used to discard negative deltas, this is what we will multiply by max_cost.

Returns:

It returns the coefficients and variables, for example:

Let's say that the soft_min is 3 and the min_cost is 2:

  • if someone works 2 days the excess is 1 and the cost will be 1*2.
  • if someone works 1 day the excess is 2 and the cost will be 2*2.

Let's also say that the soft_max is 5 and the max_cost is 3:

  • if someone works 6 days the excess is 1 and the cost will be 1*3.

Our variables are [1, 2, 1] and their coefficients [2, 2, 3].



来源:https://stackoverflow.com/questions/56787655/understanding-how-to-set-soft-constraints-using-google-or-tools

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!