Python Or Tools minimize sum of square differences

1.4k views Asked by At

I'm new to googles ortools, and I'm trying to use cp_model fot this problem:

I have a matrix "agents" of size d x s (my decision variables), a transition matrix "shifts_coverage" size s x p and an objective matrix "objetive" of size d x p. I want to Minimize

enter image description here

where "*" denotes a matrix multiplication. So I wrote

model.Minimize(sum(np.power([np.dot(agents, shifts_coverage) - objetive]),2))

agents is a model.NewIntVar, and "shifts_coverage" and "objetive" are fixed input matrixes.

However I get an error where it says TypeError: unsupported operand type(s) for ** or pow(): '_SumArray' and 'int' if I remove the np.power the error is is not a valid objective. So I'm not sure how this objetive function should be defined in order to have the expected format from ortools. I've also seen something called model.AddAbsEquality, it seems its related, but I have not been able to successfuly implement it in this objetive function

Thanks!

EDIT: I've tried using intermediate variables as suggested, but as I want to minimize an square difference, I tried something like this

  • Express the square diff as a multiplication of absolute values, as my matrixes are positives enter image description here

  • For the term agents * shifts_coverage, I added another variable called shifted_agents as

shifted_agents [d][p] = sum([agents[d][s] * shifts_coverage[s][p] for s in range(num_shifts)])

Remember shifts_coverage[s][p] is just a bool and agents[d][s] is a model.NewIntVar (I think this may be the problem)

  • For absolute value used the trick of intermediate variables with
abs_difference[d][p] = model.NewIntVar(0, 100, f'abs_difference_d{d}p{p}')
model.AddAbsEquality(abs_difference[d][p], shifted_agents[d][p] - objetive[d][p])

The idea after this, is implement the AddMultiplicationEquality with the abs_difference, but as this far, I get this error:

TypeError('NotSupported: model.GetOrMakeIndex(' + str(arg) +
TypeError: NotSupported: model.GetOrMakeIndex((((agents_d0s2)) + -objetive_d0p0))

Note: I removed the for loops, but left the indixes to understand the matrix dimensions

1

There are 1 answers

10
Laurent Perron On

Plus AddMultiplicationEquality to create intermediate variables.

That is

model.Minimize(a**2 + b**2) 

This will not work directly, as the objective, as well as equations you add must be linear.

square_a = model.NewIntVar(0, max_a**2, 'square_a')
model.AddMultiplicationEquality(square_a, [a, a])
square_b = model.NewIntVar(0, max_b**2, 'square_b')
model.AddMultiplicationEquality(square_b, [b, b])
model.Minimize(square_a + square_b)

will do the trick.