Minizin c: оптимальный порядок на столе - PullRequest
1 голос
/ 21 февраля 2020

У меня есть таблица с функциями = {A, B}. B является столбцом целых чисел. Сканируя таблицу, когда у меня есть изменение значения в столбце B, я увеличиваю переменную «изменения» на 1:

if data[i,B]!=data[i-1,B]
then changes=changes+1

Я хочу найти заказ, который минимизирует изменения и в то же время сохраняет повторение значения в B в [0, upper_bound]. Я думаю использовать массив в качестве переменной решения, где сохранить позицию j для элемента i:

order[i]=j means i element in data is the j-th element in ordering.

Как я могу моделировать с ограничением? Вот что я делаю до сих пор:

array[1..n, Features] of int: data;
int: changes=0;
constraint
   forall(i in 1..n) (
      if data[i,B] != data[i-1,B] then
        changes=changes+1
      endif
   )
;
minimize changes;

Я думаю, что я ошибаюсь, используя изменения в качестве постоянной переменной, верно? Заранее спасибо.

1 Ответ

3 голосов
/ 21 февраля 2020

В MiniZin c (и в программировании с ограничениями в целом) вы не можете увеличивать переменную как changes=changes+1).

Если changes является переменной, используемой только для общего количества изменений, вы можете использовать вместо нее сумму, например:

% ...
var 0..n: num_changes;
constraint
   changes = sum([data[i,B] != data[i-1,B] | i in 2..n])
;
% ...

Однако, если вы хотите использовать количество накопленных изменения для каждого i, затем вы должны создать массив изменений для сбора значений для каждого шага, например,

var[1..n-1] of var 0..n: changes;
% the total number of changes (to minimize)
var 0..n-1: total_changes = changes[n-1]; 
constraint
forall(i in 1..n-1) (
    if data[i,B] != data[i-1,B] then
       changes[i] = changes[i-1]+1
     else
       changes[i] = changes[i-1]    
    endif
)
;
...