GAMS 文档: 很好的说明书
l = cplex.SparsePair(ind = ['x'], val = [1.0])
q = cplex.SparseTriple(ind1 = ['x'], ind2 = ['y'], val = [1.0])
c.quadratic_constraints.add(name = "my_quad",
lin_expr = l,
quad_expr = q,
rhs = 1.0,
sense = "G")
这里一定要注意:SparsePair 和 SparseTriple 的入参顺序不能调换,必须参数 ind 在前,系数值 val 在后。否则会报错:
TypeError: non-float value in input sequence
给定 N N N 个变量,set_linear 的作用就是设置每个变量的系数(相当于为一个数组赋值),从而构建出一个线性目标函数。set_linear 的入参是一个列表,列表中每个元素 ( i , V i ) (i, V_i) (i,Vi) 的含义就是设置第 i + 1 i+1 i+1 个变量的系数为 V i V_i Vi。get_linear() 的出参也是一个列表,它实际上是构建出的线性目标函数的系数向量。
# 实例化
cpx = cplex.Cplex()
cpx.set_results_stream(None)
cpx.set_log_stream(None)
cpx.parameters.preprocessing.reduce.set(0)
cpx.parameters.lpmethod.set(cpx.parameters.lpmethod.values.primal)
cpx.objective.set_sense(cpx.objective.sense.maximize)
# 添加变量
cpx.variables.add(obj=[0.0],lb=[0.0],ub=[cplex.infinity],names=['X1'])
cpx.variables.add(obj=[0.0],lb=[0.0],ub=[cplex.infinity],names=['X2'])
cpx.variables.add(obj=[0.0],lb=[0.0],ub=[cplex.infinity],names=['X3'])
cpx.variables.add(obj=[0.0],lb=[0.0],ub=[cplex.infinity],names=['X4'])
cpx.variables.add(obj=[0.0],lb=[0.0],ub=[cplex.infinity],names=['X5'])
# 设置线性变量
cpx.objective.set_linear([(0,21),(2,22)])
cpx.objective.set_linear([(1,23),(3,24),(4,25)])
cpx.objective.set_linear([(2,11)])
print(cpx.objective.get_linear())
运行结果如下:
[21.0, 23.0, 11.0, 24.0, 25.0]
备注:在 set_linear 之前必须添加变量,否则会报错
cplex.exceptions.errors.CplexSolverError: CPLEX Error 1201: Column index 0 out of range.
objective | set_linear | |||
linear_constraints | add | |||
solution | get_status() | |||
solution | get_values(*) | |||
solution | status | unbounded | ||
solution | advanced | get_ray() | ||
SparsePair | ||||
parameters | preprocessing | reduce.set(0) | ||
parameters | lpmethod | set(*) | ||
parameters | lpmethod | values | primal | 单纯形法 |
Python 用户的 CPLEX
python教程
模块 cplex 中的主类是类 Cplex。 它将优化问题的数学方程与用户所指定的有关 CPLEX 应如何对问题求解的信息封装在一起。 类 Cplex 提供了方法以修改问题、对问题求解以及查询问题本身及其解法。 类 Cplex 的方法分组为相关功能的类别。 例如,用于添加、修改和查询与变量相关的数据的方法包含在类 Cplex 的成员 variables 中。
可以在 CPLEX 的各组件中对标准方程中的此线性规划模型求解。
要求解的问题是:
最大化 x 1 + 2 x 2 + 3 x 3 x_1+2x_2+3x_3 x1+2x2+3x3 约束 − x 1 + x 2 + x 3 ≤ 20 -x_1+x_2+x_3\leq 20 −x1+x2+x3≤20 x 1 − 3 x 2 + x 3 ≤ 30 x_1-3x_2+x_3\leq 30 x1−3x2+x3≤30
使用这些界限 0 ≤ x 1 ≤ 40 ,    x 2 ≥ 0 ,    x 3 ≥ 0 0\leq x_1\leq 40, \; x_2\ge 0, \; x_3\ge 0 0≤x1≤40,x2≥0,x3≥0
以下是使用 CPLEX 对示例求解的 Python 应用程序:
execfile("cplexpypath.py")
import cplex
from cplex.exceptions import CplexError
import sys
# data common to all populateby functions
my_obj = [1.0, 2.0, 3.0]
my_ub = [40.0, cplex.infinity, cplex.infinity]
my_colnames = ["x1", "x2", "x3"]
my_rhs = [20.0, 30.0]
my_rownames = ["c1", "c2"]
my_sense = "LL"
def populatebyrow(prob):
prob.objective.set_sense(prob.objective.sense.maximize)
# since lower bounds are all 0.0 (the default), lb is omitted here
prob.variables.add(obj = my_obj, ub = my_ub, names = my_colnames)
# can query variables like the following bounds and names:
# lbs is a list of all the lower bounds
lbs = prob.variables.get_lower_bounds()
# ub1 is just the first lower bound
ub1 = prob.variables.get_upper_bounds(0)
# names is ["x1", "x3"]
names = prob.variables.get_names([0, 2])
rows = [[[0,"x2","x3"],[-1.0, 1.0,1.0]],
[["x1",1,2],[ 1.0,-3.0,1.0]]]
prob.linear_constraints.add(lin_expr = rows, senses = my_sense,
rhs = my_rhs, names = my_rownames)
# because there are two arguments, they are taken to specify a range
# thus, cols is the entire constraint matrix as a list of column vectors
cols = prob.variables.get_cols("x1", "x3")
def populatebycolumn(prob):
prob.objective.set_sense(prob.objective.sense.maximize)
prob.linear_constraints.add(rhs = my_rhs, senses = my_sense,
names = my_rownames)
c = [[[0,1],[-1.0, 1.0]],
[["c1",1],[ 1.0,-3.0]],
[[0,"c2"],[ 1.0, 1.0]]]
prob.variables.add(obj = my_obj, ub = my_ub, names = my_colnames,
columns = c)
def populatebynonzero(prob):
prob.objective.set_sense(prob.objective.sense.maximize)
prob.linear_constraints.add(rhs = my_rhs, senses = my_sense,
names = my_rownames)
prob.variables.add(obj = my_obj, ub = my_ub, names = my_colnames)
rows = [0,0,0,1,1,1]
cols = [0,1,2,0,1,2]
vals = [-1.0,1.0,1.0,1.0,-3.0,1.0]
prob.linear_constraints.set_coefficients(zip(rows, cols, vals))
# can also change one coefficient at a time
# prob.linear_constraints.set_coefficients(1,1,-3.0)
# or pass in a list of triples
# prob.linear_constraints.set_coefficients([(0,1,1.0), (1,1,-3.0)])
def lpex1(pop_method):
try:
my_prob = cplex.Cplex()
if pop_method == "r":
handle = populatebyrow(my_prob)
if pop_method == "c":
handle = populatebycolumn(my_prob)
if pop_method == "n":
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")
if __name__ == "__main__":
if len(sys.argv) != 2 or sys.argv[1] not in ["-r", "-c", "-n"]:
print "Usage: lpex1.py -X"
print " where X is one of the following options:"
print " r generate problem by row"
print " c generate problem by column"
print " n generate problem by nonzero"
print " Exiting..."
sys.exit(-1)
lpex1(sys.argv[1][1])
else:
prompt = """Enter the letter indicating how the problem data should be populated:
r : populate by rows
c : populate by columns
n : populate by nonzeros\n ? > """
r = 'r'
c = 'c'
n = 'n'
lpex1(input(prompt))