Перемешать список в Minizinc

array[1..6] of var 0..1: Path;
include "alldifferent.mzn";
constraint
forall(j in 1..6)(
alldifferent(i in 1..6)(Path[i])
)

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

Path = array1d(1..6, [5, 4, 3, 2, 1, 0]);

person Learner Minizinc    schedule 23.10.2020    source источник
comment
Если вы позволите MiniZinc отображать все решения (с флагом -a при запуске из командной строки), вы получите все 5040 различных решений. Это не решает вашу проблему? Или вы имеете в виду что-то другое под перемешиванием? Кстати можно просто написать all_different(Path).   -  person hakank    schedule 23.10.2020
comment
еще раз спасибо за ваш ответ. Я хочу 6 раз перетасовать список массивов с 0,1. пример [0,0,0,0,0,1] [0,0,0,0,1,0] [0,0,0,1,0,0] .. и так далее ...   -  person Learner Minizinc    schedule 23.10.2020
comment
Вы имеете в виду случайную матрицу 6x6 из {0,1} значений? Иначе я не понимаю тасования 6 раз.   -  person hakank    schedule 23.10.2020
comment
Пожалуйста, будьте более конкретными. В вашем основном вопросе, о значениях в домене 0..5, теперь вы спрашиваете о значениях 0..1.   -  person hakank    schedule 23.10.2020
comment
мои извенения! Это была ошибка. да всего 0,1   -  person Learner Minizinc    schedule 23.10.2020
comment
К сожалению, ответ еще не принят   -  person David Tonhofer    schedule 10.07.2021


Ответы (1)


Существует как минимум два подхода к генерации случайной матрицы в зависимости от того, хотите ли вы сгенерировать все возможные переменные (первая модель ниже с использованием значений решения) или если вам просто нужна случайная случайная матрица (вторая модель, использующая встроенную случайный генератор). (Третий подход - написать собственный генератор случайных чисел, но это оставлено как упражнение :-)).

Вот простая модель MiniZinc, которая генерирует все возможные матрицы 6x6 из {0,1} в качестве переменных решения.

int: n = 6;
array[1..n,1..n] of var 0..1: x;
solve :: int_search(array1d(x), first_fail, indomain_random) satisfy;

constraint
  true
;

output
[
   if j = 1 then "\n" else " " endif ++
      show(x[i,j])
   | i,j in 1..n        
];

Примечание. Эвристика indomain_random генерирует решения в более случайном порядке.

Есть другой способ сделать это, используя функцию bernoulli(0.5), которая случайным образом генерирует 0 или 1 во время создания модели, т.е. это не переменные решения:

int: n = 6;
array[1..n,1..n] of int: x = array2d(1..n,1..n,[ bernoulli(0.5) | i,j in 1..n]);

solve satisfy;

constraint
  true
;

output
[
  if j = 1 then "\n" else " " endif ++
    show(x[i,j])
  | i,j in 1..n        
];

В результате получается следующая матрица:

1 1 1 0 0 0
1 0 1 1 0 0
0 0 0 0 1 1
0 1 0 0 1 0
1 1 1 1 0 1
0 1 1 1 1 1

Недостатком этого является то, что вам придется вручную запускать генератор случайных чисел для генерации различных матриц. Это (согласно https://www.minizinc.org/doc-2.5.1/en/command_line.html?highlight=random#cmdoption-r) сделано с флагом --random-seed i (или -r i), но сейчас это не работает на моем Версия MiniZinc.

MiniZinc имеет довольно много генераторов случайных чисел, подробнее см. Здесь: https://www.minizinc.org/doc-2.5.1/en/lib-stdlib.html?highlight=random#random-number-generator-builtins.

person hakank    schedule 23.10.2020
comment
Спасибо большое за вашу помощь! Удивительный! это то, что я искал! :) - person Learner Minizinc; 23.10.2020
comment
Замечательно. Если вас устраивает мой ответ, установите для него значение "Принято". - person hakank; 23.10.2020
comment
@LearnerMinizinc, поскольку ответ решил вашу проблему, примите его - см. Что мне делать, когда кто-то ответит на мой вопрос? - person desertnaut; 23.02.2021