Cplex объективная функция в реализации java (затмение) - PullRequest
0 голосов
/ 21 апреля 2020

Это моя объективная функция в cplex:

минимизировать сумму (j в horas, k в trabajos) ((1 / prioridad [j] [k]) * (сумма (i в персонах) x [ i] [j] [k] - min_demanda [j] [k]));

, и вот как я пытался сделать это в java, но это не работает хорошо (объективное значение ноль и вся переменная x [] [] [] тоже, поэтому в этом случае она должна быть отрицательной, потому что есть термин -min_demanda [j] (не нуль)):

                double valorFuncionObjetivo = 0;
                IloCplex cplex = new IloCplex();

                IloNumVar[][][] x = new IloNumVar[Map.NumPersM][Map.NumHrsM][Map.NumTrab];

                for (int i = 0; i < Map.NumPersM; i++) {
                    for (int j = 0; j < Map.NumHrsM; j++) {
                        for (int k = 0; k < Map.NumTrab; k++) {

                        x[i][j][k] = cplex.boolVar();
                        }
                    }
                }
                //cplex.setParam(IloCplex.Param.Preprocessing.Presolve, false);

                // Model            
                IloLinearNumExpr funcion_objetivo = cplex.linearNumExpr();

                for (int j = 0; j < Map.NumHrsM; j++) {
                     for (int k = 0; k < Map.NumTrab; k++) {
                          for (int i = 0; i < Map.NumPersM; i++) {

                                funcion_objetivo.addTerm(x[i][j][k],Map.Demandas[j][k].Prioridad);
                          }
                       funcion_objetivo.setConstant(-(Map.Demandas[j][k].Prioridad)*Map.Demandas[j][k].Min_personas);  
                     }
                } 

                cplex.addMinimize( funcion_objetivo);

1 Ответ

2 голосов
/ 21 апреля 2020

Существует проблема с тем, как вы устанавливаете постоянный термин в своей цели. Ваш код:

for (int j = 0; j < Map.NumHrsM; j++) {
  for (int k = 0; k < Map.NumTrab; k++) {
    for (int i = 0; i < Map.NumPersM; i++) {
      funcion_objetivo.addTerm(x[i][j][k],Map.Demandas[j][k].Prioridad);
    }
    funcion_objetivo.setConstant(-(Map.Demandas[j][k].Prioridad)*Map.Demandas[j][k].Min_personas);  
  }
}

Так что в каждой итерации j / kl oop вы перезаписываете постоянный член. Если последний член окажется равным 0, то постоянный член в цели будет равен 0. Возможно, вы хотите суммировать константу следующим образом (я добавил funcion_objectivo.getConstant()):

for (int j = 0; j < Map.NumHrsM; j++) {
  for (int k = 0; k < Map.NumTrab; k++) {
    for (int i = 0; i < Map.NumPersM; i++) {
      funcion_objetivo.addTerm(x[i][j][k],Map.Demandas[j][k].Prioridad);
    }
    funcion_objetivo.setConstant(funcion_objectivo.getConstant() - (Map.Demandas[j][k].Prioridad)*Map.Demandas[j][k].Min_personas);  
  }
}

Также вы можете System.out.println(funcion_objective.getConstant()) чтобы дважды проверить, что постоянный член действительно ненулевой.

Я не уверен, является ли тот факт, что все переменные равны 0, является неожиданным или нет. Если это неожиданно, то вы, вероятно, пропускаете некоторые ограничения, которые требуют, чтобы переменные были ненулевыми. Хороший способ отладки - назначить имена вашим переменным и ограничениям (используйте функцию setName()), экспортируйте модель в формат файла LP, используя cplex.exportModel("model.lp"), а затем проверьте созданный файл model.lp в текстовом редакторе, чтобы сделать убедитесь, что все ограничения выглядят как ожидалось.

...