首页 > 解决方案 > 如何在 cplex/c++ 中更改约束的左侧?

问题描述

我能做些什么来改变约束子集的左侧?

例如,我有以下约束集:

typedef struct{
  IloCplex cplex;
  IloEnv env;
  IloModel mod;
  IloNumVarArray f;
  IloNumArray _f;
  IloRangeArray constraints_r1c;
  IloObjective fo;
  IloNum _fo;
} CPX_RHLPflow;

struct DATA {

  int n;
  vector<vector<vector<int> > > _x;
  int p;

};

int MAPf (int router, int nodei, int nodej, int nodeu, int nodev, int N) { 
  return router*N*N*N*N+nodei*N*N*N+nodej*N*N+nodeu*N+nodev;
}


void create_model_RHLPflow(CPX_RHLPflow &mono, DATA data){


  IloEnv& env = mono.env;
  mono.mod = IloModel(env);
  mono.cplex = IloCplex(mono.mod);

  int sizef = data.p*data.n*data.n*data.n*data.n;
  mono.f = IloNumVarArray(env, sizef, 0.0, +IloInfinity, ILOFLOAT);
  mono._f = IloNumArray(env,sizef);


  mono.constraints_r1c = IloRangeArray(env);

  char name[50];
  for (int i = 0; i < data.n; i++) {
    for (int j = 0; j < data.n; j++) {
        if (i != j) {
          IloExpr r_1c(env);
          for (int k = 0; k < data.n; k++) {
              if (k != j) {
                  for (int p = 0; p < data.p; p++) {
                      if (data._x[p][k][j] == 1) {
                          r_1c += mono.f[MAPf(p,i,j,k,j,data.n)];
              sprintf(name, "f(%d,%d,%d,%d,%d)",p,i,j,k,j);
                          mono.f[MAPf(p,i,j,k,j,data.n)].setName(name);
                      }
                  }
               }
          }
          IloRange ctr;
          ctr = (1 <= r_1c <= 1);
      sprintf(name, "r1c_%d_%d",i,j);
          ctr.setName(name);
          mono.constraints_r1c.add(ctr);
          r_1c.end();
      }
    }
  }   

  mono.mod.add(mono.constraints_r1c);

}

int main(int argc, char* argv[]) {

  CPX_RHLPflow mono;

  DATA data;
  data.n = 5;
  data.p = 3;

  data._x = vector<vector<vector<int> > > (data.p, vector<vector<int> > (data.n, vector<int> (data.n,0)));

  data._x[0][0][1] = 1;
  data._x[0][1][3] = 1;
  data._x[0][3][4] = 1;
  data._x[0][4][0] = 1;

  data._x[1][2][4] = 1;
  data._x[1][4][3] = 1;
  data._x[1][3][2] = 1;


  data._x[2][1][2] = 1;
  data._x[2][2][3] = 1;
  data._x[2][3][4] = 1;
  data._x[2][4][1] = 1;

  cout << "oi" << endl;

  create_model_RHLPflow (mono, data);

  char name[50];
  sprintf(name, "ModelBeforeModification.lp");
  mono.cplex.exportModel(name);

  data._x[1][2][4] = 0;
  data._x[1][4][3] = 0;
  data._x[1][3][2] = 0;

  data._x[1][2][3] = 1;
  data._x[1][3][1] = 1;
  data._x[1][1][4] = 1;
  data._x[1][4][2] = 1;

  return 0;

}

在每次迭代中,对于 的特定值 p,参数的值会data._x[p][k][j]发生变化。

因此,f要添加到子集左侧的变量contraints_r1c(具有相应的变量p)也必须更改。我该如何进行此修改?

谢谢!

标签: c++constraintscplex

解决方案


I found out how to do what I was trying and I thought it'd be great to share here.

void ModifyModel (CPX_RHLPflow &mono, DATA data) {

  char name[50];

  int cont = 0;
  for (int i = 0; i < data.n; i++) {
      for (int j = 0; j < data.n; j++) {
          if (i != j) {
              IloExpr r_1c(mono.cplex.getEnv());
              for (int k = 0; k < data.n; k++) {
                  if (k != j) {
                      for (int p = 0; p < data.p; p++) {
                          if (data._x[p][k][j] == 1) {
                              r_1c += mono.f[MAPf(p,i,j,k,j,data.n)];
                  sprintf(name, "f(%d,%d,%d,%d,%d)",p,i,j,k,j);
                              mono.f[MAPf(p,i,j,k,j,data.n)].setName(name);
              }
              }
          }
          }
              mono.constraints_r1c[cont].setExpr(r_1c);
              cont += 1;
      }
      }
  }

  sprintf(name, "ModelAfterModification.lp");
  mono.cplex.exportModel(name);

}

推荐阅读