我试图了解cplex中的表达式究竟是什么以及如何在Java中使用它们来创建线性程序。遗憾的是,文档中没有足够的示例供我理解。
我想写的是一些带有以下信息的约束:
sum {i in I}, {j in J}, {k in K} of c[i][j][k]*v[i][j][k] >= rhs[i][j][k]
sum {k in K} of c[i][j][k]*v[i][j][k] >= rhs[i][j][k] for all {i in I}, {j in J}
是否可能解决1.问题是,在三个循环之前初始化Expression以及2.在第三个循环之前初始化Expression?
循环内部跟随expression.addTerm(...,...);
也是2.问题代码expression[i][j].addTerm(...,...);
和expression.addTerm(...,...);
之间的问题有什么不同?
这里也是我的小型最小化线性程序的代码。
import java.util.ArrayList;
import java.util.HashMap;
import ilog.concert.IloIntVar;
import ilog.concert.IloLinearIntExpr;
import ilog.cplex.IloCplex;
public class MiniCplex {
public static void main(String[] args) {
miniCplex();
}
public static void miniCplex () {
try {
HashMap<Integer,Integer> zw = new HashMap<Integer,Integer>();
zw.put(0, 1);
zw.put(1, 1);
zw.put(2, 0);
zw.put(3, 0);
zw.put(4, 2);
zw.put(5, 2);
HashMap<Integer,Integer> rhs = new HashMap<Integer,Integer>();
rhs.put(0, 20);
rhs.put(1, 40);
rhs.put(2, 0);
rhs.put(3, 0);
rhs.put(4, 5);
rhs.put(5, 7);
ArrayList<HashMap<Integer,Integer>> forms = new ArrayList<HashMap<Integer,Integer>>();
HashMap<Integer,Integer> formGA = new HashMap<Integer,Integer>();
formGA.put(0, 1);
formGA.put(1, 1);
formGA.put(2, 0);
formGA.put(3, 0);
formGA.put(4, 1);
formGA.put(5, 1);
forms.add(formGA);
HashMap<Integer,Integer> formEZ1 = new HashMap<Integer,Integer>();
formEZ1.put(0, 3);
formEZ1.put(1, 0);
formEZ1.put(2, 0);
formEZ1.put(3, 0);
formEZ1.put(4, 0);
formEZ1.put(5, 0);
forms.add(formEZ1);
HashMap<Integer,Integer> formEZ2 = new HashMap<Integer,Integer>();
formEZ2.put(0, 0);
formEZ2.put(1, 4);
formEZ2.put(2, 0);
formEZ2.put(3, 0);
formEZ2.put(4, 0);
formEZ2.put(5, 0);
forms.add(formEZ2);
// System.out.println("forms: " + forms.get(0).get(3));
IloCplex cplex = new IloCplex();
//variables
IloIntVar [] p = new IloIntVar[3]; // Anzahl der Formen
for (int j = 0; j < 3; j++) {
p[j] = cplex.intVar(0, 8);
}
//objective
IloLinearIntExpr objective = cplex.linearIntExpr();
for (int l = 0; l < 3; l++) {
objective.addTerm(1,p[l]);
}
// define objective
cplex.addMinimize(objective);
//expressions
// IloLinearIntExpr expr = new IloLinearIntExpr;
for (int l = 0; l < formEZ2.size(); l++) {
IloLinearIntExpr expr = cplex.linearIntExpr();
for (int l2 = 0; l2 < forms.size(); l2++) {
// System.out.println("EZ index: " + l + " von der " + l2 + " form");
expr.addTerm(forms.get(l2).get(l), p[l2]);
}
cplex.addGe(expr, (rhs.get(l)-zw.get(l)));
}
if (cplex.solve()) {
System.out.println("An optimal solution for the LP has been found!");
double objectVal = cplex.getObjValue();
System.out.println("Objective function: " + objectVal);
for (int i = 0; i < p.length; i++) {
System.out.println("The value for the variable v(" + i + ") is " + cplex.getValue(p[i]));
}
} else {
System.out.println("LP not solved");
}
cplex.end();
} catch (Exception exc) {
exc.printStackTrace();
}
}
}
答案 0 :(得分:2)
表达式是常量(即固定数字)和变量的组合,后来可以在模型中使用。一种非常重要的表达式是线性表达式,它是变量的线性组合(即术语之和,其中每个术语是变量乘以常量)。
代码expr = cplex.linearIntExpr();
创建并为expr
分配一个空线性表达式,然后您可以使用expr.addTerm(constant, variable);
向表达式添加术语。为此,您必须提供(在第二个参数中)对参与该术语的变量的引用,最简单的方法是将这些引用保留在数组中。当您创建新变量时(例如,使用cplex.intVar(...)
或cplex.boolVar(...)
),您将获得对新变量的引用。您还可以通过扩展表达式
expr = cplex.sum(expr, cplex.prod(constant, variable));
。
在线性或整数线性模型中,您可以在目标函数中使用线性表达式并创建约束。为了指定模型目标函数,您必须创建表示目标函数的表达式,例如obj
,然后执行cplex.addMaximize(obj);
。约束也有右侧,因此您可以使用左侧(包含模型变量)创建表达式(例如lhs
),然后使用cplex.addLe(lhs, 1, "constraint_name");
添加约束。最后一个语句创建约束&#34; lhs&lt; = 1&#34;。
您必须为模型中的每个约束创建一个表达式,然后执行cplex.addLe(...);
或model.addGe(...);
或model.addEq(...);
以将约束添加到模型中。您还必须为目标函数创建一个表达式,并使用cplex.addMaximize(...);
或cplex.addMinimize(...);
添加目标函数。
我希望这有帮助!