1

Dears,

I´m experimenting on CVXPY and have generated a simple Integer Program. For the sake of comparisson I´ve also generated a linear relaxation of it. But, when solving, I get a value for the relaxed problem (1.429). For the integer problem, however, I get -inf. What am I missing?

Thank you!

Follows the code:

import cvxpy as cp
import numpy as np

def make_problem(m, n, integer, name = 'Not named', solve = True, seed = 0):
    np.random.seed(seed)

    # Generating problem parameters
    A = np.random.randn(m, n)
    b = np.dot(A, np.ones(n))/2
    c = -np.random.randn(n)

    # Generation problem variables
    x = cp.Variable(n, integer = integer)

    # Generating problem objective
    obj = cp.Minimize(c.T @ x)

    # Generating problem constraints
    cstr = [
        A @ x <= b,
        x >= 0,
        x <= 1,
    ]

    # Generating problem
    prob = cp.Problem(obj, cstr)

    if solve:
        prob.solve()
        print(f'PROBLEM {name}: STATUS: {prob.status} | VALUE: {prob.value}')    
        return x

    else:
        return prob

m = 300
n = 100

x_rlx = make_problem(m, n, integer = False, name = 'Relaxed')
x = make_problem(m, n, integer = True, name = 'Integer')

Output:

PROBLEM Relaxed: STATUS: optimal | VALUE: 1.4295841445033348

PROBLEM Integer: STATUS: unbounded | VALUE: -inf

Bruno
  • 87
  • 5

1 Answers1

2

It's common, that the relaxation is feasible, while the original problem is not. Imagine the simple problem:

min(x)

x == 0.5

This is feasible with optimum 0.5 for x = 0.5, while infeasible when we enforce x to be binary.

Chances are high, that you are observing the same (as indicated in comments: we don't know your problem exactly).

Important: Query the Solver-Status!

For:

np.random.seed(0)
m = 20
n = 10
...
print(prob_rlx.status)
print(prob_rlx.value)
...
print(prob.status)
print(prob.value)

i observe:

optimal
0.0822089776045708

infeasible
inf

This means: The solver proved infeasibility for the non-relaxed problem and uses a default-value of infinity for this case!

This is ambigious -> the relaxation might also be unbounded; therefore: read the status!

See for example slides: page 13/14

sascha
  • 32,238
  • 6
  • 68
  • 110
  • 1
    For the `b = np.dot(A, np.ones(n))/5` it was really **infeasibile**, but for `b = np.dot(A, np.ones(n))/2` it raises **unbounded**. I´ve editted the question for having the code updated for `b = np.dot(A, np.ones(n))/2`. – Bruno Feb 18 '21 at 22:16