Python cvxpy - reuse some constraints

676 views Asked by At

I'm currently using cvxpy to optimize a really big problem but now facing the current issue. I run multiple iterations of the solver (every iteration reduces the flexibility of some variables). Every run has 50 constraints in total, of which only 2 of them are different on every run. The remaining 48 constraints are identical. During every iteration I rebuild from scratch those 2 constraints, the problem, and the obj function. If I don't rebuild the remaining (same) 48 constraints, the final solution makes no sense.

I read this post CVXPY: how to efficiently solve a series of similar problems but here in my case, I don't need to change parameters and re-optimize.

I just managed to prepare an example that shows this issue:

    x = cvx.Variable(3)
    y = cvx.Variable(3)

    tc = np.array([1.0, 1.0,1.0])
    constraints2 = [x >= 2]
    constraints3 = [x <= 4]
    constraints4 = [y >= 0]
    
    for i in range(2):
        if i == 0:
            constraints1 = [x - y >= 0]
            
        else:
            x = cvx.Variable(3)
            y = cvx.Variable(3)
            constraints1 = [x + y == 1,
                           x - y >= 1,
                           x - y >= 0,
                           x >= 0]
    
        
        
        constraints = constraints1 + constraints2 + constraints3 + constraints4
        # Form objective.
        obj = cvx.Minimize( (tc.T @ x ) - (tc.T @ y ) )
        
        # Form and solve problem.
        prob = cvx.Problem(obj, constraints)
        prob.solve()
        

        solution_value = prob.value
        solution = str(prob.status).lower() 
        print("\n\n** SOLUTION:  {}     Value: {} ".format(solution, solution_value))
        print("* optimal (x + y == 1) dual variable", constraints[0].dual_value)
        print("optimal (x - y >= 1) dual variable", constraints[1].dual_value)
        print("x - y value:", (x - y).value)
        print("x = {}".format(x.value))
        print("y = {}".format(y.value))

As you can see, constraints2 requires all the values in the x vector to be greater than 2. constraints2 is added in both iterations to "constraints" that is used in the solver. The second solution should give you values of vector x that are less than 2. Why? How to avoid this issue? Thank you

1

There are 1 answers

3
steven On BEST ANSWER

You need to use parameters as described in the linked post. Suppose you have the constraint rhs >= lhs which is sometimes used and other times not, where rhs and lhs have dimensions m x n. Write the following code:

param = cp.Parameter((m, n))
slack = cp.Variable((m, n))
param_constraint = [rhs >= lhs + cp.multiply(param, slack)]

Now to turn off the constraint, set param.values = np.ones((m, n)). To turn the constraint on, set param.values = np.zeros((m, n)). You can turn some entries of the constraint off/on by setting some entries of param to be 1 and others to be 0.