CPLEX Python入门--从简单的CplexPythonAPI详解到简单的DoCplex建模

好久不写博客了,大部分时间都用来干一些重复而繁杂的工作,好久没有认认真真学习一些东西了。
借着参加服创的机会要入手学习一些运筹学知识,就从Cplex开始吧。

首先直接用Python的cplex接口写线性规划比较简单,话不多说直接从实例看:
每一句的详解都在旁边的注释上

Cplex实例

# The MIP problem solved in this example is:
#
#   Maximize  x1 + 2 x2 + 3 x3 + x4
#   Subject to
#      - x1 +   x2 + x3 + 10 x4 <= 20
#        x1 - 3 x2 + x3         <= 30
#               x2      - 3.5x4  = 0
#   Bounds
#        0 <= x1 <= 40
#        0 <= x2
#        0 <= x3
#        2 <= x4 <= 3
#   Integers
#       x4

import cplex
from cplex.exceptions import CplexError

# 首先实现定义各参数,包括变量和变量约束等
# 用来在之后方便地添加到优化器里面

# obj 指的是objective 意为目标,
# 也就是要优化的目标(函数x1 + 2 x2 + 3 x3 + x4 的最小值)的系数
my_obj = [1.0, 2.0, 3.0, 1.0]

#ub Upper Bound,上界,分别表示x1,x2,x3,x4的上界,infinity就是无穷大
#(计算机类无穷大是有穷的,所以这个数可以事先修改为一个很大的数如 cplex.infinity = 2147483647
my_ub = [40.0, cplex.infinity, cplex.infinity, 3.0]

#lb Lower Bound,下界,同上理
my_lb = [0.0, 0.0, 0.0, 2.0]

#变量类型,详见https://www.ibm.com/support/knowledgecenter/SSSA5P_12.9.0/ilog.odms.cplex.help/refpythoncplex/html/cplex._internal._subinterfaces.VarTypes-class.html
#ctrlF搜索Class Variables即可
#分别表示4各变量的变量类型,C表示Continuous 连续值(浮点数),I表示Integer
my_ctype = "CCCI"

#给4个变量起个名字
my_colnames = ["x1", "x2", "x3", "x4"]

#约束规则
#rows是约束集的左值,数组类型
#每一个元素为一条约束规则,也为一个数组类型,包含2个元素,前者为约束变量的名称列表,后者为系数关系
my_rows = [[["x1", "x2", "x3", "x4"], [-1.0, 1.0, 1.0, 10.0]],
            [["x1", "x2", "x3"], [1.0, -3.0, 1.0]],
            [["x2", "x4"], [1.0, -3.5]]]

#rhs是约束规则集的右值
my_rhs = [20.0, 30.0, 0.0]

#约束规则集的左右值关系,详见https://www.ibm.com/support/knowledgecenter/SSSA5P_12.9.0/ilog.odms.cplex.help/refcallablelibrary/cpxapi/getsense.html
#L表示小于等于,E表示等于
my_sense = "LLE"

#给各条约束规则起名字
my_rownames = ["r1", "r2", "r3"]

try:
    #实例化一个cplex优化器
    prob = cplex.Cplex()

    #求解的目标为目标函数的最小值
    prob.objective.set_sense(prob.objective.sense.maximize)

    #添加变量:变量在目标函数里的系数,变量的上下界,变量类型,名称
    prob.variables.add(obj=my_obj, lb=my_lb, ub=my_ub, types=my_ctype,
                       names=my_colnames)

    #添加约束:约束左值,等式/不等式符号,右值,名称
    prob.linear_constraints.add(lin_expr=my_rows, senses=my_sense,
                                rhs=my_rhs, names=my_rownames)

    #求解
    prob.solve()

    #显示最优情况下的变量值
    x = prob.solution.get_values()
    print(x)

    #显示最优情况下的目标值
    objective_value = prob.solution.get_objective_value()
    print(objective_value)

    
except CplexError as exc:
    print(exc)

运行可以看到如下结果
在这里插入图片描述

Docplex实例

在学习了以上内容后我想自己建模解一些比较复杂的优化问题,
发现CplexPythonAPI中提供的接口还是很不人性化的,

prob.indicator_constraints.add() #添加当且仅当约束
prob.linear_constraints.add()    #添加线性约束
prob.pwl_constraints.add()       #添加分段约束
prob.quadratic_constraints.add() #添加平方约束

想要实现这样的约束还是蛮复杂的
在这里插入图片描述

而在网上搜刮了一番资料也没找到相关的cplex实例,反而是Docplex库对cplex的Python实现的Api还比较清晰明了
因此果断转用Docplex:

使用docplex实现的案例:
优化的是一个简单的拓扑工序:
其中X表示要优化出来的各个工区起始时间,Y为常数,各工序时长
并且有一个特殊限制,X2和X5不可以同时进行
在这里插入图片描述

mdl = Model(name='schedule')
#告诉cplex开辟这些自变量空间
x1 = mdl.integer_var(name='x1')
x2 = mdl.integer_var(name='x2')
x3 = mdl.integer_var(name='x3')
x4 = mdl.integer_var(name='x4')
x5 = mdl.integer_var(name='x5')
x6 = mdl.integer_var(name='x6')

#一些常数
y=[0,100,50,500,50,400,100]

#添加约束,约束表达式与名称
mdl.add_constraint(x1 + y[1] <= x2, 'c1')
mdl.add_constraint(x2 + y[2] <= x3, 'c2')
mdl.add_constraint(x4 + y[4] <= x5, 'c3')
mdl.add_constraint(x5 + y[5] <= x6, 'c4')

#一种特殊的约束,if_then(表达式1, 表达式2) 
#如果满足表达式1,那么就需要满足表达式2的约束
mdl.add(mdl.if_then(x5 >= x2, x5 - x2 >= y[2]))
mdl.add(mdl.if_then(x2 >= x5, x5 - x2 >= -y[5]))


mdl.minimize(x6 + y[6])


mdl.solve()

for v in mdl.iter_integer_vars():
   print(v," = ",v.solution_value)

print(mdl.solution.get_objective_value())

完成
在这里插入图片描述

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值