最近使用 java 调用 cplex, 发现 cplex 对 java 的支持比对matlab强大多了,类跟方法有几百个。
但这些类和方法的注释并不是特别详细,还需要结合例子来看懂。
一、 准备工作:导入 cplex 库 到 eclipse 中
1. 首先从官网上下载 cplex:
https://www.ibm.com/developerworks/community/blogs/jfp/entry/CPLEX_Is_Free_For_Students?lang=en, 这个页面能申请学术版。
http://www-01.ibm.com/software/websphere/products/optimization/cplex-studio-community-edition, 这个是普通的免费版,最多只能有1000个约束条件和1000个变量。
cplex 的 java 使用手册:http://download.csdn.net/download/robert_chen1988/10119473
2. 将 cplex库导入java里面。
新建一个java项目,右键单击项目,build path, add libraries, 如下图所示:
然后选择 user library, 刚开始里面并没有 cplex库,那么我们继续 点击 user libraries 将 cplex 库添加进来。选择新建,如下图所示:
可以命名为 cplex, 然后开始导入cplex 的库:
选择导入外部 jar, 选择 cplex 安装目录中的 lib 文件夹,将 cplex.jar 添加进去即可,这个项目就能调用 cplex 了。
3. 添加 cplex 的java 例子。
cplex 的 java 例子在安装程序的 cplex\examples\src\java 目录下, 可以在java 项目里新建一个package,将 例子全部导进去,就能查看例子了。
二、求解问题。
1. 一个简单的线性规划问题:
\begin{align} &\max\quad &&x_1 + 2x_2 +3x_3\nonumber\\ &s.t.&&\nonumber\\ & &&-x_1 + x_2 + x_3 \leq 20\nonumber\\ & &&x_1 - 3x_2 + x_3 \leq 30\nonumber\\ & &&0\leq x_1\leq 40\nonumber \end{align}
java 中的 cplex 代码如下:
import ilog.concert.IloException;import ilog.concert.IloNumVar;import ilog.cplex.IloCplex;public class LP1 { public static void main(String[] args) { try { IloCplex cplex = new IloCplex(); // creat a model double[] lb = {0.0, 0.0, 0.0}; double[] ub = {40.0, Double.MAX_VALUE, Double.MAX_VALUE}; IloNumVar[] x = cplex.numVarArray(3, lb, ub); double[] objvals = {1.0, 2.0, 3.0}; cplex.addMaximize(cplex.scalProd(x, objvals)); double[] coeff1 = {-1.0, 1.0, 1.0}; double[] coeff2 = {1.0, -3.0, 1.0}; cplex.addLe(cplex.scalProd(x, coeff1), 20.0); cplex.addLe(cplex.scalProd(x, coeff2), 30.0); if (cplex.solve()) { cplex.output().println("Solution status = " + cplex.getStatus()); cplex.output().println("Solution value = " + cplex.getObjValue()); double[] val = cplex.getValues(x); for (int j = 0; j < val.length; j++) cplex.output().println("x" + (j+1) + " = " + val[j]); } cplex.end(); } catch (IloException e) { System.err.println("Concert exception caught: " + e); } }}输出结果:
Tried aggregator 1 time.
No LP presolve or aggregator reductions. Presolve time = 0.00 sec. (0.00 ticks) Iteration log . . . Iteration: 1 Dual infeasibility = 0.000000 Iteration: 2 Dual objective = 202.500000 Solution status = Optimal Solution value = 202.5 x1 = 40.0 x2 = 17.5 x3 = 42.52. 使用java 调用 cplex 的几点感受:
(1)使用 IloCplex 类新建一个 cplex 类, 使用 IloNumVar 定义求解变量, 使用 addMaximize 或addMinimize 定义求解目标,
使用 addLe 添加约束条件, 使用 solve() 方法求解。
(2)使用 IloNumExpr 定义中间变量。
(3)cplex 的 java api 不支持加减乘除符号,加必须用 sum 方法, 减必须用 diff 方法, 乘除必须用 prod 方法。