Sunday, February 12, 2017

Mini Programming Tutorial for Python with Cplex

This code is from lpex1.py that you can find in ...\IBM\ILOG\CPLEX_Studio127\cplex\examples\src\python, minimized for demostrating purpose. 

Tutorial by IBM is here: https://www.ibm.com/support/knowledgecenter/en/SSSA5P_12.6.0/ilog.odms.cplex.help/CPLEX/GettingStarted/topics/tutorials/Python/eg_lpex1.html

1) Import statements

from __future__ import print_function
import sys
import cplex
from cplex.exceptions import CplexError

2) First, you initialize the problem information.
my_obj = [5.0, 4.0] (i)
my_ub = [cplex.infinity, 2.0] (ii) 
my_colnames = ["x1", "x2"] (iii)
my_rhs = [24, 6.0, 1.0] (iv)
my_rownames = ["c1", "c2", "c3"] (v)
my_sense = "LLL" (vi)
i. Objective constants
ii. Set the bound for each variables.
iii. Declare the variable names.
iv. RHS of constraints.
v. Constraint names
vi. For each contraint, specify the relationship with RHS. L/G/E for Less than, Greater than, etc (see source code for cplex.linear_constraints.add for more info)


2) Set up the problem as a function populatebyrow(prob) where prob will take an object of cplex.Cplex()
def populatebyrow(prob): 
i. Set type of problem.  For minimization, use prob.objective.sense.minimize. 
    prob.objective.set_sense(prob.objective.sense.maximize)
ii. Lower bound is 0.0 by default. Should be a line to set lower bounds if needed. For now, add the variables to the problem. 
    prob.variables.add(obj=my_obj, ub=my_ub, names=my_colnames)
 iii. Prepare lower bounds and upper bounds. In problem information initialization, for unbounded variables, we set cplex.infinity. However, here, for upper bound, since it applies to x2 only, we can also set ub1 to get_upper_bounds(1), retrieving upper bound for x2 only. 
    lbs = prob.variables.get_lower_bounds()
    ub1 = prob.variables.get_upper_bounds()
iv. Get the variable name.  
    names = prob.variables.get_names()
v. This part, set the rows as a pair of list of indices mapping to the values. I don't really get how the indices are determined but this should work for now.  
    rows = [[["x1", "x2"], [6.0, 4.0]],
            [["x1", "x2"], [1.0, 2.0]],
            [["x1", "x2"], [-1.0, 1.0]]
            ]
    prob.linear_constraints.add(lin_expr=rows, senses=my_sense,
                                rhs=my_rhs, names=my_rownames)
    cols = prob.variables.get_cols("x1", "x2")

3) Using the function:

my_prob = cplex.Cplex()
populatebyrow(my_prob)
my_prob.solve()
numrows = my_prob.linear_constraints.get_num()
numcols = my_prob.variables.get_num()
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(), ":", end=' ')
# 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")

No comments:

Post a Comment