I am trying to solve a linear programming problem using IBM's CPLEX Python API. It involves two sets of equality constraints. The code below works fine when we use either one of the two sets of constraints, but fails to find a solution when both sets of constraints are used.
The constraints are:
First constraint: Wx' = c'
, where W = [[20,0,0],[0,20,30]]
, x = [a,b,c]
, c=[20,30]
Second constraint: Vx' = e'
, where V = [[1,1,0],[0,0,1]]
, x = [a,b,c]
, c=[1,1]
Objective function: minimize a + c
One solution which meets both sets of constrains is a=1
, b=0
, c=1
.
There is an error in the way I am introducing the two sets of constrains in Cplex Python. My code is below. To check that the code works with either set of constraints by itself comment out on of the sets of constraints.
import cplex
from cplex.exceptions import CplexError
import sys
def populatebynonzero(prob):
my_obj = [1.0, 0.0, 1.0]
my_ub = [1.0] * len(my_obj)
my_lb = [0.0] * len(my_obj)
my_colnames = ["a", "b", "c"]
prob.objective.set_sense(prob.objective.sense.minimize)
prob.variables.add(obj = my_obj, ub = my_ub, lb = my_lb ,names = my_colnames)
# first set of equality constraints: Wx' = c', where W = [[20,0,0],[0,20,30]], x = [a,b,c], c=[20,30]
my_rhs = [20.0, 30.0]
my_rownames = ["c1", "c2"]
my_sense = "E" * len(my_rownames)
rows = [0,1,1]
cols = [0,1,2]
vals = [20.0,20.0,30.0]
prob.linear_constraints.add(rhs = my_rhs, senses = my_sense,names = my_rownames)
prob.linear_constraints.set_coefficients(zip(rows, cols, vals))
# second set of equality constraints: Vx' = e', where V = [[1,1,0],[0,0,1]], x = [a,b,c], c=[1,1]
my_rhs = [1.0, 1.0]
my_rownames = ["e1", "e2"]
my_sense = "E" * len(my_rownames)
rows = [0,0,1]
cols = [0,1,2]
vals = [1.0,1.0,1.0]
prob.linear_constraints.add(rhs = my_rhs, senses = my_sense,names = my_rownames)
prob.linear_constraints.set_coefficients(zip(rows, cols, vals))
def lpex1():
try:
my_prob = cplex.Cplex()
handle = populatebynonzero(my_prob)
my_prob.solve()
except CplexError, exc:
print exc
return
numrows = my_prob.linear_constraints.get_num()
numcols = my_prob.variables.get_num()
print
# solution.get_status() returns an integer code
print "Solution status = " , my_prob.solution.get_status(), ":",
# the following line prints the corresponding string
print my_prob.solution.status[my_prob.solution.get_status()]
print "Solution value = ", my_prob.solution.get_objective_value()
slack = my_prob.solution.get_linear_slacks()
pi = my_prob.solution.get_dual_values()
x = my_prob.solution.get_values()
dj = my_prob.solution.get_reduced_costs()
for i in range(numrows):
print "Row %d: Slack = %10f Pi = %10f" % (i, slack[i], pi[i])
for j in range(numcols):
print "Column %d: Value = %10f Reduced cost = %10f" % (j, x[j], dj[j])
my_prob.write("lpex1.lp")
print x, "SOLUTIONS"
lpex1()