Преобразование модели MiniZinc в шоколадный код

Моя модель minizinc работает нормально, но мне нужно преобразовать ее в код Java, поэтому я использовал choco для этого. Проблема, с которой я столкнулся прямо сейчас, заключается в том, что механизм, с которым работает minizinc, отличается от choco. Я написал ограничения, которые использовал в minizinc, точно в choco, но это не сработало.

Предположим, что :

Модель minizinc это:

array[sub_set] of var cl_set: cl_id;
constraint alldifferent(cl_id);
constraint forall(i in sub_set) ( sub_cap[i] <= cl_cap[cl_id[i]]);

код choco:

cl_id = VF.boundedArray("", sub_sz, 0, cl_sz - 1, solver);
solver.post(ICF.alldifferent(cl_id));
for (int i = 0; i < sub_sz; i++) {
     Constraint a = ICF.arithm(VF.fixed(cl_cap[cl_id[i].getValue()], solver), ">=", sub_cap[i]);
      solver.post(a);
        }
  • Cl_cap - это массив int.
  • cl_id[i].getValue() всегда равен 0, потому что он получает нижнюю границу домена и ограничение не применяется к cl_id

Что мне делать, чтобы ограничение choco работало так же, как minizinc?


person Abdelhamid Nour    schedule 20.04.2016    source источник
comment
Непонятно, что делает модель MiniZinc, поскольку определение cl_cap не показано. Но проблема, похоже, в том, что вы используете .getValue в ограничении, которое выбирает значение (здесь, по-видимому, 0). Возможно, вам придется использовать ограничение элемента (choco-solver.org/user_guide/5_elements.html #element), чтобы извлечь значение cl_cap в позиции cl_id [i] (которая является переменной решения). Такие ограничения легче установить в MiniZinc.   -  person hakank    schedule 20.04.2016
comment
Решатель решателя = новый Решатель (); int [] a = новый int [] {30,70,50}; int [] b = новый int [] {50,30,80}; IntVar [] idx = VF.boundedArray (, 3, 0, 2, решатель); solver.post (ICF.alldifferent (idx)); for (int i = 0; i ‹3; i ++) {IntVar x = VF.fixed (b [idx [i] .getValue ()], решатель); solver.post (ICF.arithm (x, ›, a [i])); } solver.findSolution (); для (int i = 0; i ‹3; i ++) {System.out.println (idx [i] .getValue ()); } b [idx [i] .getValue ()] всегда 0, потому что еще не инициализирован. Как я пишу код для этого.   -  person Abdelhamid Nour    schedule 20.04.2016
comment
Что ж, переменные решения не будут инициализированы (или присвоены) никакими значениями перед поисковой частью модели. Как я упоминал ранее, вы должны использовать ограничение элемента для извлечения значения idx [i], чтобы получить индекс в b. (MiniZinc имеет гораздо лучший синтаксис для ограничения элемента, поэтому этот шаг может быть сложно описать в других системах CP.) См. Пример на странице, на которую я ссылался ранее.   -  person hakank    schedule 20.04.2016
comment
Choco может решать проблемы, закодированные как файлы FlatZinc. Возможно, стоит использовать промежуточный файл FlatZinc для MiniZinc и загрузить его в Choco.   -  person Axel Kemper    schedule 21.04.2016
comment
Я решил свою проблему, теперь у меня есть еще одна, когда я запускаю свою модель в minizinc IDE для конкретных данных, дает решения около 10 мс, но когда я запускаю свою модель с помощью команд командной строки, требуется много времени, если она дает решения, отличные от minizinc IDE, или он не дает решений для всех моих команд, которые я использую, как показано ниже: cd C: \ Program Files \ MiniZinc IDE (в комплекте) minizinc.exe MinizincCode.mzn   -  person Abdelhamid Nour    schedule 22.04.2016


Ответы (1)


Как сказал Хаканк, вам нужно элементное ограничение Choco Solver. Его синтаксис: element(IntVar VALUE, int[] TABLE, IntVar INDEX), что означает VALUE = TABLE[INDEX].

Это дает что-то вроде:

for (int i = 0; i < sub_sz; i++) {

    solver.post(ICF.element(VF.bounded(sub_cap[i], cl_sz - 1, solver), cl_cap, cl_id[i]));
}

Вы не можете использовать getValue(), потому что на этом этапе проблема еще не решена (getValue() выдает исключение, когда -ea передается аргументам JVM или возвращает текущую переменную LOWER BOUND, поэтому вы получаете 0).

person Jean-Guillaume Fages    schedule 21.04.2016