Многомерная переменная решения Cplex C++

Я новичок в использовании cplex, и я пытаюсь найти некоторую информацию в Интернете, но не нашел четких вещей, которые могли бы помочь мне в моей проблеме.

У меня P[k]k будет равно от 1 до 4

и у меня есть переменная решения x[i][k] должна быть равна 0 или 1 (также p[k])

i находится между 1 и 5

На данный момент я делаю так

  IloEnv env;
  IloModel model(env);
  IloNumVarArray p(env);
  p.add(IloNumVar(env, 0, 1));
  p.add(IloNumVar(env, 0, 1));
  p.add(IloNumVar(env, 0, 1));
  IloIntVar x(env, 0, 1);

  model.add(IloMaximize(env, 1000 * p[1] + 2000 * p[2] + 500 * p[3] + 1500 * p[4]));

   for(int k = 1; k <= 4; k++){
    for(int i = 1; i <= 5; i++){
      model.add(x[i][k] + x[i][k] + x[i][k] + x[i][k] + x[i][k] => 2 * p[k]; );
    }}

Цикл должен делать что-то вроде этого:

x[1][1] + x[2][1] + x[3][1] + x[4][1] + x[5][1] => 2 * p[1];

x[1][2] + x[2][2] + x[3][2] + x[4][2] + x[5][2] => 2 * p[2];

x[1][3] + x[2][3] + x[3][3] + x[4][3] + x[5][3] => 2 * p[3];

x[1][4] + x[2][4] + x[3][4] + x[4][4] + x[5][4] => 3 * p[4];

но я далек от этого результата.

У кого-нибудь есть идея?

Спасибо


person usertfwr    schedule 19.03.2013    source источник


Ответы (2)


Вероятно, вы захотите использовать IloNumExpr.

for(int k = 0; k < 4; k++){
   IloNumExpr sum_over_i(env);
   for(int i = 0; i < 5; i++){
        sum_over_i += x[i][k];
   }
   model.add(sum_over_i >= 2 * p[k]; );
}

Вам также необходимо объявить x как двумерный массив.

IloArray x(env, 4);
for (int k = 0; k < 4; ++k)
      x[k] = IloIntVarArray(env, 5, 0, 1);

Кроме того, в С++ индексы массива имеют значение от 0 до size-1, а не от 1 до size. Ваша цель должна быть написана

model.add(IloMaximize(env, 1000 * p[0] + 2000 * p[1] + 500 * p[2] + 1500 * p[3]));
person David Nehme    schedule 19.03.2013

Usertfwr уже дал хороший ответ, но я хотел бы дать другую версию решения, которая может помочь вам кодировать приложения CPLEX более общим способом. Во-первых, я бы посоветовал вам использовать текстовый файл для хранения всех данных (коэффициентов целевой функции), которые будут загружены в программу. В вашем случае вам нужно всего лишь буквально скопировать следующую матрицу, например данные, в блокнот и назвать ее «coef.dat»:

[1000, 2000, 500, 1500]

Теперь идет полный код, дайте мне знать, если возникнут трудности с пониманием какого-либо утверждения:

  #include <ilcplex/ilocplex.h>
  #include <fstream>
  #include <iostream>
  ILOSTLBEGIN

  int main(int argc, char **argv) {
    IloEnv env; 
    try {
        const char* inputData = "coef.dat";

        ifstream inFile(inputData);   // put your data in the same directory as your executable
        if(!inFile) {
            cerr << "Cannot open the file " << inputData << " successfully! " <<endl;
            throw(-1);
        }

        // Define parameters (coef of objective function)
        IloNumArray a(env); 

        // Read in data
        inFile >> a; 

        // Define variables 
        IloBoolVarArray p(env, a.getSize());  // note that a.getSize() = 4 
        IloArray<IloBoolVarArray> X(env, 5);  // note that you need a 5x4 X variables, not 4x5
        for(int i = 0; i < 5; i++) {
            X[i] = IloBoolVarArray(env,4);
        }

        // Build model
        IloModel model(env);

        // Add objective function 
        IloExpr  objFun (env); 
        for(int i = 0; i < a.getSize(); i++){
            objFun += a[i]*p[i];
        }

        model.add(IloMaximize(env, objFun));  

        objFun.end();  

        // Add constraints -- similar to usertfwr’s answer
        for(int i = 0; i < 4; k++){
            IloExpr sumConst (env);
            for(int j = 0; j < 5; i++){
                    sumConst += x[j][i];
            }
            // before clearing sumConst expr, add it to model
            model.add(sumConst >= 2*p[i]);
            sumConst.end(); // very important to end after having been added to the model
        }

        // Extract the model to CPLEX 
        IloCplex cplex(mod);

        // Export the LP model to a txt file to check correctness
        //cplex.exportModel("model.lp");

        // Solve model 
        cplex.solve();

    }
    catch (IloException& e) {
        cerr << "Concert exception caught: " << e << endl;
    }
    catch (...) {
           cerr << "Unknown exception caught" << endl;
    }
        env.end();
}
person Deanna1125    schedule 13.02.2015
comment
Что вы имеете в виду под ILOSTBEGIN? - person Willem Van Onsem; 13.02.2015
comment
Этот макрос определен в ilconcert/ilosys.h как использующий пространство имен std. Таким образом, это позволит вам запускать ваше приложение с помощью STL C++. - person Deanna1125; 15.02.2015