【问题标题】:A fatal error is detected by the JRE with CPLEX LazyCallBackJRE 使用 CPLEX LazyCallBack 检测到致命错误
【发布时间】:2019-11-23 17:39:45
【问题描述】:

我在使用 cplex 的 LazyCallback 为库存路由问题运行分支和切割时遇到问题。

public class lazyConstraintCallback extends IloCplex.LazyConstraintCallback {

private IloCplex cplex;
private IloNumVar[][][][] x;
private IloNumVar[][][] y;
private int nbLocations;
private int horizon;
private int nbVehicles;
private double[][] graph;
private boolean subtour;

public lazyConstraintCallback (IloCplex cplex, IloNumVar[][][][] x, IloNumVar[][][] y, int nbLocations, int horizon, int nbVehicles, double[][] graph, boolean subtour) {
    this.cplex=cplex;
    this.x=x;
    this.y=y;
    this.nbLocations=nbLocations;
    this.horizon=horizon;
    this.nbVehicles=nbVehicles;
    this.graph=graph;
    this.subtour=subtour;
}

protected void main() throws IloException {
    this.graph= new double[this.nbLocations][this.nbLocations];
    for(int t=0;t<this.horizon;t++) {
        for(int k=0;k<this.nbVehicles;k++) {
            double tourlength=1;
            for(int i=1;i<this.nbLocations;i++) {
                if(getValue(y[i][t][k])>0.1) {
                    tourlength++;
                }
            }
            int[] subtour = null;
            if(tourlength>5) {
                for(int i=0;i<this.nbLocations;i++) {
                    for(int j=i+1;j<this.nbLocations;j++) {
                        graph[i][j]=getValue(x[i][j][t][k]);
                    }
                }
                subtour=this.getSubtours(graph, tourlength);
                if(this.subtour) {
                    IloLinearNumExpr expr = this.cplex.linearNumExpr();
                    for (int i=0;i<subtour.length; i++) {
                        for (int j=i+1;j<subtour.length;j++) {
                            if (subtour[i] < subtour[j]) {
                                expr.addTerm(1, this.x[subtour[i]][subtour[j]][t][k]);
                            } else {
                                expr.addTerm(1, this.x[subtour[j]][subtour[i]][t][k]);
                            }
                        }
                    }
                    IloRange SEC = this.cplex.le(expr, subtour.length-1);
                    this.cplex.addLazyConstraint(SEC);
                    System.out.println(SEC);
                }
            }
        }
    }
}

似乎是在添加 SEC 切割时出现问题。但是,如下图所示,切割似乎没有任何问题:

IloRange  : -infinity <= (1.0*x_{2,5}^{1,2} + 1.0*x_{2,6}^{1,2} + 1.0*x_{5,6}^{1,2}) <= 2.0

如果有人有想法,我将不胜感激。

这是错误信息:

Java 运行时环境检测到一个致命错误: SIGSEGV (0xb) at pc=0x000000012cc5020b, pid=7202, tid=10499

JRE 版本:Java(TM) SE Runtime Environment (10.0.1+10) (build 10.0.1+10) Java VM:Java HotSpot(TM) 64 位服务器 VM(10.0.1+10,混合模式,分层,压缩 oops,g1 gc,bsd-amd64) 有问题的框架: C [libcplex1271remotejni.jnilib+0x73920b] _72f67b7f5c69d5c29f1bcb05ad4e6d45+0x1b

不会写入核心转储。核心转储已被禁用。要启用核心转储,请在再次启动 Java 之前尝试“ulimit -c unlimited”

包含更多信息的错误报告文件保存为: /Users/faycal/Desktop/AcademicWork/info/workspace/IRP/hs_err_pid7202.log

如果您想提交错误报告,请访问: http://bugreport.java.com/bugreport/crash.jsp 崩溃发生在 Java 虚拟机之外的本地代码中。 请参阅有问题的框架以了解报告错误的位置。

【问题讨论】:

    标签: java cplex


    【解决方案1】:

    问题出在这一行:

    this.cplex.addLazyConstraint(SEC);
    

    您在这里所做的是将惰性约束添加到模型 static 惰性约束表中。由于这是模型的一部分,因此不允许在优化期间对其进行修改。要从回调中添加惰性约束,请使用回调的 add() 方法:

    add(SEC);
    

    【讨论】:

    • 非常感谢。这解决了问题。但是,我想问一下这种情况下 addLazyConstraint() 方法有什么用?
    • 添加惰性约束有两个选项: 1. 您可以添加所有惰性约束开始优化小瓶solve()。这是使用addLazyConstraints() 完成的,如果惰性约束很容易枚举并且它们的数量相对较小,则很有用。 2. 您可以使用回调动态分离惰性约束(就像您所做的那样)。这在有很多惰性约束的情况下很有用(特别是如果它们的数量是指数级的)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-06
    相关资源
    最近更新 更多