这篇案例将介绍使用 MindOpt 来求解一般性的非线性规划(Non-Linear Programming,NLP)问题。
我们使用 MindOpt 团队自研的代数建模语言软件 MindOpt APL (MAPL)来实现一般性非线性问题的建模,并与 MindOpt 求解器间进行求解交互。
非线性规划建模
一般性的非线性规划(Non-linear Programming,NLP)问题可以用以下数学形式表示:
其中
是决策变量, 和 分别为 的下界和上界, 是目标函数, 是第 条约束, 是第 条约束的上界。
非线性规划问题中的目标函数
MindOpt APL 与 MindOpt 目前支持由以下算术操作符或数学函数所复合而成的非线性问题的建模与求解。
支持的数学操作符
数学形式 | 解释 | MAPL中的表示 |
加减法运算符/正负号 |
| |
乘除法运算符 |
| |
幂次运算符(a是常量) |
| |
求和运算符 |
|
支持的非线性数学函数
数学形式 | 解释 | MAPL中的表示 |
正弦函数 |
| |
余弦函数 |
| |
正切函数 |
| |
反正弦函数 |
| |
反余弦函数 |
| |
反正切函数 |
| |
双曲正弦函数 |
| |
双曲余弦函数 |
| |
双曲正切函数 |
| |
反双曲正弦函数 |
| |
反双曲余弦函数 |
| |
反双曲正切函数 |
| |
指数函数 |
| |
e为底的对数函数 |
| |
10为底的对数函数 |
| |
2为底的对数函数 |
| |
开平方函数 |
| |
绝对值函数 |
|
使用 MindOpt APL 及 MindOpt 的步骤为:
利用 MindOpt APL 创建优化模型;
输入优化模型到 MindOpt 中,并设置算法参数;
MindOpt 求解优化问题并获取解。
非线性规划问题示例
在下文中,我们将考虑下面的非线性约束规划问题,这是一个简单的带正则化约束的逻辑回归:
我们将展示两种方式调用 MindOpt 求解这个优化问题,分别基于 MindOpt APL 及其Python扩展包 MaplPy 来实现。
基于MAPL的问题建模及优化
目前, MindOpt APL 支持云平台及本地版两种使用方式,可参考 MindOpt APL 的建模与优化章节的介绍。 MindOpt APL 的详细使用语法,可以参考 用户手册。
首先,创建 .mapl 文件,声明问题的待优化变量
var x;
var y;
var z;声明目标函数
minimize ln(1+exp(x+2*y+z)) + ln(1+exp(x-y-z)) + ln(1+exp(-3*x+y-z)) + ln(1+exp(3*x+z));声明约束
subto x^2 + y^2 <= 1;而后,运行求解指令,则会自动实现优化模型的构建及 MindOpt 的调用求解。
solve;MindOpt 求解过程的日志如下
MindOpt Version 2.1.0 (Build date: xxxxxxxx)
Start license validation (current time : xxxxxxxx xx:xx:xx).
License validation terminated. Time : 0.002s
wantsol=1
Model summary.
- Num. variables : 3
- Num. constraints : 1
- Num. nonzeros : 8
- Bound range : [1.00e+00,1.00e+00]
Interior point method started.
Iter PrimObj DualObj PrimFea DualFea GapFea Mu Time
0 +2.77258874e+00 +3.77258875e+00 0.0e+00 1.0e+00 1.0e+00 1.0e+00 0.00s
1 +2.10107174e+00 +2.23028984e+00 0.0e+00 7.8e-01 1.0e-01 1.0e-01 0.00s
2 +1.42075610e+00 +1.52543264e+00 6.7e-01 2.7e-01 1.8e-03 1.8e-03 0.00s
3 +1.65885758e+00 +1.72802441e+00 0.0e+00 1.2e-01 3.6e-02 3.6e-02 0.00s
4 +1.65511048e+00 +1.69576276e+00 0.0e+00 6.6e-02 2.1e-02 2.1e-02 0.00s
5 +1.65736811e+00 +1.66000850e+00 0.0e+00 2.6e-04 2.6e-03 2.6e-03 0.00s
6 +1.65490062e+00 +1.65506485e+00 0.0e+00 9.0e-06 1.6e-04 1.6e-04 0.00s
7 +1.65474536e+00 +1.65474726e+00 0.0e+00 3.6e-08 1.9e-06 1.9e-06 0.00s
8 +1.65474358e+00 +1.65474367e+00 0.0e+00 4.9e-12 9.1e-08 9.1e-08 0.00s
Terminated.
- Method : Interior point method.
- Primal objective : 1.6547435766246e+00
- Dual objective : 1.6547436675411e+00
- Num. threads : 1
- Num. iterations : 8
- Solver details : Solver terminated with a primal/dual optimal status.
Interior point method terminated. Time : 0.003883s
Optimizer summary.
- Optimizer used : Interior point method
- Optimizer status : OPTIMAL
Solution summary. Primal solution
- Objective : +1.6547435766e+00
OPTIMAL; objective 1.654744
Completed.成功求解后,MindOpt APL 会获取到问题的最优解 (optimal solution),我们可以将其打印出来进行查看:
print "x={}" % x;
print "y={}" % y;
print "z={}" % z;上述命令的输出为
x = -0.5728551903261085
y = -0.8196564705817261
z = 1.2728750741453017我们还可以根据得到的最优解,计算对应的最优目标函数值(此处保留三位小数)
param obj = ln(1+exp(x+2*y+z)) + ln(1+exp(x-y-z)) + ln(1+exp(-3*x+y-z)) + ln(1+exp(3*x+z));
print "obj={:.3f}" % obj;上述代码的输出如下
obj=1.655示例 MAPLLR.mapl提供了完整的 MindOpt APL 源代码:
# Example: 2D Regularized Logistic Regression Classifcation
#
# data points:
# - label=1: {(1,2), (3,0)}
# - label=-1: {(-1,1),(3,-1)}
var x;
var y;
var z;
minimize ln(1+exp(x+2*y+z)) + ln(1+exp(x-y-z)) + ln(1+exp(-3*x+y-z)) + ln(1+exp(3*x+z));
subto x^2 + y^2 <= 1;
solve;
print "x={}" % x;
print "y={}" % y;
print "z={}" % z;
param obj = ln(1+exp(x+2*y+z)) + ln(1+exp(x-y-z)) + ln(1+exp(-3*x+y-z)) + ln(1+exp(3*x+z));
print "obj={:.3f}" % obj;基于MaplPy的问题建模及优化
目前,MindOpt APL 支持云平台及本地版两种使用方式,可参考 MindOpt APL 的建模与优化章节的介绍。 MaplPy 的完整API介绍,可以参考 MaplPy 手册。
首先,创建.mapl文件,编写待优化问题的数学形式。
# Example: 2D Regularized Logistic Regression Classifcation
#
# data points:
# - label=1: {(1,2), (3,0)}
# - label=-1: {(-1,1),(3,-1)}
var x;
var y;
var z;
minimize
ln(1+exp(x+2*y+z)) + ln(1+exp(x-y-z)) + ln(1+exp(-3*x+y-z)) + ln(1+exp(3*x+z));
subto
x^2 + y^2 <= 1;在Python代码中,导入 MaplPy 依赖包
import maplpy as mp创建一个新的 MAPL 模型,命名为“lr”
m = mp.MAPL('lr') # Create MAPL model读入我们声明的数学形式到模型中
m.read(modelfile) # Read model file指定 MindOpt 求解器,并设定其对应的路径地址
m.setOption(mp.StrOption.SOLVER, "mindopt")m.setOption(mp.StrOption.SOLVER_PATH, "/home/mindopt/mindopt/2.1.0/linux64-x86/bin") #you can set your own solver-path here调用模型的求解函数,这会自动实现优化模型的构建及 MindOpt 的调用求解。
m.solve() # Solve执行Python代码,MindOpt 求解过程的日志如下
[mindopt@idec mindopt] python mapl_lr.py
Running mindoptampl
MindOpt Version 2.1.0 (Build date: xxxxxxxx)
Copyright (c) 2020-2025 Alibaba Cloud.
Start license validation (current time : xxxxxxxx).
License validation terminated. Time : 0.002s
wantsol=1
Model summary.
- Num. variables : 3
- Num. constraints : 1
- Num. nonzeros : 8
- Bound range : [1.00e+00,1.00e+00]
Interior point method started.
Iter PrimObj DualObj PrimFea DualFea GapFea Mu Time
0 +2.77258874e+00 +3.77258875e+00 0.0e+00 1.0e+00 1.0e+00 1.0e+00 0.00s
1 +2.10107174e+00 +2.23028984e+00 0.0e+00 7.8e-01 1.0e-01 1.0e-01 0.00s
2 +1.42075610e+00 +1.52543264e+00 6.7e-01 2.7e-01 1.8e-03 1.8e-03 0.00s
3 +1.65885758e+00 +1.72802441e+00 0.0e+00 1.2e-01 3.6e-02 3.6e-02 0.00s
4 +1.65511048e+00 +1.69576276e+00 0.0e+00 6.6e-02 2.1e-02 2.1e-02 0.00s
5 +1.65736811e+00 +1.66000850e+00 0.0e+00 2.6e-04 2.6e-03 2.6e-03 0.00s
6 +1.65490062e+00 +1.65506485e+00 0.0e+00 9.0e-06 1.6e-04 1.6e-04 0.00s
7 +1.65474536e+00 +1.65474726e+00 0.0e+00 3.6e-08 1.9e-06 1.9e-06 0.00s
8 +1.65474358e+00 +1.65474367e+00 0.0e+00 4.9e-12 9.1e-08 9.1e-08 0.00s
Terminated.
- Method : Interior point method.
- Primal objective : 1.6547435766246e+00
- Dual objective : 1.6547436675411e+00
- Num. threads : 1
- Num. iterations : 8
- Solver details : Solver terminated with a primal/dual optimal status.
Interior point method terminated. Time : 0.004203s
Optimizer summary.
- Optimizer used : Interior point method
- Optimizer status : OPTIMAL
Solution summary. Primal solution
- Objective : +1.6547435766e+00
OPTIMAL; objective 1.654744
Completed.成功求解后, MAPL 模型会获取到问题的最优解 (optimal solution),我们可以通过API获取其值并打印:
x = m.getVariable("x").valuey = m.getVariable("y").valuez = m.getVariable("z").valueprint("x = {}".format(x))print("y = {}".format(y))print("z = {}".format(z))则会输出
x = -0.5728551903261085
y = -0.8196564705817261
z = 1.2728750741453017示例 MaplPy-LR.py提供了完整的 Python 源代码:
import maplpy as mp
def lr_solve(modelfile):
m = mp.MAPL('lr') # Create MAPL model
m.read(modelfile) # Read model file
m.setOption(mp.StrOption.SOLVER, "mindopt")
m.setOption(mp.StrOption.SOLVER_PATH, "/home/mindopt/mindopt/2.1.0/linux64-x86/bin") #you can set your own solver-path here
m.solve() # Solve
return m
m = lr_solve("mapl_lr.mapl")
x = m.getVariable("x").value
y = m.getVariable("y").value
z = m.getVariable("z").value
print("x = {}".format(x))
print("y = {}".format(y))
print("z = {}".format(z))