Что использовать, чтобы избежать чрезмерной компенсации в многоцелевой модели в Cplex Java? - PullRequest
1 голос
/ 04 июля 2019

Я устанавливаю многоцелевую модель оптимизации с помощью Cplex в своем приложении Java.Однако, когда он решает модель, он компенсирует одну переменную, а остальные равны 0. Что я могу использовать, чтобы иметь более распределенное решение?

 int[] x = {49,43,43,44,48,49,51,54,51,52,57,59};
 double[] y = {10, 12, 13.2, 22.7, 17.1, 16.5, 14.87, 12, 16.5, 14.8, 12, 11.5};
int[] z = {59, 59, 57, 57, 53, 53, 52, 51, 51, 50, 50, 50};
int totalVacations = 73;

        try {
            IloCplex model = new IloCplex();
            int size = 12;
            IloNumVarType varType = IloNumVarType.Int;
            double[] lb = new double[size];
            double[] ub = new double[size];
            IloNumVarType[] varTypes = new IloNumVarType[size];
            for (int i = 0; i < lb.length ; i++) {
                lb[i] = 0.0;
                ub[i] = Double.MAX_VALUE;
                varTypes[i] = varType;
            }
            IloNumVar[] varUsed = model.numVarArray(size, lb, ub, varTypes);
            for (int i = 0; i < varUsed.length; i++) {
                model.add(varUsed[i]);
            }
            IloNumExpr[] objArray = new IloNumExpr[size];
            for (int i = 0; i < objArray.length; i++) {
                IloObjective next = model.maximize();
                IloNumExpr exprVar = varUsed[i];
                double setValue = z[i] - x[i] - y[i];
                next.setExpr(model.diff(setValue, exprVar));
                next.setSense(IloObjectiveSense.Maximize);
                objArray[i] = next.getExpr();
            }

            model.add(model.maximize(model.staticLex(objArray)));
            model.addEq(totalVacations, model.sum(varUsed), "c1");
            if (model.solve()) {
                double[] results = model.getValues(varUsed);
                for (int i = 0; i < results.length; i++) {
                    System.out.println(results[i]);
                }
            }
            System.out.println(model.toString());
            model.end();
        } catch (IloException e) {
            System.err.println("Concert exception caught: " + e);
        }

Значения: 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,00,0 0,0 73,0

Когда я хочу, чтобы оно было более распределенным (хотя и неравномерно).Любые рекомендации о том, что делать в этом случае?

1 Ответ

2 голосов
/ 04 июля 2019

Позвольте мне использовать OPL, чтобы показать вам, что делать:

Вы написали Java-эквивалент

int totalVacation=73;
range r=1..12;

int  x[r] = [49,43,43,44,48,49,51,54,51,52,57,59];
float y[r] = [10, 12, 13.2, 22.7, 17.1, 16.5, 14.87, 12, 16.5, 14.8, 12, 11.5];
float z[r] = [59, 59, 57, 57, 53, 53, 52, 51, 51, 50, 50, 50];

dvar int varUsed[r] in 0..totalVacation;

maximize sum(i in r) (z[i] - x[i] - y[i]-varUsed[i]);

subject to
{
c1:sum(i in r) varUsed[i]==totalVacation;
}

, который дает

varUsed = [73 0 0 0 0 0 0 0 0 0 0 0];

, потому что тамв объективе нет ничего о справедливости.

Но если вы измените цель с

maximize sum(i in r) (z[i] - x[i] - y[i]-varUsed[i]);

на

maximize staticLex(sum(i in r) (z[i] - x[i] - y[i]-varUsed[i]),
        -max(j in r) varUsed[j]+min(j in r) varUsed[j]);

Затем вы добавите вторую лексикографическую цель, чтобы максимизировать справедливостьи тогда вы получите

varUsed = [7 6 6 6 6 6 6 6 6 6 6 6];
...