Понимание формата ввода ограничения Geost Minizincs

Я пытаюсь понять ограничение MiniZincs geost, которое описано в раздел ограничений упаковки в документации. Я пытаюсь реализовать 2D-упаковку прямоугольников с вращением: поэтому я хотел бы разместить прямоугольники на пластине заданной длины и ширины, но мне трудно понять ожидаемый формат ввода. .

У меня есть следующая модель, где я читаю количество частей или прямоугольников, которые нужно поместить в nParts. nShapes - количество форм, которые могут принимать эти прямоугольники.

include "globals.mzn";

int: nParts;
set of int: PARTS = 1..nParts;

int: nShapes; 
set of int: SHAPES = 1..nShapes;

int: plateLength;
int: plateWidth;

set of int: LEN = 0..plateLength;
set of int: WID = 0..plateWidth;

int: k = 2;
set of int: DIM = 1..k;

array[SHAPES,DIM] of int: rect_size;
array[SHAPES,DIM] of 0..0: rect_offset;
array[PARTS] of set of SHAPES: shape;

array[PARTS,DIM] of var int: xy;
array[PARTS] of var SHAPES: kind;

constraint geost(k, rect_size, rect_offset, shape, xy, kind);

constraint forall(i in PARTS)(kind[i] in shape[i]);

constraint forall(i in PARTS)(xy[i,1] in LEN);
constraint forall(i in PARTS)(xy[i,1] + rect_size[kind[i], 1] in LEN);

constraint forall(i in PARTS)(xy[i,2] in WID);
constraint forall(i in PARTS)(xy[i,2] + rect_size[kind[i], 2] in WID);

Данная модель, кажется, работает для этих чрезвычайно простых данных (размещение только одного прямоугольника с двумя возможными формами):

plateLength = 4000;
plateWidth = 4000;

nParts = 1;
nShapes = 2;

rect_size = [|4000, 2000|
2000, 4000|];
rect_offset = [|0, 0|
0, 0|];

shape = [{1,2}];

Тем не менее, для более сложных данных я сталкиваюсь с ошибками, что приводит к выводу, что мое понимание формата ввода может быть неправильным. В следующем примере я хочу разместить 5 частей на пластине и ожидать такого результата: первый прямоугольник может принимать форму [4000, 2000] или [2000, 4000] и поэтому индексируется через {1, 2}, второй прямоугольник может иметь форму [2000, 2000] и индексируется через {3}.

введите здесь описание изображения

plateLength = 4000;
plateWidth = 4000;

nParts = 5;
nShapes = 7;

rect_size = [|4000, 2000|
2000, 4000|
2000, 2000|
1000, 2000|
2000, 1000|
500, 1000|
1000, 500|];
rect_offset = [|0, 0|
0, 0|
0, 0|
0, 0|
0, 0|
0, 0|
0, 0|];

shape = [{1,2}, {3}, {4,5}, {6,7}, {6,7}];

Эта спецификация верна? Если нет, как я могу правильно указать ввод для ограничения геостационизма? Также поможет простой пример, я нашел только довольно сложные здесь и здесь.


person Phonolog    schedule 10.03.2020    source источник


Ответы (1)


Глобальное ограничение geost неперекрытия для k размерных объектов требует, чтобы никакие два объекта не перекрывались. Его двоюродный брат geost_bb дополнительно ограничивает объекты, чтобы они вписывались в глобальную k размерную ограничивающую рамку.


Допустим, мы хотим найти подходящее размещение на 2D-плоскости для следующих трех объектов:

введите здесь описание изображения

Допустим, мы можем повернуть каждый объект на 90 ° (или его кратное количество), тогда наша задача состоит в том, чтобы найти подходящее размещение на 2D-плоскости для 3 объектов, которые могут принимать одну из следующих 10 форм:

введите здесь описание изображения

(Обратите внимание, что нам нужно учитывать только два возможных поворота для второго объекта.)

Теперь давайте посмотрим на определение geost_bb ограничение:

constraint
    geost_bb(
        k,              % the number of dimensions
        rect_size,      % the size of each box in k dimensions
        rect_offset,    % the offset of each box from the base position in k dimensions
        shape,          % the set of rectangles defining the i-th shape
        x,              % the base position of each object.
                        % (var) x[i,j] is the position of object i in dimension j
        kind,           % (var) the shape used by each object
        l,              % array of lower bounds
        u               % array of upper bounds
    );

Все, кроме x, kind, l, u, является входом для ограничения. Матрица x определяет левую нижнюю координату (наименьшей) прямоугольной выпуклой оболочки, охватывающей каждый объект i. Вектор kind определяет форму данного объекта i. Векторы l и u определяют ограничения нижней и верхней границы для каждого k измерения N-мерной прямоугольной выпуклой оболочки, охватывающей все объекты в задаче.

Форма задается составом набора прямоугольников. Каждый прямоугольник уникально идентифицируется своим размером и смещением относительно него. нижняя левая координата в соответствующей фигуре.

Обратите внимание, что может быть несколько способов разложить коллекцию фигур на коллекцию прямоугольников. Как показывает практика, всегда рекомендуется использовать как можно меньше прямоугольников.

Это возможное разложение для нашего текущего примера (прямоугольники с одинаковым размером и смещением имеют одинаковый цвет):

введите здесь описание изображения

Закодируем этот пример в Minizinc.

Начнем с объявления входных параметров и выходных переменных нашей задачи:

int: k;
int: nObjects;
int: nRectangles;
int: nShapes; 

set of int: DIMENSIONS = 1..k;
set of int: OBJECTS    = 1..nObjects;
set of int: RECTANGLES = 1..nRectangles;
set of int: SHAPES     = 1..nShapes;

array[DIMENSIONS] of int:             l;
array[DIMENSIONS] of int:             u;
array[RECTANGLES,DIMENSIONS] of int:  rect_size;
array[RECTANGLES,DIMENSIONS] of int:  rect_offset;
array[SHAPES] of set of RECTANGLES:   shape;
array[OBJECTS,DIMENSIONS] of var int: x;
array[OBJECTS] of var SHAPES:         kind;
  • Количество размеров для 2D-плоскости равно 2, поэтому k равно 2;
  • Количество объектов 3, поэтому nObjects равно 3;
  • Количество уникальных прямоугольников, необходимых для создания всех фигур в задаче, равно 13, поэтому nRectangles равно 13;
  • Количество фигур равно 10, поэтому nShapes равно 10;

Следовательно, мы пишем:

k = 2;                  % Number of dimensions for a 2D Plane
nObjects = 3;           % Number of objects
nRectangles = 13;       % Number of rectangles
nShapes = 10;           % Number of shapes

Начиная с правого верхнего угла, мы определяем размер и смещение 13 прямоугольников, которые нам нужны, следующим образом:

rect_size = [|
     4, 2|
     2, 4|
     4, 2|
     2, 4|

     1, 2|
     2, 1|
     1, 2|
     2, 1|

     2, 1|
     1, 2|

     1, 1|
     1, 1|
     1, 1|];

rect_offset = [|
     0, 0|
     0, 0|
     0, 2|
     2, 0|

     2, 2|
     2, 1|
     1, 0|
     0, 2|

     0, 0|
     0, 0|

     0, 1|
     1, 1|
     0, 0|];

Теперь мы можем определить 10 формы, которые нам нужны, в терминах данного списка или прямоугольников:

shape = [
    { 1, 5 },
    { 2, 6 },
    { 3, 7 },
    { 4, 8 },

    { 9 },
    { 10 },

    { 9, 11 },
    { 10, 12 },
    { 7, 11 },
    { 7, 13 }
];

Мы требуем, чтобы решение проблемы размещало все объекты в квадрате 4x4, помещенном в начало координат:

l = [0, 0];
u = [4, 4];

Чтобы завершить этот пример, нам нужно дополнительное ограничение, чтобы гарантировать, что каждому объекту назначена допустимая форма из доступных:

array[OBJECTS] of set of SHAPES: valid_shapes;

valid_shapes = [{1, 2, 3, 4}, {5, 6}, {7, 8, 9, 10}];

constraint forall (obj in OBJECTS) (
    kind[obj] in valid_shapes[obj]
);

...

solve satisfy;

Возможное решение этой тривиальной проблемы:

x = array2d(1..3, 1..2, [0, 0, 0, 3, 0, 0]);
kind = array1d(1..3, [4, 5, 7]);
----------

Графически решение:

введите здесь описание изображения


Ты спрашиваешь:

Эта спецификация верна?

Нет. Очевидным источником путаницы является определение формы. Приведенное выше объяснение должно прояснить этот аспект.

person Patrick Trentin    schedule 12.03.2020
comment
Большое спасибо за исчерпывающее объяснение! Это определенно объясняет мое замешательство. Надо подумать о создании версии, которая не требует разных ограничений для разных наборов данных, но это не должно быть слишком сложно реализовать. - person Phonolog; 12.03.2020
comment
@Phonolog, какое ограничение для вас проблематично? - person Patrick Trentin; 12.03.2020
comment
Ограничения типа constraint kind[1] in { 1 , 2, 3, 4 }; могут быть разными для каждого набора данных, если я хочу решить разные проблемы упаковки с одной и той же моделью ... - person Phonolog; 12.03.2020
comment
@Phonolog а, это просто я ленился. Я обновил ответ с лучшей кодировкой. В случае, если у вас есть много объектов одного типа (с одинаковыми допустимыми формами), вы можете дополнительно уточнить его, введя массив object_type, который будет действовать как посредник между фактическим экземпляром obj и содержимым valid_shapes. - person Patrick Trentin; 12.03.2020
comment
Да, определение массива допустимых форм звучит как решение этой проблемы. Еще раз большое спасибо :) - person Phonolog; 12.03.2020
comment
@CarlS. Вы можете задать новый вопрос для видимости. У меня нет времени отвечать сейчас, но другие могут. Будет ли решение содержать переменное количество прямоугольников? Важно ли рассматривать прямоугольники как вращение или, в вашем случае, можно ли их рассматривать как разные прямоугольники? Возможно, проблема не требует геоста, если это так. - person Patrick Trentin; 07.04.2021