0

Use CLINGO to pack a given set of squares into a given rectangular area without overlaps. For example, we want to pack the squares:

A of size 4, B of size 3, C & D of size 2, E of size 1

into an area 5 x 8.

 #const x = 8.
  #const y = 5.

square(a,4; b,3; c,2; d,2; e,1).

%generate a grid:
1 { pos(X,Y) } 1 :- x(X), y(Y).

%generate placement of the squares
1 { placement(P, SQ) } 1 :- square(SQ), pos(P).

%throw out overlaps

I'm not sure what the constraint to throwing out overlapping squares would be, or if I'm doing this right.

1010101
  • 51
  • 1
  • 1
  • 4

1 Answers1

0

Fix the code

The grid generation does not yield expected atoms. Here is the one you want:

pos(1..x,1..y).

Also, the placement of squares says: placement/2 holds for any pair square×position. Instead, we want to associate a position to each square:

1 {placement(pos(X,Y),S): pos(X,Y)} 1:- square(S,_).

Now we have to design the overlapping constraints.

Solution to the problem.

First, we define occupy/3, where occupy(S,X,Y) holds when square S occupy the grid at position (X,Y):

occupy(S,X+I,Y+J):- square(S,Size) ; placement(pos(X,Y),S) ; I=0..Size-1 ; J=0..Size-1.

For instance, square(a,2). placement(a,pos(1,3)). will be associated with occupy(a,1,3).occupy(a,1,4).occupy(a,2,3).occupy(a,2,4)..

Then, we discard any model that have more than more than one occupy at a given position:

:- {occupy(_,X,Y)}>1 ; occupy(_,X,Y).

Fix: you must also discard models where a square is placed so it occupy a non existing place:

:- occupy(_,X,Y) ; not pos(X,Y).
aluriak
  • 5,559
  • 2
  • 26
  • 39