I use Google OR-Tools (CP-SAT solver) to solve a constraint problem.
I need to place people in categories, hence, I create the following model:
model = cp_model.CpModel()
matches = {}
for p in people:
for c in categories:
# matches[(p, c)] == True if p must be in c
matches[(p, c)] = model.NewBoolVar("%s-->%02d" % (p,c))
One of the constraints is that people of similar age must be in the same cluster. Thus, for all clusters I minimize the absolute difference of one's age with the mean age in a category. To do so, I wrote the following minimization constraint:
abs_diffs = []
for c in categories:
ages_in_category = [int(ages[p])*matches[(p, c)] for p in people]
for a in ages_in_category:
n = len(ages_in_category)
diff = model.NewIntVar(-50*n, 50*n, name="")
model.Add(diff == n*a - sum(ages_in_category))
abs_diff = model.NewIntVar(0, 100*n, name="")
model.AddAbsEquality(abs_diff, diff)
abs_diffs.append(abs_diff)
model.Minimize(sum(abs_diffs))
The only other constraint I have is that one people must be assigned exactly one category, it has been tested and working.
However after a solution is found by the sat solver, people in categories are set completely at random and not based on their age.
Why did I do wrong?
Why this minimization constraint isn't taken into account by the solver?
EDIT: I noticed that the total sum to minimize varies in the range [0, 1 000 000]. Isn't that a problem for the solver?