title: Understanding how to set soft constraints using Google OR -tools
body: <p>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 ( <a href="https://github.com/google/or-tools/blob/master/examples/python/shift_scheduling_sat.py" rel="nofollow noreferrer">https://github.com/google/or-tools/blob/master/examples/python/shift_scheduling_sat.py</a>) is not described well.</p>
  
  <p>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 <code>add_soft_sum_constraint()</code> (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.</p>
  
  <p>In the 2 if statements Im unsure what the <code>delta</code> and <code>excess</code> 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.</p>
  
  <p>If anyone has any insight into this example I would be grateful, thanks.</p>
  
  <pre><code>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 &gt; hard_min and min_cost &gt; 0:
      delta = model.NewIntVar(-len(works), len(works), '')
      model.Add(delta == soft_min - sum_var)
      # TODO(user): Compare efficiency with only excess &gt;= 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 &lt; hard_max and max_cost &gt; 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
  </code></pre>