I am using a CP-SAT solver for optimization purposes using Python.
I have a certain amount of IntVars with their names representing events. I would like to have a minimum delay between each var without any particular order in the events. I have tried many things, but the closest I've come to a solution is using boolvars like this (I've tried with abs() but it seems the library does not accept it) :
dictio_bool[k] = model.NewBoolVar('') #dictio_bool is a dictionary to stock boolvars
dictio_bool[k + 1] = model.NewBoolVar('')
model.Add(date[event1] > delay + date[event2]).OnlyEnforceIf(dictio_bool[k]) #date is a dictionary to stock intvars
model.Add(date[event1] < delay + date[event2]).OnlyEnforceIf(dictio_bool[k + 1])
model.AddBoolXOr([dictio_bool[k], dictio_bool[k + 1]])
However, when I use this, the code always decide to put the first bool at False and the second one at True. I have many others constraints that work. I might be a bit confused sorry, but do you know how to make the code choose the status of the bool depending on other constraints and not always 0 then 1.
To be more precise, How to set different values for some intvars with a minimum amount between them and no particular order ?
for abs, you need to write ( I use the CP-SAT 9.9 python API)
model.add_abs_equality(target_expr, expr)
when all expressions are of the form a * var + b (a, b integers). So x, x - 5, 3 * x are all valid.
Furthermore, to write a disjunction, just use a single Boolean variable.
model.add(x < y + delay).only_enforce_if(b)
model.add(y < x + delay).only_enforce_if(~b)
using bool_xor will force all literals to be alternating (true, false, true, false...) or (false, true, false, true, ...)
There is another model using scheduling.
x = [ my integer variables ]
intervals = [model.new_fixed_size_interval_var(local_x, delay, '') for local_x in x]
model.add_no_overlap(intervals)