杉数求解器

本文涉及的产品
应用型负载均衡 ALB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
简介: 杉数求解器

前言


杉数求解器是一款针对大规模优化问题的高效数学规划求解器。(主要是因为有详尽的文档!)


一、简介以及安装


简介:杉数求解器目前支持求解线性规划 (LP) 问题、二阶锥规划 (SOCP) 问题、凸二次规划(QP)问题、凸二次约束规划(QCP)问题、半定规划(SDP)问题、混合整数线性规划(MILP)、混合整数二阶锥规划(MISOCP)、混合整数凸二次规划 (MIQP)、混合整数凸二次约束规划(MIQCP)问题,并且支持各类主流语言、支持所有主流的操作系统。


下载安装:使用杉数求解器之前,用户需要下载并安装杉数求解器到计算机中。如果还未下载软件,请用户访问软件官方申请页面. 按照说明进行申请。(链接在文章结尾),申请通过后,会得到一份邮件。目前,杉树求解器提供了四种许可类型,以下以个人许可、在Windows上的安装为例,其他许可请查看官方说明文档。


邮件中会提供杉数求解器安装包的下载链接及授权通过的密钥信息,该密钥信息与用户申请信息一一对应。推荐直接下载第一个可执行程序,傻瓜式安装即可。


686cba2f779f46e9be5301cd7d08da51.png


  • 申请者需要根据本章内容安装杉数求解器并配置许可文件,以下以在Windows配置许可为例子,打开cmd终端,到杉树求解器的bin目录下,我的在D:\ShanShuQiujieqi\copt60\bin,使用命令获取到许可文件。


copt_licgen -key 这里填写密钥信息


  • 许可通过后,生成 license.dat 和 license.key 授权文档并下载到用户计算机,默认下载目录为当前工作目录。输入如下命令检验许可文件是否安装成功。
copt_licgen -v


  • 最后一步,将license.dat 和 license.key 授权文档复制,粘贴到copt60目录下。

二、COPT交互式命令行工具


简介:COPT 交互式命令行工具 copt_cmd 是一个由杉数求解器提供的,与 Windows、Linux 和 MacOS 下终端无缝连接的、可以直接调用杉数求解器编程接口进行模型求解与分析的工具。使用该工具前,请用户确保已正确安装杉数求解器,并成功配置授权文档。简单来说,COPT 交互式命令行工具是一个对从终端输入或脚本读入的命令行进行解释并执行的程序。它调用相应的杉数求解器编程接口进行求解与分析,并提供了以下启动参数:


  • -c: 该选项读取并执行指定的内联脚本内容。注意,内联脚本需要带双引号。
  • -i: 该选项读取并执行指定的脚本文件。(在外部可以使用copt_cmd -i diet.in来执行diet.in命令脚本。)
  • -o: 该选项提供了脚本录制功能。任何在“交互模式”下“执行正确”的命令都会输出到指定的脚本文件中,文件后缀无特殊要求。


2-1、普通工具命令

cd: 类似 DOS 命令 'cd' ,该命令改变 '当前工作目录' 。
dir/ls: 类似 DOS 命令 dir 和 Bash 命令 ls ,该命令列出给定的相对或绝对路径下的所有文件和文件夹。
exit/quit: 退出 COPT 命令行模式。
help: 提供 COPT 命令的使用说明。查阅单个命令的详细使用说明,
load: 读入给定路径下的脚本文件或者带引号的内联脚本,执行直到文件结尾或暂停字符 '?' 。暂停后,如果继续输入 load 命令,无论是否带参数(实际上任何参数都会被忽略),均继续执行被暂停的脚本。之前加载的脚本执行完成后,才可以加载其它脚本。
pwd: 类似 Bash 命令 'pwd' ,该命令显示当前工作目录,可以让用户查看目前在什么位置。

7e4e2542f2e44b7ea92327062464e885.png


2-2、COPT工具命令

display/get: 获取给定的参数或属性的当前值。特别地,对于不带参数名的调用,会列出目前所有支持的参数和属性名称,方便不熟悉 COPT 参数和属性名的用户查看其所需的信息,
opt/optimize: 求解已读入的模型,并将工具状态置为 'Optimize'。
read: 读取给定的相对或绝对路径下的模型文件、结果文件、基文件、初始解文件和参数设置文件。目前支持 '.mps' 、'.mps.gz' 、'.lp' 和 '.lp.gz' 、'.dat-s' 和 '.dat-s.gz' 、'.cbf' 和'.cbf.gz' 、'.bin' 和 '.bin.gz' 模型文件格式;以 '.sol' 为后缀的结果文件;以 '.bas' 为后缀的基解文件;以 '.mst' 为后缀的初始解文件;以 '.par' 为后缀的参数设置文件;以 '.tune'为后缀的调参文件。
readmps: 读取给定的相对或绝对路径下的模型文件。该命令不要求待读取的文件后缀为 '.mps' 或'.mps.gz' ,只要文件本身符合 MPS 格式即可。命令调用完成后将工具状态置为 'Read' 。
set: 设置给定的 COPT 参数的当前值。该命令的完整语法形如:'set TimeLimit 100' 。特别地,对于不带参数名的调用,将列出目前所有参数的名称和简介。


(后续补充)


三、使用示例


3-1、交互模式


  • Windows下终端窗口输入copt_cmd加载copt终端
  • 输入read diet.mps读取待求解模型。
  • 输入set timelimit 10设置COPT的求解参数。
  • 输入opt工具命令来求解当前优化模型。
  • 使用get命令获取到相关参数
  • 输入writesol diet把求解结果输出到指定文件
  • 输出quit退出交互界面


c0b08190bd0949248994c27dcc8b0831.png


3-2、Windows下终端窗口直接加载

直接在终端窗口使用copt_cmd -i diet.in来加载脚本。(diet.in脚本包含了上述命令)

8756f4fa140548aa9b2b237730f33166.png

四、Python接口

4-1、安装

pip install coptpy


4-2、案例分析

案例如下


a1026ce92a7a44fcb3d9f0e3bd023c6e.png

源码

# This file is part of the Cardinal Optimizer, all rights reserved.
# 导入python接口库
from coptpy import *
# Create COPT environment
# 创建环境
env = Envr()
# Create COPT model
# 创建问题
model = env.createModel("lp_ex1")
# Add variables: x, y, z
# 添加变量,创建变量时允许同时指定变量在目标函数中的系数、变量上下界等信息。本示例中创建变量时仅指定上下界和名称信息。其他为默认值。
# lb——下限
# ub——上限
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
# 设置目标函数
# sense 目标函数模式,COPT.MAXIMIZE这里代指最大化。
model.setObjective(1.2*x + 1.8*y + 2.1*z, sense=COPT.MAXIMIZE)
# Set paramete
# 设置求解参数
# COPT.Param.TimeLimit: 时间限制,这里设置为10秒
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")


输出


8f4646463f874f82b2c72b37e4ecd08f.png


五、COPT调优工具


5-1、介绍


对于支持的优化问题类型,杉数求解器 COPT 调优工具可以进行求解性能的自动调优。


5-2、调优工具相关参数


TuneTimeLimit: 参数调优的时间限制
TuneTargetTime:参数调优的时间目标
TuneMethod: 参数调优的方法
TuneMode: 参数调优的模式
TuneMeasure: 参数调优的计算方式

六、Python API参考

6-1、COPT一般常数

简介:一般常数定义了建模常用的常数,包括优化方向、变量类型和求解状态等。用户通过 COPT 前缀访问一般常数。,如 COPT.VERSION_MAJOR 表示软件大版本号信息。

MAXIMIZE: 最大化目标函数
MINIMIZE:最小化目标函数
INFINITY:代表无边界的量的默认值 (1e30),即代表的是最大常数
# 变量类型
CONTINUOUS: 连续变量
BINARY:二进制变量
INTEGER:整数变量


6-2、属性类常数

6-2-1、优化模型相关属性

# 在 Python API 中,用户可以通过 COPT.Attr 前缀访问属性常数,如 COPT.Attr.Cols 表示模型中变量个数。
Cols: 属性个数
Rows:约束的个数
Elems:系数矩阵中非0元素的个数
ObjSense:优化方向
ObjConst:目标函数中的常数部分
# 求解结果相关属性
LpStatus: 线性规划求解状态
MipStatus:整数规划求解状态
TuneResults:参数调优结果的数目
LpObjval:线性规划目标函数值
BestObj:整数规划求解结束时最好的目标函数值。
SolvingTime:求解所使用的时间。

6-2-2、Model类相关属性


# 在 Python API 中,通过指定属性名称获取属性取值,具体请参考Python Model类。
# 
Model.objval: 模型的目标函数值
Model.status: 模型的求解状态
Model.getAttr() 如:Model.getAttr("Cols") 获取模型中变量个数;
Model.addVar(): 添加一个变量到模型中,并返回创建的一个Var类对象。
参数:
lb: 变量下界
ub:变量的上界
obj:变量的目标函数系数
vtype:变量类型,CONTINUOUS:连续变量,BINARY:二进制变量,INTEGER:整数变量。
name:变量的名字
Model.addVars(): 添加一组变量到模型中
Model.addConstr(): 添加一个线性约束、半定约束或 Indicator 约束到模型中
参数:
lhs: 线性约束的左端项或约束构建器
sense: 线性约束的类型,可选参量,默认为None。常见类型有LESS_EQUAL——小于等于,GREATER_EQUAL——大于等于,EQUAL——等于, RANGE——同时有上下边界的。
rhs:线性约束的右端项,可选参量,默认为None。可取值为常数、Var类对象或者LinExpr类对象。
Model.addBoundConstr(): 添加一个带上下界的线性约束到模型中。
参数:
expr: 线性约束的表达式,可取值为Var类对象或者LinExpr类对象
lb:线性约束的下界,可选参量
ub:线性约束的上界。
name:线性约束的名称。
Model.setObjective(): 设置模型的目标函数
expr:目标函数的表达式
sense:目标函数的优化方向。两种优化方向MAXIMIZE、MINIMIZE,最大化、最小化目标函数。
Model.setObjSense(): 设置目标函数的优化方向。
Model.getObjective(): 获取模型的目标函数。
Model.getCol():获取指定变量对应的列,返回Column类对象。
Model.getRow(): 获取指定线性约束对应的行。
Model.getVar(): 根据变量在模型中的下标获取相应的变量,返回一个Var类对象。
参数:
idx:变量在系数矩阵中的下标,起始为0。
Model.getVarByName(): 根据变量的名称获取相应的变量,返回一个Var类对象。
Model.getVars(): 获取模型中的全部变量。 
Model.getCoeff(): 获取变量在线性约束中的系数。
参数:
constr:指定的线性约束
var:指定的变量。
Model.setCoeff(): 设置变量在线性约束中的系数
参数:
constr:指定的线性约束
var:指定的变量
newval: 待设置的新系数。
Model.read(): 根据文件名后缀判断文件类型并读入到模型中。
Model.readMps(): 按照MPS文件格式读取指定的文件到模型中去。
Model.write(): 根据文件后缀判断文件类型并写出到磁盘。
Model.solve(): 求解优化模型。
Model.tune(): 对模型进行参数调优
Model.remove(): 从模型中移除变量或者约束。
Model.clear(): 清空模型中的内容。

6-3、信息类常数

# 包括模型信息和求解结果相关信息
# 在 Python API 中,用户可以通过 COPT.Info 前缀访问信息常数,如 COPT.Info.Obj 表示变量在目标函数中系数。
# 获取变量或约束信息取值:Model.getInfo() / Var.getInfo() / Constraint.getInfo()
# 设置变量或约束信息取值:Model.setInfo() / Var.setInfo() / Constraint.setInfo()
obj: 变量的目标函数系数
lb:变量或者约束的下界
ub:变量或者约束的上界
value:变量的取值
....loading


6-4、参数

# 参数类常数表示杉数求解器的优化参数,优化参数控制 COPT 求解器优化算法的行为。
# 在 Python API 中,用户可通过 COPT.Param 前缀访问参数常数,如 COPT.Param.TimeLimit 表示模型的求解时间限制。
TimeLimit: 优化求解的时间限制
NodeLimit: 整数规划求解的节点数限制


6-5、优化建模类功能

Envr.createModel(): 创建优化模型,返回一个Model类对象
参数: name——待创建优化模型的名称。
Model.solve(): 求解优化模型
Var.x: 访问变量的取值
Var.vtype: 访问变量类型
Var.name: 访问变量的名称
Var.getType(): 获取变量的类型
Var.getName():获取变量的名字
Var.getIdx(): 获取变量在系数矩阵中的下标。
Var.setType(): 设置变量的类型。
Var.setName(): 设置变量的名称。
Var.getInfo(): 获取变量指定的信息值,返回一个常数。
Var.setInfo(): 给变量设置新的信息值。
Constraint.name:访问约束的名称。
Constraint.getName():获取线性约束的名称。
Constraint.setName():设置线性约束的名称。
Constraint.setInfo():根据新的信息值指定线性约束。
Column(): 创建一个Colimn类对象
参数:
constrs:线性约束
coeffs:变量在线性约束中的系数 
LinExpr(arg1=0.0, arg2=None):用于构建线性表达式时变量的相关组合操作。
LinExpr.setCoeff(): 根据变量在表达式中的下标设置其系数
参数:
idx:变量在表达式中的下标,起始为0.
newval:变量的新系数。
LinExpr.getCoeff():根据变量在表达式中的下标获取其系数
参数:
idx:变量在表达式中的下标,起始为0。


参考文章:

杉树求解器官网——https://www.shanshu.ai/copt.


总结


过年后要上一周班,好累!


相关文章
|
7月前
|
机器学习/深度学习 并行计算 算法
粒子群优化算法详细讲解(附完整代码实现一元二次方程求解)
粒子群优化算法详细讲解(附完整代码实现一元二次方程求解)
|
算法
秒懂算法 | 递推方程求解方法
时间复杂度和空间复杂度表示为递推方程的两种求解方法。
333 1
秒懂算法 | 递推方程求解方法
Cplex求解QCP非线性规划
Cplex求解QCP非线性规划
140 0
|
人工智能 移动开发 算法
初等变换法求解线性方程组
初等变换法求解线性方程组
|
人工智能 开发者
最小二乘法推导与求解 | 学习笔记
快速学习最小二乘法推导与求解
最小二乘法推导与求解 | 学习笔记
雅克比迭代法求解线性方程组
雅克比迭代法求解线性方程组
122 0
|
算法
F#实现Runge–Kutta算法求解常微分方程
不少工程问题中涉及的微分方程,我们很难求出方程的解析解,或者说根本不存在精确的解析解。此时,我们需要利用电脑,结合数值分析的方法来近似求出微分方程的相关解,并研究其性质。通过求出多个自变量的值,并求出对应的解,那么可以绘制出图形来辅助研究方程的特征。本文将介绍F#实现Runge–Kutta算法求解微分方程。
853 0
F#实现Runge–Kutta算法求解常微分方程