JRE обнаруживает фатальную ошибку с помощью CPLEX LazyCallBack

У меня проблема при выполнении ветвления и вырезания для задачи маршрутизации инвентаризации с помощью 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) при pc = 0x000000012cc5020b, pid = 7202, tid = 10499

Версия JRE: Java (TM) SE Runtime Environment (10.0.1 + 10) (сборка 10.0.1 + 10) Java VM: Java HotSpot (TM) 64-разрядная серверная виртуальная машина (10.0.1 + 10, смешанный режим, многоуровневый, сжатый oops, g1 gc, bsd-amd64) Проблемный фрейм: C [libcplex1271remotejni.jnilib + 0x73920b] _72f67b7f5c69d5c29f1bcb05ad4e6d45 + 0x1b

Дамп ядра записываться не будет. Дампы ядра отключены. Чтобы включить дамп ядра, попробуйте "ulimit -c unlimited" перед повторным запуском Java.

Файл отчета об ошибке с дополнительной информацией сохраняется как /Users/faycal/Desktop/AcademicWork/info/workspace/IRP/hs_err_pid7202.log

Если вы хотите отправить отчет об ошибке, посетите: http://bugreport.java.com/bugreport/crash.jsp Сбой произошел за пределами виртуальной машины Java в собственном коде. См. Проблемный фрейм, чтобы узнать, где сообщить об ошибке.


person Fayçal A. Touzout    schedule 23.11.2019    source источник


Ответы (1)


Проблема в этой строке:

this.cplex.addLazyConstraint(SEC);

Здесь вы добавляете ленивые ограничения в таблицу статических ленивых ограничений модели. Поскольку это часть модели, ее нельзя изменять во время оптимизации. Чтобы добавить ленивое ограничение из обратного вызова, используйте метод обратного вызова add():

add(SEC);
person Daniel Junglas    schedule 25.11.2019
comment
Большое Вам спасибо. Это устранило проблему. Однако я хотел бы спросить, как в этом случае используется метод addLazyConstraint ()? - person Fayçal A. Touzout; 25.11.2019
comment
Есть два варианта добавления ленивых ограничений: 1. Вы можете добавить все ленивые ограничения до запуска флакона оптимизации solve(). Это делается с помощью addLazyConstraints() и полезно, если ленивые ограничения легко перечислить и их количество относительно невелико. 2. Вы можете динамически разделять ленивые ограничения с помощью обратного вызова (как и вы). Это полезно в случае, если есть много ленивых ограничений (в частности, если их экспоненциальное количество). - person Daniel Junglas; 25.11.2019