I'm working on a scheduler in CP-Sat on OR Tools (Python) and I'm trying to extend this constraint
// Cover constraints
foreach (int s in Range(1, numShifts))
{
foreach (int w in Range(numWeeks))
{
foreach (int d in Range(7))
{
var works = new BoolVar[numEmployees];
foreach (int e in Range(numEmployees))
{
works[e] = work[e, s, w * 7 + d];
}
// Ignore off shift
var minDemand = weeklyCoverDemands[d][s - 1];
var worked = model.NewIntVar(minDemand, numEmployees, "");
model.Add(LinearExpr.Sum(works) == worked);
var overPenalty = excessCoverPenalties[s - 1];
if (overPenalty > 0)
{
var name = $"excess_demand(shift={s}, week={w}, day={d}";
var excess = model.NewIntVar(0, numEmployees - minDemand, name);
model.Add(excess == worked - minDemand);
obj.AddTerm(excess, overPenalty);
}
}
}
As I understand, it penalize too many shifts per day.
How I can extend/edit it so it will try to reach the target (minDemand)? In other words: how I can penalize both excess and insufficiency? Ideally with some kind a multiplication on a cost, so the further from the target, the higher the cost.
All my efforts ended on INFEASIBLE or UNKNOWN statuses.
It is implemented here: https://github.com/google/or-tools/blob/d37317b17ca16658451cafe05085fc22c39dd6c8/examples/python/shift_scheduling_sat.py#L131