Java 复合表达式和约束

Java Cplex Expressions and Constraints

我想了解 cplex 中的表达式到底是什么,以及如何在 Java 中使用它们来创建线性规划。不幸的是,文档中没有足够的例子让我理解它们。

我想写的是一些具有以下信息的约束:

问题 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 函数

希望对您有所帮助!