Модель Cplex: нет решения

возникли проблемы с моим C++ Concert Cplex. Я пытаюсь воссоздать задачу о кратчайшем пути. Вывод в текстовый файл:

Minimize
 obj: 2 x_12 + x_13 + 2 x_21 + x_24 + x_31 + 3 x_34 + x_42 + 3 x_43 + x9
Subject To
 c1: x_12 + x_13 - x_21 - x_31 + x_14 - x_41  = 1
 c2: - x_12 + x_21 + x_24 - x_42 + x_23 - x_32  = 0
 c3: - x_13 + x_31 + x_34 - x_43 - x_23 + x_32  = 0
 c4: - x_24 - x_34 + x_42 + x_43 - x_14 + x_41  = -1
Bounds
      x9 = 0
End

Затем я использовал следующий код для получения решения:

    IloCplex spp(model);
    spp.setParam(IloCplex::RootAlg, IloCplex::AutoAlg);
    spp.solve();
    IloArray<IloNumArray> vals(env);
    env.out() << "Solution status = " << spp.getStatus() << endl;
    env.out() << "Solution value  = " << spp.getObjValue() << endl;
    env.out() << "Values x       = " << vals << endl;

Однако вывод, который я продолжаю получать, таков:

Solution status = Optimal
Solution value = 0
Values x       =  []

Кто-нибудь знает, что не так с моей программой? Спасибо

РЕДАКТИРОВАТЬ:

Моя модель построена в самой программе, вот первая часть:

    IloEnv env;
    IloModel model(env);
    IloArray<IloNumVarArray> x(env);
    IloRangeArray c(env);
    IloInt nnodes = G.size();
    IloInt i, j;
    IloEnv env = model.getEnv();

    //SHORTEST PATH PROBLEM

    for (i = 0; i < nnodes; i++){   //x decision variables
        x.add(IloNumVarArray(env, nnodes, 0, IloInfinity));
    }
    for (i = 0; i < nnodes; i++){
        for (j = 0; j < nnodes; j++){
            stringstream sts;
            sts << "x_" << i + 1 << j + 1;
            x[i][j].setName(sts.str().c_str()); //SET NAMES
        }
    }

    //set objective min sum_(all ij)[c_ij][x_ij]
    IloExpr obj(env);
    for (i = 0; i < nnodes; i++){
        for (j = 0; j < nnodes; j++){
            obj += G[i][j] * x[i][j];
        }
    }
    model.add(IloMinimize(env, obj));
    obj.end();

    //constraints sum_j[x_ij]-sum_j[x_ji] = 1 for s, -1 for t, or 0
    for (i = 0; i < nnodes; i++){
        int ss = 0;
        if (i == s) ss = 1;
        if (i == t) ss = -1;
        IloExpr sum1(env);
        IloExpr sum2(env);
        for (j = 0; j < nnodes; j++){
            sum1 += x[i][j];
            sum2 += x[j][i];
        }
        c.add(sum1 - sum2 == ss);
        sum1.end();
        sum2.end();
    }
    model.add(c);

    //solving---------------------------------------------------------
    IloCplex spp(model);

    //write to file
    spp.exportModel("model1.lp");
    spp.solve();

person Michael    schedule 09.07.2016    source источник


Ответы (3)


Похоже, в вашем коде чего-то не хватает. В начале кода создания вашей модели у вас есть объявление двумерного массива IloNumVars x:

IloEnv env;
IloModel model(env);
IloArray<IloNumVarArray> x(env);
IloRangeArray c(env);

Но позже вы говорите, что код, который вы используете для получения решения, выглядит так:

IloCplex spp(model);
spp.setParam(IloCplex::RootAlg, IloCplex::AutoAlg);
spp.solve();
IloArray<IloNumArray> vals(env);
env.out() << "Solution status = " << spp.getStatus() << endl;
env.out() << "Solution value  = " << spp.getObjValue() << endl;
env.out() << "Values x       = " << vals << endl;

Я не вижу, где вы что-то делаете, чтобы связать vals (двумерный массив IloNums) со значениями в x (двухмерный массив IloNumVars в вашей модели). Я думаю, что вы должны вызывать что-то вроде spp.getValue(...) для IloNumVars, чтобы получить значения в массиве IloNums.

person TimChippingtonDerrick    schedule 11.07.2016

Видимо вы модель не из файла читаете. Вот пример. Итак, в вашем случае:

  #include <ilcplex/ilocplex.h>
  ILOSTLBEGIN

  int main (int argc, char **argv)
  {
     IloEnv   env;
     try {
        IloModel model(env);
        IloCplex cplex(model);

        IloObjective   obj;
        IloNumVarArray var(env);
        IloRangeArray  con(env);

        cplex.importModel(model, "tmp.lp", obj, var, con);
        cplex.extract(model);

        // Optimize the problem and obtain solution.
        if ( !cplex.solve() ) {
           env.error() << "Failed to optimize LP" << endl;
           throw(-1);
        }

        IloNumArray vals(env);
        env.out() << "Solution status = " << cplex.getStatus() << endl;
        env.out() << "Solution value  = " << cplex.getObjValue() << endl;
        cplex.getValues(vals, var);
        env.out() << "Values        = " << vals << endl;
        cplex.getSlacks(vals, con);
        env.out() << "Slacks        = " << vals << endl;
        cplex.getDuals(vals, con);
        env.out() << "Duals         = " << vals << endl;
        cplex.getReducedCosts(vals, var);
        env.out() << "Reduced Costs = " << vals << endl;
     }
     catch (IloException& e) {
        cerr << "Concert exception caught: " << e << endl;
     }
     catch (...) {
        cerr << "Unknown exception caught" << endl;
     }

     env.end();

     return 0;
  }  // END main

где tmp.lp — файл вашей модели LP. Запустив этот код, я получил

Tried aggregator 1 time.
LP Presolve eliminated 3 rows and 12 columns.
Aggregator did 1 substitutions.
All rows and columns eliminated.
Presolve time = 0.00 sec. (0.01 ticks)
Solution status = Optimal
Solution value  = 0
Values        = [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
Slacks        = [0, 0, 0, 0]
Duals         = [1, 0, 0, 1]
Reduced Costs = [1, 0, 3, 2, 2, 4, 0, 2, 1, 0, 0, 0, 0]
person serge_k    schedule 09.07.2016
comment
Спасибо за ответ, я отредактировал исходный пост. Рассматриваемая модель создана cplex. Вывод текстового файла является результатом работы exportModel(). Итак, в моем случае есть ли ошибка вsolve ()? - person Michael; 09.07.2016

Сначала позвольте мне заметить кое-что в цитируемом Вами тр. Есть два решения, которые идеально подходят для решения, которое предоставляет вам cplex:

x_14 = 1, all other x_ijs = 0 or  x_41 = -1 all other x_ijs = 0

в результате объективное значение 0.

Имея x_14 и x_41 в качестве переменных, но не связанных с какой-либо стоимостью в цели, вы в основном поощряете путешествие от источника к стоку без каких-либо затрат. Проблема не в вашей модели, работает нормально. Это то, как вы строите свой график, каким бы он ни был.

person Serkan Kalay    schedule 14.07.2016