Java Cplex表达式和约束

时间:2017-07-20 10:25:52

标签: java mathematical-optimization linear-programming cplex

我试图了解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}
    1. sum {i in I}, {j in J}, {k in K} of c[i][j][k]*v[i][j][k] >= rhs[i][j][k]
    2. 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();
        }
    }

}

1 个答案:

答案 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(...);添加目标函数。

我希望这有帮助!