1

I am new to integer optimization. I am trying to solve the following large (although not that large) binary linear optimization problem:

max_{x} x_1+x_2+...+x_n

subject to: A*x <= b ; x_i is binary for all i=1,...,n

As you can see,

. the control variable is a vector x of lengh, say, n=150; x_i is binary for all i=1,...,n

. I want to maximize the sum of the x_i's

. in the constraint, A is an nxn matrix and b is an nx1 vector. So I have n=150 linear inequality constraints.

I want to obtain a certain number of solutions, NS. Say, NS=100. (I know there is more than one solution, and there are potentially millions of them.)

I am using Google's OR-Tools for Python. I was able to write the problem and to obtain one solution. I have tried many different ways to obtain more solutions after that, but I just couldn't. For example:

  1. I tried using the SCIP solver, and then I used the value of the objective function at the optimum, call it V, to add another constraint, x_1+x_2+...+x_n >= V, on top of the original "Ax<=b," and then used the CP-SAT solver to find NS feasible vectors (I followed the instructions in this guide). There is no optimization in this second step, just a quest for feasibility. This didn't work: the solver produced N replicas of the same vector. Still, when asked for the number of solutions found, it misleadingly replies that solution_printer.solution_count() is equal to NS. Here's a snippet of the code that I used:
# Define the constraints (A and b are lists)
for j in range(n):
    constraint_expr = [int(A[j][l])*x[l] for l in range(n)]
    model.Add(sum(constraint_expr) <= int(b[j][0]))

V = 112
constraint_obj_val = [-x[l] for l in range(n)]
model.Add(sum(constraint_obj_val) <= -V)


# Call the solver:
solver = cp_model.CpSolver()
solution_printer = VarArraySolutionPrinterWithLimit(x, NS)
solver.parameters.enumerate_all_solutions = True
status = solver.Solve(model, solution_printer)
  1. I tried using the SCIP solver and then using solver.NextSolution(), but every time I was using this command, the algorithm would produce a vector that was less and less optimal every time: the first one corresponded to a value of, say, V=112 (the optimal one!); the second vector corresponded to a value of 111; the third one, to 108; fourth to sixth, to 103; etc.

My question is, unfortunately, a bit vague, but here it goes: what's the best way to obtain more than one solution to my optimization problem?

Please let me know if I'm not being clear enough or if you need more/other chunks of the code, etc. This is my first time posting a question here :)

Thanks in advance.

2 Answers2

1

Is your matrix A integral ? if not, you are not solving the same problem with scip and CP-SAT.

Furthermore, why use scip? You should solve both part with the same solver.

Furthermore, I believe the default solution pool implementation in scip will return all solutions found, in reverse order, thus in decreasing quality order.

Laurent Perron
  • 8,594
  • 1
  • 8
  • 22
  • Hi Laurent! First of all thanks so much for the amazing job you've done with OR-Tools. Re: your questions: 1. Yes, A is integral: all the entries are integers. 2. I used scip just because this was the method I found in the guides (here: https://developers.google.com/optimization/mip/mip_example). I'm not sure whay you mean by "you should solve both parts with the same solver." In the second alternative (my point 2 above), I always used the SCIP solver, I didn't use CP-SAT. 3. How do I ask SCIP to return all solutions found? And what do you mean by solution here? – Francisco Espinosa Nov 16 '22 at 18:02
0

In Gurobi, you can do something like this to get more than one optimal solution :

solver->SetSolverSpecificParametersAsString("PoolSearchMode=2"); // or-tools [Gurobi]

From Gurobi Reference [Section 20.1]:

By default, the Gurobi MIP solver will try to find one proven optimal solution to your model.

You can use the PoolSearchMode parameter to control the approach used to find solutions. In its default setting (0), the MIP search simply aims to find one optimal solution. Setting the parameter to 1 causes the MIP search to expend additional effort to find more solutions, but in a non-systematic way. You will get more solutions, but not necessarily the best solutions. Setting the parameter to 2 causes the MIP to do a systematic search for the n best solutions. For both non-default settings, the PoolSolutions parameter sets the target for the number of solutions to find.

Another way to find multiple optimal solutions could be to first solve the original problem to optimality and then add the objective function as a constraint with lower and upper bound as the optimal objective value.

watchdogs132
  • 185
  • 1
  • 1
  • 5