Ограничение Minizinc против рекурсивной функции

Я хочу использовать такую ​​функцию:

function int: nextr(var int: n)
if n <= 1
  2
elseif n <= 8
  n + 5
elseif n <= 68
  n + 13
elseif n <= 509
  n + 34
elseif n <= 3611
  n + 89
else n + 233

в ограничении эта переменная должна удовлетворять любому значению в nextr (n), nextr (nextr (n)), nextr (next (nextr (n))) и т. д.

Есть ли способ указать такое ограничение в minizinc? Если это вообще невозможно, я в порядке с явным ограничением рекурсии, но без утомительного перечисления всех шагов?


person Juraj    schedule 05.11.2019    source источник


Ответы (1)


Пример:

Значение y ограничено, чтобы быть равным

next(x) \/ next(next(x)) \/ ...

до K уровней вложенности.

function var int: nextr(var int: n) =
  if n <= 1 then
    2
  elseif n <= 8 then
    n + 5
  elseif n <= 68 then
    n + 13
  elseif n <= 509 then
    n + 34
  elseif n <= 3611 then
    n + 89
  else
    n + 233
  endif;

int: K = 10;

var int: x;
var int: y;
array[1..K] of var int: rec_up_to_k;

constraint forall (i in 1..K) (
  if i == 1 then
    rec_up_to_k[i] = nextr(x)
  else
    rec_up_to_k[i] = nextr(rec_up_to_k[i-1])
  endif
);

constraint exists (i in 1..K) (
  y = rec_up_to_k[i]
);

constraint x >= 0;

solve satisfy;

выходы:

x = 3612;
y = 3845;
rec_up_to_k = array1d(1..10, [3845, 4078, 4311, 4544, 4777, 5010, 5243, 5476, 5709, 5942]);
----------
person Patrick Trentin    schedule 05.11.2019
comment
Я не голосовал, поскольку не вижу ответа на вопрос: как выразить ограничение, позволяющее переменной быть nextr (n) или nextr (nextr (n)) или nextr (next (nextr (n))) или. ...так далее... - person Juraj; 06.11.2019
comment
ограничение z = nextr (y) / \ y = nextr (x) / \ x ›= 0 - это всего 2 итерации, мне нужно их любое количество, не выписывая их все вот так. - person Juraj; 06.11.2019
comment
@Juraj Я неправильно понял вопрос, посмотрим, подходит ли он сейчас вашим потребностям. - person Patrick Trentin; 06.11.2019