C#调用Cplex入门基础总结
1 创建模型实例
Cplex myCplexSolver = new Cplex();
这一步相当与创建了一个Cplex的一个对象,后面将使用这个对象进行变量定义、目标函数、约束及决策变量的界
2 创建目标函数
//使用默认参数,构建最大值问题的目标函数 IObjective myObjFunc = myCplexSolver.AddMaximize(); IObjective myObjFunc = myCplexSolver.AddMinimize(); //使用变量加系数的方式构建目标函数--批量添加模式 //函数参数为:INumExpr,由变量数组和系数数组相乘构建 IObjective myObjFunc = myCplexSolver.AddMinimize(myCplexSolver.Prod(DV,COFFS));
注释:
Cplex.Prod(INumExpr[], double[]);第一个参数是决策变量数组,第二个参数是决策变量的系数数组
//向模型中动态添加单个决策变量的方法 myCplexSolver.NumVar(myCplexSolver.Column(myObjFunc, coff), lb, ub, varName); //参数解释:要向目标函数中添加的列,该列有目标函数对象和系数构成;下界,上界,变量名称
3 变量的定义
- 定义变量的名字
- 使用变量名字构建Cplex的数值变量
string[] varNames = new varNames[varsCnt]; INumExpr[] varNE = myCplexSolver.NumVarArray(varsCnt, lb, ub, vasNames); //其中的lb可以是数组,也可以使数值;如果为数组则是每个变量有自己独有的界;若为数值,表示所有变量的界是相同的
4 添加约束
添加约束的方法按照行的形式和按照列的形式;
- 按照行的形式使用函数如下
//添加小于等于约束myCplexSolver.AddLe(); //有多个重载版本: //--1 值 <= 表达式 [val <= expr] IRange AddLe(Double, INumExpr); //--2 表达式 <= 表达式 [e1 <= e2] AddLe(INumExpr, INumExpr) //--3 表达式 <= 值 [expr <= rhs] IRange AddLe(INumExpr expr,double rhs) //--4 值 <= 表达式,约束带名字 AddLe(Double, INumExpr, String) //--5 表达式 <= 表达式,约束带名字 [e1 <= e2] AddLe(INumExpr, INumExpr, String) //添加大于等于约束myCplexSolver.AddGe(); //大于等于约束使用函数:myCplexSolver.AddGe();>= 同上,有5个重载版本 //等式约束使用函数:myCplexSolver.AddEq(); 同上,有五个重载版本
- 按列方式添加约束
5 模型求解与输出
//求解模型 myCplexSolver.Solve(); //导出模型:可导出如下格式:.sav, .mps, .Lp, .sav.Gz, .mps.Gz, .Lp.Gz, .Bz2 myCplexSolver.ExportModel("fileName.lp"); //输出解决方案文件:sol后缀 myCplexSolver.WriteSolutions("solmdp.sol"); //获取解的状态:返回值为Cplex.Status类型 myCplexSolver.GetStatus(); //得到变量的值 myCplexSolver.GetVaules();
6 LP、MPS模型文件解释与Cplex导入模型求解
为了实现不同求解器之间的模型通用,我们可以将Cplex的模型导入到Gurobi等求解器去求解,常用的是lp格式和MPS格式。
这节讲述两种文件的定义和一个读入外部模型的示例程序
6.1 LP文件的解释
LP文件非常清晰明了,但貌似规划软件对 mps 文件支持的更好。其中需要注意的是
- Bounds 里面若有 free 表示该变量无上下界
- General 表示整数变量
- Binary 表示二进制变量
- \ 表示注释
6.2 MPS文件解释
上面问题的 MPS 文件内容为:
下面详细解释这个 MPS 文件:
NAME: 表示这个优化模型的名字,后面可以不写内容
ROWS: 每一行,包括目标函数与约束条件
(1) N 表示自由行, obj是对目标函数的命名,可以任意取
(2) L 表示该行小于等于, c1是对改行的命名,可以任意取名
(3) G 表示该行大于等于
(4) E 表示该行等于
COLUMNS: 每一列,及对应的系数
(1) 下面的第一列要空
(2) 下面的第二列表示列的名字,其实就是求解变量
(3) 下面的第三列表示所在行的名字
(4) 下面的第四列表示所在行与列对应的系数
(5) 其中 MARK0000 ‘MARKER’ ‘INTORG’ , MARK0001 ‘MARKER’ ‘INTEND’ 分别表示整数变量的起止
(6) 第五列、第六列分别与第三列、第四列的含义相同。
RHS: 约束条件最右端的数字
(1) 下面的第一列要空
(2) 下面的第二列表示 rhs 名字,可以任取
(3) 下面的第三列表示所在行的名字
(4) 下面的第四列表示所在行对应的 RHS 值
(5) 第五列、第六列分别与第三列、第四列的含义相同。
Bounds: 表示各变量的上界或下界
(1) LO 表示下界
(2) UP 表示上界
(3) FX 表示该变量固定值
(4) FR 表示改变量的范围为 (−∞,∞)(-\infty,\infty)(−∞,∞)
(5) MI 表示下界为负无穷
(6) PL 表示上界为正无穷
MPS 变量默认的范围为 [0,∞)[0,\infty)[0,∞)
ENDDATA: 表示 MPS 文件结束
6.3 导入模型的代码
string modelName = "my.lp"; Cplex my = new Cplex(); my.ImportModel(modelName); my.SetParam(Cplex.Param.RootAlgorithm, Cplex.Algorithm.Primal); my.Solve(); if (my.GetStatus() == Cplex.Status.Optimal) { System.Console.WriteLine("解的状态:" + my.GetStatus()); System.Console.WriteLine(my.GetObjValue()); my.WriteSolutions("solmdp.sol"); }
System.Console.WriteLine("解的状态:" + my.GetStatus()); System.Console.WriteLine(my.GetObjValue()); my.WriteSolutions("solmdp.sol");