Как исправить границы / изменить границы переменных в макросе BranchCallback? C ++ - PullRequest
0 голосов
/ 13 марта 2019

В приведенном ниже коде я пытаюсь создать ответный вызов ветви с помощью макроса CPLEX ILOBRANCHCALLBACK2, где я выбираю способы исправления границ некоторых переменных.Но при выполнении исправления я получаю ошибку нарушения доступа при чтении некоторого пространства.Может ли кто-нибудь сказать мне правильный способ сделать это?Нужно ли делать ветку make для всех переменных или ответ ответной ветви сделает это сам?

ILOBRANCHCALLBACK2(simetria, const Instance&, instance, const IloNumVarMatrix&, X) {
    vector<coordenates> F_zeros;
    vector<coordenates> F_ones;
    vector<int> a;
    a.resize(instance.getNbClients());
    a[0] = 0;
    coordenates first;
    first.x = 0;
    first.y = 0;
    F_ones.push_back(first);

    // Je verifie s'il y a deja des variables fixées
    for(int i = 1; i < instance.getNbClients() - 1; ++i) {
        for(int j = 1; j < instance.getNbVehicles() - 1; ++j) {
            if(getUB(X[i][j]) <= 0.001) {
                coordenates obj;
                obj.x = i;
                obj.y = j;
                F_zeros.push_back(obj);
            }

            if(getLB(X[i][j]) >= 0.99) {
                coordenates obj;
                obj.x = i;
                obj.y = j;
                F_ones.push_back(obj);
            }
        }
    }

    // Je vais construir mon a.
    for(int k = 1; k < instance.getNbClients() - 1; k++) {
        // Zero setting
        if(a[k - 1] == instance.getNbVehicles() - 1 || findInVector(F_zeros, k, a[k - 1] + 1)) {
            a[k] = a[k - 1];
            coordenates obj;
            obj.x = k;
            obj.y = a[k - 1];

        } else {
            a[k] = a[k - 1] + 1;
            coordenates obj;
            obj.x = k;
            obj.y = a[k - 1] + 1;
        }
    }

    // Je mets a jour le F_zero a partir de a
    for(int k = 1; k < instance.getNbClients() - 1; k++) {
        for(int p = 1; p < instance.getNbVehicles() - 1; p++) {
            if(p > a[k]) {
                coordenates obj;
                obj.x = k;
                obj.y = p;
                F_zeros.push_back(obj);
            }
        }
    }

    // je fixe tout ce qui est en  F_zero en zero (Changer les bornnes)
    for(int i = 0; i < F_zeros.size(); i++) {
        int a = F_zeros[i].x;
        int b = F_zeros[i].y;
        X[a][b].setUB(0);
        // X[F_zeros[i].x][F_zeros[i].y].setBounds(0, 0);
        // makeBranch(X[F_zeros[i].x][F_zeros[i].y], 0, IloCplex::BranchUp, getBestObjValue());
        // makeBranch(X[F_zeros[i].x][F_zeros[i].y], 0, IloCplex::BranchDown, getBestObjValue());
    }

1 Ответ

1 голос
/ 14 марта 2019

Вы не можете изменить модель во время ее решения (например, см. Примечание в документации здесь ). Как вы выяснили, это может привести к segfault. Таким образом, вы не можете использовать метод setUB в вашем обратном вызове.

Как вы, вероятно, знаете (основываясь на коде, который вы закомментировали), вы можете использовать метод makeBranch , который:

инструктирует вызывающий объект IloCplex, как создать подузел из текущий узел, указав новые, более жесткие границы для набора переменные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...