\qquad 最近再搞一些模型,需要用到AMPL中不同的求解器进行验证求解,故建立本博客,用于随时整理AMPL的相关语法和命令,方便后续查阅,也方便同在使用AMPL的小伙伴参考~
\qquad AMPL将模型和数据进行分离,书写一个模型的时候需要完成一个
.mod
文件和一个
.dat
文件的书写,在
.mod
书写模型参数,变量,目标,约束等要素,在
.dat
文件中书写参数的取值。
1、参数\集合和变量定义
\qquad 单个参数定义方式为:
param 参数;
#示例,定义一个名为n的参数
param n;
\qquad 集合定义方式为:
set = 范围;
#示例,定义一个0到n的集合V
set V = 0..n;
\qquad 集合参数定义方式为:
param 参数{集合};
#示例,定义一个包括0到n个元素的参数集合L
param L{V} >= 0; #注释:后面的>=0表示集合中参数的取值范围非负
\qquad 变量定义方式为:
var 变量名{集合} 类型;
#示例,定义一个(0,1)变量x,x包括三个维度的下标,每个维度的大小均为0到n
var x{V,V,V} binary;
2、目标和约束的书写
\qquad
目标的书写,以最小化某个目标obj
为例,如下所示:
minimize 目标名: 目标表达式;
minimize obj: 5*sum(i in V, j in V, k in V)x[i,j,k];
\qquad 约束的书写,以每个变量x均不小于5,并且对x第一维度的求和值不大于20,为例,如下所示:
约束名{枚举范围}:sum{求和范围} 约束表达式;
C1{i in V, j in V, k in V}x[i,j,k]>=5;
C2{i in V}: sum{j in V, k in V}x[i,j,k]<=20;
3、求解命令
\qquad 基本求解命令包括模型加载,数据加载,求解器选择,和求解四步,如下所示:
model ***.mod;
data ***.dat;
option solver cplex; #可以选择各种求解器,cplex gurobi xpress lingo baron等,官网有不同的价位,也有免费的cbc ipopt等可以使用
solve;
\qquad 展示求解时间信息,在AMPL用户手册中,提到了如下几种求解器求解相关的时间:
_solve_elapsed_time: elapsed seconds for most recent solve command
_solve_system_time: system CPU seconds used by most recent solve command
_solve_user_time: user CPU seconds used by most recent solve command
_solve_time: _ solve _ system _ time + _ solve _ user _ time
\qquad
笔者通过测试和与gurobi单独求解的时间对比,发现_solve_system_time
比较接近真实的模型求解时间,所以可以使用_solve_system_time
作为模型求解的时间,在模型求解完毕之后,通过display _solve_system_time
获取到这个时间值。
4、AMPL调用不同求解器的Options目录
\qquad 在使用AMPL调用不同求解器时,可以通过命令行,给求解器定义不同的求解参数,如限制求解时间等。首先给出使用AMPL给求解器给定options的命令如下所示:
option SolverName_options '命令=**';
e.g., option gurobi_options 'timelim=7200'; #限定gurobi求解时间最多为7200s
\qquad
下面笔者整理了一些求解器的options网址,有需要可以自行查看所需要的命令。
\qquad
AMPL官方给出了一个不太全的求解器options参考:https://dev.ampl.com/solvers/gurobi/index.html
\qquad
Gurobi官网给出的AMPl 的options参考:https://www.gurobi.com/documentation/9.5/ampl-gurobi/parameters.html
\qquad
Octeract官网给出的AMPl 的options参考:https://octeract.gg/docs/octeract-engine-options/options-reference/
5、AMPL IDE中展示变量/参数的值
\qquad
在AMPL IDE中需要使用display
来展示变量或者参数的取值,具体命令如下所示:
display {set_expression: condition} {elements_to_display};
\qquad 举个例子,假如我想要查看变量 x i , j , k , i ∈ V , j ∈ V , k ∈ C x_{i,j,k},i \in V, j \in V, k \in C xi,j,k,i∈V,j∈V,k∈C中满足 x i , j , k = 1 x_{i,j,k}=1 xi,j,k=1的值,则命令如下所示:
display {i in V, j in V, k in C:x[i,j,k]==1} x[i,j,k];
\qquad 由于计算精度问题,上式一般写成如下的形式:
display {i in V, j in V, k in C:x[i,j,k]>=0.99} x[i,j,k];