0

I am trying to get all solutions for a Mixed Integer program through ortools. I have two lists x and y of size 4. I want to get all solutions which satisfy sum(x) = 4 * sum(y). I created a function which takes list of past solutions as input and returns next solution. I am able to get only 2 solutions even though there are more. What am I doing wrong here?

I am expecting the following solutions

Solution 1: xs1 = [0,0,0,0], ys1 = [0,0,0,0]

Solution 2: xs2 = [4,0,0,0], ys2 = [1,0,0,0]

Solution 3: xs3 = [0,4,0,0], ys3 = [1,0,0,0]

Solution 4: xs4 = [0,0,4,0], ys4 = [0,0,1,0]

and soon on

from ortools.linear_solver import pywraplp

def opt(xs, ys):
    solver = pywraplp.Solver.CreateSolver('SCIP')

    infinity = solver.infinity()
    # x and y are integer non-negative variables.

    n = 4
    M = 20

    x = [0]* n
    y = [0]* n

    w = [[0]* n]*len(xs)

    δ = [[0]* n]*len(xs)

    for i in range(0,n):
        x[i] = solver.IntVar(0, 20, 'x'+str(i))
        y[i] = solver.IntVar(0, 20, 'y'+str(i))

        for j in range(len(xs)):
            w[j][i] = solver.IntVar(0, 20, 'zp'+str(j)+ '-' + str(i))
            δ[j][i] = solver.IntVar(0, 1, 'δ'+str(j)+ '-' + str(i))

    for j in (range(len(xs))):
        for i in range(0,n):
            solver.Add((w[j][i] - x[i] + xs[j][i]) >=0) 
            solver.Add((w[j][i] - x[i] + xs[j][i]) <= M*(1-δ[j][i])) 
            
            solver.Add((w[j][i] + x[i] - xs[j][i]) >=0) 
            solver.Add((w[j][i] + x[i] - xs[j][i]) <= M*δ[j][i])

    for j in range(len(xs)):
        solver.Add(solver.Sum([w[j][i] for i in range(0,n)]) >= 1)
        
    solver.Add(solver.Sum([x[i] for i in range(0, n)]) - 4 * solver.Sum([y[i] for i in range(0, n)]) == 0)


    solver.Minimize(solver.Sum([x[i] for i in range(0, n)]))

    status = solver.Solve()

    if status == pywraplp.Solver.OPTIMAL:
        solver_x = [0]*n
        solver_y = [0]*n
        for i in range(0,n):
            solver_x[i] = x[i].solution_value()
            solver_y[i] = y[i].solution_value() 
        return ([solver_x, solver_y, solver.Objective().Value()])
    else:
        print('No Solution')
        return ([[0], [0]], -1) 



psx = [[0,0,0,0], [0,4,0,0]]
psy = [[0,0,0,0], [1,0,0,0]]

ns = opt(psx, psy)
print(ns)

Output:

No Solution
([[0], [0]], -1)

Reference:

  1. Finding multiple solutions to general integer linear programs
  2. How to write constraints for sum of absolutes
Vinay
  • 1,149
  • 3
  • 16
  • 28

1 Answers1

0

If you have a pure integer programming model, you can use the CP-SAT solver which allows you to print all the solutions [See this].

Alphanerd
  • 11
  • 1
  • 3