Python接口
安装说明
目前,杉数求解器的Python接口支持Python 2.7, 3.6-3.12版本。 其中,对于Python 3.8-3.12版本,COPT的MacOS-Universal可提供支持;对于Python 2.7, 3.6-3.7版本,则只有MacOS-X86。
使用Python接口前,请用户确保已正确安装和配置杉数求解器,详情可参考 如何安装杉数求解器 。
用户可以从 Anaconda发行版 或者
Python官方发行版 下载并安装Python。我们推荐用户
安装Anaconda发行版,因为它对Python新手使用更加友好与方便(对于Windows系统,请勿使用
通过Microsoft Store安装的Python)。若使用官方发行版本或系统自带版本,则应确保已安装
pip
和 setuptools
Python工具包。
注意
我们推荐使用3.8-3.12版本,因为COPT-Python接口的矩阵建模功能最低版本要求是3.8。2.7, 3.6-3.7版本除非必要,不推荐首选。
Windows
方式一:通过pip install的方式(推荐)
打开cmd命令行窗口(若Python是Anaconda发行版,则打开Anaconda命令行窗口),输入如下命令:
pip install coptpy
若已安装了旧版本的 coptpy
包,请在cmd命令行窗口(若Python是Anaconda发行版,则打开Anaconda命令行窗口),
输入如下命令,以升级到最新版本的 coptpy
包:
pip install --upgrade coptpy
方式二:通过COPT安装包
对于Windows系统,假定杉数求解器安装路径为:C:\Program Files\copt71,则切换目录到 C:\Program Files\copt71\lib\python ,并在命令行窗口上执行如下命令:
python setup.py install
注意: 若杉数求解器安装在系统盘(一般为C盘),则需要 以管理员权限执行 打开命令行窗口。 为测试Python接口是否正确安装,用户可切换目录至 C:\Program Files\copt71\examples\python , 并在命令行窗口上执行如下命令:
python lp_ex1.py
若模型正确执行,则表示已正确安装杉数求解器的Python接口。
注意: 若使用Python官方发布的Python 3.8版本,假定安装路径为:"C:\Program Files\Python38"
,
则需要将杉数求解器安装路径的 "bin"
子目录下的 copt_cpp.dll
文件复制到杉数求解器的
Python接口安装路径:"C:\Program Files\Python38\Lib\site-packages\coptpy"
以解决动态库依赖问题。
目前, coptpy
支持type hints, coptpy
安装成功后,在Python IDE中编写代码时,
会自动提示变量名补全及函数原型信息。
Linux
方式一:通过pip install的方式(推荐)
打开终端,输入如下命令,安装COPT Python接口
pip install coptpy
若已安装了旧版本的 coptpy
包,请打开终端,输入如下命令,以升级到最新版本的 coptpy
:
pip install --upgrade coptpy
方式二:通过COPT安装包
对于Linux系统,假定杉数求解器安装路径为:/opt/copt71 ,则切换目录到 /opt/copt71/lib/python ,并在终端上执行:
sudo python setup.py install
对于使用Anaconda发行版的用户,若执行上述命令失败,则需要使用Anaconda发行版Python可执行文件
的完整路径执行安装命令。假定Anaconda安装路径为:"/opt/anaconda3"
,则在终端上执行下述
命令安装杉数求解器的Python接口:
sudo /opt/anaconda3/bin/python setup.py install
为测试Python接口是否正确安装,用户可切换目录至 /opt/copt71/examples/python , 并在命令行窗口上执行如下命令:
python lp_ex1.py
若模型正确执行,则表示已正确安装杉数求解器的Python接口。
目前, coptpy
支持type hints, coptpy
安装成功后,在Python IDE中编写代码时,
会自动提示变量名补全及函数原型信息。
MacOS
方式一:通过pip install的方式(推荐)
打开终端terminal,输入如下命令,安装COPT Python接口:
pip install coptpy
若已安装了旧版本的 coptpy
包,请打开终端,输入如下命令,以升级到最新版本的 coptpy
:
pip install --upgrade coptpy
方式二:通过COPT安装包
对于MacOS系统,假定杉数求解器的安装路径为:/Applications/copt71 ,则切换目录到 /Applications/copt71/lib/python ,并在终端上执行:
sudo python setup.py install
为测试Python接口是否正确安装,用户可切换目录至 /Applications/copt71/examples/python , 并在终端执行如下命令:
python lp_ex1.py
若模型正确执行,则表示已正确安装杉数求解器的Python接口。
目前, coptpy
支持type hints, coptpy
安装成功后,在Python IDE中编写代码时,
会自动提示变量名补全及函数原型信息。
示例解析
本章通过一个简单的示例演示如何使用杉数求解器的Python接口,待求解的问题数学形式如 公式 5 所示:
使用杉数求解器的Python接口求解与分析上述问题的代码见 代码 6 :
1#
2# This file is part of the Cardinal Optimizer, all rights reserved.
3#
4
5"""
6The problem to solve:
7
8 Maximize:
9 1.2 x + 1.8 y + 2.1 z
10
11 Subject to:
12 1.5 x + 1.2 y + 1.8 z <= 2.6
13 0.8 x + 0.6 y + 0.9 z >= 1.2
14
15 where:
16 0.1 <= x <= 0.6
17 0.2 <= y <= 1.5
18 0.3 <= z <= 2.8
19"""
20
21import coptpy as cp
22from coptpy import COPT
23
24# Create COPT environment
25env = cp.Envr()
26
27# Create COPT model
28model = env.createModel("lp_ex1")
29
30# Add variables: x, y, z
31x = model.addVar(lb=0.1, ub=0.6, name="x")
32y = model.addVar(lb=0.2, ub=1.5, name="y")
33z = model.addVar(lb=0.3, ub=2.8, name="z")
34
35# Add constraints
36model.addConstr(1.5*x + 1.2*y + 1.8*z <= 2.6)
37model.addConstr(0.8*x + 0.6*y + 0.9*z >= 1.2)
38
39# Set objective function
40model.setObjective(1.2*x + 1.8*y + 2.1*z, sense=COPT.MAXIMIZE)
41
42# Set parameter
43model.setParam(COPT.Param.TimeLimit, 10.0)
44
45# Solve the model
46model.solve()
47
48# Analyze solution
49if model.status == COPT.OPTIMAL:
50 print("Objective value: {}".format(model.objval))
51 allvars = model.getVars()
52
53 print("Variable solution:")
54 for var in allvars:
55 print(" x[{0}]: {1}".format(var.index, var.x))
56
57 print("Variable basis status:")
58 for var in allvars:
59 print(" x[{0}]: {1}".format(var.index, var.basis))
60
61 # Write model, solution and modified parameters to file
62 model.write("lp_ex1.mps")
63 model.write("lp_ex1.bas")
64 model.write("lp_ex1.sol")
65 model.write("lp_ex1.par")
接下来我们将基于上述代码分步骤讲解求解与分析过程,详细的Python接口使用说明请用户查阅 Python API参考手册 。
导入Python接口
使用杉数求解器的Python接口,需要首先导入Python接口库。
import coptpy as cp
from coptpy import COPT
创建环境
对于任意求解任务,杉数求解器要求首先创建求解环境。
# Create COPT environment
env = cp.Envr()
创建问题
创建求解环境成功后,用户需要创建模型,模型中将包括待求解的变量、约束等信息。
# Create COPT model
model = env.createModel("lp_ex1")
添加变量
创建变量时允许同时指定变量在目标函数中的系数、变量上下界等信息。 本示例中创建变量时仅指定上下界和名称信息,其它为默认值。
# Add variables: x, y, z
x = model.addVar(lb=0.1, ub=0.6, name="x")
y = model.addVar(lb=0.2, ub=1.5, name="y")
z = model.addVar(lb=0.3, ub=2.8, name="z")
添加约束
添加变量成功后,进一步添加作用于变量的约束条件。
# Add constraints
model.addConstr(1.5*x + 1.2*y + 1.8*z <= 2.6)
model.addConstr(0.8*x + 0.6*y + 0.9*z >= 1.2)
设置目标函数
添加完变量和约束后,进一步指定模型的目标函数。
# Set objective function
model.setObjective(1.2*x + 1.8*y + 2.1*z, sense=COPT.MAXIMIZE)
设置求解参数
用户可以在求解模型前设置求解参数,如设置求解时间限制为10秒。
# Set parameter
model.setParam(COPT.Param.TimeLimit, 10.0)
求解模型
调用下述方法求解模型。
# Solve the model
model.solve()
分析结果
求解完成后,首先获取模型求解状态,若状态为找到了最优解,则进一步获取目标函数值、各变量的取值及其 基状态信息。
# Analyze solution
if model.status == COPT.OPTIMAL:
print("Objective value: {}".format(model.objval))
allvars = model.getVars()
print("Variable solution:")
for var in allvars:
print(" x[{0}]: {1}".format(var.index, var.x))
print("Variable basis status:")
for var in allvars:
print(" x[{0}]: {1}".format(var.index, var.basis))
文件输出
用户可以将当前求解的模型保存为标准的MPS模型文件,以及输出变量结果文件、基状态信息文件和修改过的 参数文件。
# Write model, solution and modified parameters to file
model.write("lp_ex1.mps")
model.write("lp_ex1.bas")
model.write("lp_ex1.sol")
model.write("lp_ex1.par")
最佳实践
升级新版本
对于已经安装了COPT Python接口 coptpy
的用户,如果想升级到最新版本,建议先卸载旧版本的coptpy,然后再
安装新版本。旧版本的 coptpy
可以从Python的 site-package
的子目录 coptpy
中找到。
对于联网的条件下,我们推荐通过 pip
的方式进行 coptpy
的卸载或升级。
卸载旧版本
pip uninstall coptpy
安装新版本
pip install --upgrade coptpy
如果用户通过COPT离线安装包中 python setup.py install
形式安装 coptpy
,请参考如下步骤进行卸载升级:
1.首先,请确认 coptpy
的安装位置,可通过 pip show coptpy
查看,输出如下:
Name: coptpy
Version: 7.1.3
Summary: The Python interface of the Cardinal Optimizer
Home-page: www.shanshu.ai
Author: Cardinal Operations, LLC
Author-email: coptsales@shanshu.ai
License: Cardinal Operations, LLC
End User License Agreement
Location: /Users/user/anaconda3/lib/python3.11/site-packages
Requires:
Required-by:
2.手动删除安装以上 Location
目录 site-packages
下的 coptpy-*.egg-info
和 coptpy
目录。
3.安装新版本的 coptpy
,进入COPT的安装包目录(形如 copt71/lib/python
)中,执行:
python setup.py install
多线程编程
COPT的建模API并不保证可重入性,在多线程编程时如果共享模型对象可能造成数据错误。一般来说,
在多个线程下共享COPT环境类Envr是可以的。但是,注意不要共享模型类,除非用户明确知道自己的行为后果。
举例来说,如果在两个线程里共享同一个模型类,确保建模和求解只在其中一个线性进行;在另外一个线程里,
可以对求解过程监督,然后在合适的时候通过 interrupt()
中断任务执行,比如任务超时了。
Python的字典顺序
Python默认的字典是无序的,也就是说,遍历次序和数据加入的次序可能不同。例如,输入数据是
{'fruits': ['apple', 'orange'], 'veggies': ['carrot', 'pea']}
,但是输出的是
{'veggies': ['carrot', 'pea'], 'fruits': ['apple', 'orange']}
。
从Python 3.6开始,Python字典的内部实现变成有序了。特别是Python 3.7及以后,保持字典顺序成为其自带要求。
如果用户有保持字典次序的需求,请使用基于Python 3.7或更新版本的COPT Python接口 coptpy
例如,下面的程序如果是在Python 2.7里运行:
m = Envr().createModel("customized model")
vx = m.addVars(['hello', 'world'], [0, 1, 2], nameprefix = "X")
# add a constraint for each var in tupledict 'vx'
m.addConstrs(vx[key] >= 1.0 for key in vx)
那么,模型里的约束的次序可能是 {R(hello,1), R(hello,0), R(world,1), R(world,0), R(hello,2), R(world,2)}
。
尽可能使用quicksum和psdquicksum
COPT的Python接口支持直观地创建线性、二次和半定表达式。对于线性和二次表达式,建议使用 quicksum()
来创建表达式对象; 对于线性和半定表达式,建议使用 psdquicksum()
来创建表达式对象。他们都优化
了表达式项的求和,比直接使用加号运算符在性能上会好很多。
对模型进行批量操作
COPT的Python接口提供相关函数,支持用户方便地对模型进行批量操作,例如:
批量添加一组变量或约束:
Model.addVars()/Model.addConstrs()
;批量修改变量在模型中的系数
Model.setCoeffs()
( 注意: 待修改变量和约束的下标对不能重复出现);批量修改变量或约束的名称:
Model.setNames()
。
请参考 Python API参考手册:Model类 查看函数说明。