Java 复合表达式和约束
Java Cplex Expressions and Constraints
我想了解 cplex 中的表达式到底是什么,以及如何在 Java 中使用它们来创建线性规划。不幸的是,文档中没有足够的例子让我理解它们。
我想写的是一些具有以下信息的约束:
- 系数:c 具有三个索引 {i in I}、{j in J}、{k in K}
- 变量:v 具有三个索引 {i in I}、{j in J}、{k in K}
- RHS:具有三个索引的 rhs {i in I}、{j in J}、{k in K}
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. 表达式的初始化在三个循环之前和 2. 表达式在第三个循环之前的初始化是否有可能的解决方案?
循环内部遵循 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();
}
}
}
表达式是常量(即固定数字)和稍后可以在模型中使用的变量的组合。一种非常重要的表达式类型是线性表达式,它是变量的线性组合(即项的总和,其中每个项是一个变量乘以一个常数)。
代码 expr = cplex.linearIntExpr();
创建并分配给 expr
一个空的线性表达式,然后您可以使用 expr.addTerm(constant, variable);
向表达式添加项。为此,您必须(在第二个参数中)提供对参与该术语的变量的引用,最简单的方法是将此类引用保存在一个数组中。当您创建一个新变量时(例如,使用 cplex.intVar(...)
或 cplex.boolVar(...)
),您将获得对新变量的引用。您还可以通过以下方式扩展表达式
expr = cplex.sum(expr, cplex.prod(constant, variable));
.
在线性或整数线性模型中,您可以在 objective 函数中使用线性表达式来创建约束。为了指定模型 objective 函数,您必须创建一个表达式,比如 obj
,代表 objective 函数,然后执行 cplex.addMaximize(obj);
。约束也有右边,所以你可以用左边(涉及模型变量)创建一个表达式,比如 lhs
,然后用 cplex.addLe(lhs, 1, "constraint_name");
添加约束。最后一条语句创建约束 "lhs <= 1".
您必须为模型中的每个约束创建一个表达式,然后执行cplex.addLe(...);
或model.addGe(...);
或model.addEq(...);
以将约束添加到模型中。您还必须为 objective 函数创建一个表达式,并添加带有 cplex.addMaximize(...);
或 cplex.addMinimize(...);
.
的 objective 函数
希望对您有所帮助!
我想了解 cplex 中的表达式到底是什么,以及如何在 Java 中使用它们来创建线性规划。不幸的是,文档中没有足够的例子让我理解它们。
我想写的是一些具有以下信息的约束:
- 系数:c 具有三个索引 {i in I}、{j in J}、{k in K}
- 变量:v 具有三个索引 {i in I}、{j in J}、{k in K}
- RHS:具有三个索引的 rhs {i in I}、{j in J}、{k in K}
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. 表达式的初始化在三个循环之前和 2. 表达式在第三个循环之前的初始化是否有可能的解决方案?
循环内部遵循 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();
}
}
}
表达式是常量(即固定数字)和稍后可以在模型中使用的变量的组合。一种非常重要的表达式类型是线性表达式,它是变量的线性组合(即项的总和,其中每个项是一个变量乘以一个常数)。
代码 expr = cplex.linearIntExpr();
创建并分配给 expr
一个空的线性表达式,然后您可以使用 expr.addTerm(constant, variable);
向表达式添加项。为此,您必须(在第二个参数中)提供对参与该术语的变量的引用,最简单的方法是将此类引用保存在一个数组中。当您创建一个新变量时(例如,使用 cplex.intVar(...)
或 cplex.boolVar(...)
),您将获得对新变量的引用。您还可以通过以下方式扩展表达式
expr = cplex.sum(expr, cplex.prod(constant, variable));
.
在线性或整数线性模型中,您可以在 objective 函数中使用线性表达式来创建约束。为了指定模型 objective 函数,您必须创建一个表达式,比如 obj
,代表 objective 函数,然后执行 cplex.addMaximize(obj);
。约束也有右边,所以你可以用左边(涉及模型变量)创建一个表达式,比如 lhs
,然后用 cplex.addLe(lhs, 1, "constraint_name");
添加约束。最后一条语句创建约束 "lhs <= 1".
您必须为模型中的每个约束创建一个表达式,然后执行cplex.addLe(...);
或model.addGe(...);
或model.addEq(...);
以将约束添加到模型中。您还必须为 objective 函数创建一个表达式,并添加带有 cplex.addMaximize(...);
或 cplex.addMinimize(...);
.
希望对您有所帮助!