I'm trying to create a custom search in Docplex (python) in a CP model.
The model:
mdl = CpoModel()
a = mdl.integer_var(0, 2, name="a")
b = mdl.integer_var(0, 8, name="b")
c = mdl.integer_var(0, 8, name="c")
mdl.add(a < b)
mdl.add(c < b)
mdl.add(a < c)
mdl.add(b != 3)
mdl.add(mdl.minimize(a + b+c))
msol = mdl.solve(LogPeriod=1, LogVerbosity="Verbose")
msol.print_solution()
In C++ you can use `IlcGoal` to implement custom search steps.
However, from the documentation is not clear how to do the same in python.
So far, I tried to use Callbacks:
class MySolver(CpoCallback):
def invoke(self, solver, event, sres):
if len(sres.solution.var_solutions_list) > 0:
print("search step")
vars = pd.DataFrame(
{
"domain": [
np.sum(
[
inter[1] - inter[0] + 1
if isinstance(inter, tuple)
else 1
for inter in v.value
]
)
if isinstance(v.value, tuple)
else 0
for v in sres.solution.get_all_var_solutions()
],
"varName": [
v.expr.name for v in sres.solution.get_all_var_solutions()
],
}
)
if len(vars[(vars.domain == vars.domain.max()) & (vars.domain > 0)]) > 0:
vn = vars[
(vars.domain == vars.domain.max()) & (vars.domain > 0)
].varName.values[0]
vlue = sres.solution.var_solutions_dict[vn].value[0][0]
sres.solution.var_solutions_dict[vn] = vlue
print(f"setting to {vn} = {vlue}")
else:
print('Solution found')
mdl.add_solver_callback(MySolver())
However, in this way, it looks like the solver does not take into account the assignment made by the callback. In fact, the callback assigns a value only to
c (value
1) and then finds the optimal solution directly.
Is there any way to implement a custom search in
docplex.cp?
Thanks
------------------------------
Federico Caselli
------------------------------
#DecisionOptimization