Есть ли способ поменять местами столбцы двумерного массива (матрицы) в MiniZin c и отслеживать это? - PullRequest
1 голос
/ 19 апреля 2020

Я сейчас работаю над MiniZin c.

Я получил следующий 2d массив (матрицу):

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

Предположим, что он имеет некоторый порядок. Самый первый столбец слева - первый, следующий справа - второй, и так далее, например:

1  2  3  4  5  6
----------------
0  1  0  0  0  0 
0  1  1  1  0  1 
0  0  0  0  1  1

Мне нужен способ (например, ограничение или что-то), который помогает мне уменьшить расстояние между самой первой 1 в ряду и последней 1 в той же строке. Например, идеальной матрицей для этого является:

1  2  3  4  6  5
----------------
0  1  0  0  0  0 
0  1  1  1  1  0 
0  0  0  0  1  1

Как вы можете видеть, это путем замены столбца 5 и столбца 6 каждый. Но я не знаю, как это сделать, и отслеживать порядок, зная, что первая матрица имеет [1 2 3 4 5 6], а вторая - [1 2 3 4 6 5]

Я действительно не знаю, как смоделировать такие столбцы в массиве 2d переменных.

Спасибо за помощь!

1 Ответ

4 голосов
/ 19 апреля 2020

Вот простой способ: допустим, ваша исходная матрица данных data. Вы можете использовать массив (скажем, x), чтобы отслеживать новый порядок столбцов. Для использования нового заказа вы используете data[row,x[col]], например

 [data[row,x[col]] | row in 1..num_rows, col in 1..num_cols]

Вот небольшой пример этого. Обратите внимание, что вы должны добавить ограничения на x, чтобы сделать его более интересным.

include "globals.mzn"; 
int: num_rows;
int: num_cols;
array[1..num_rows, 1..num_cols] of int: data;

% decision variables
array[1..num_cols] of var 1..num_cols: x; 

solve satisfy;

constraint
  all_different(x)
  % /\ more constraints on x  ....
;

output [
    "data:\n",
    show2d(data) ++ "\n" ++ 
    "x: \(x)\n",
    "new_data:\n",
    show2d(array2d(1..num_rows, 1..num_cols, [data[i,x[j]] | i in          1..num_rows,j in 1..num_cols])) ++ "\n"
];

% data
num_rows = 3;
num_cols = 6;
data = array2d(1..num_rows,1..num_cols,
  [
  0,1,0,0,0,0,
  0,1,1,1,0,1,
  0,0,0,0,1,1
  ]);

Одним из решений является:

 data:
 [| 0, 1, 0, 0, 0, 0 |
    0, 1, 1, 1, 0, 1 |
    0, 0, 0, 0, 1, 1 |]

 x: [3, 1, 4, 5, 2, 6]
 new_data:
 [| 0, 0, 0, 0, 1, 0 |
    1, 0, 1, 0, 1, 1 |
    0, 0, 0, 1, 0, 1 |]
...