Prolog Constraint Processing : Packing Squares

前端 未结 5 1270
误落风尘
误落风尘 2020-12-06 03:49

I\'m trying to solve a constraint processing problem in prolog.

I need to pack 4 squares of 5x5,4x4,3x3 and 2x2 in a grid of 10x10. They may not overlap.

My

5条回答
  •  暖寄归人
    2020-12-06 04:44

    I coded in SWI-Prolog

    /*  File:    pack_squares.lp
        Author:  Carlo,,,
        Created: Nov 29 2012
        Purpose: http://stackoverflow.com/questions/13623775/prolog-constraint-processing-packing-squares
    */
    
    :- module(pack_squares, [pack_squares/0]).
    :- [library(clpfd)].
    
    pack_squares :-
        maplist(square, [5,4,3,2], Squares),
        flatten(Squares, Coords),
        not_overlap(Squares),
        Coords ins 1..10,
        label(Coords),
        maplist(writeln, Squares),
        draw_squares(Squares).
    
    draw_squares(Squares) :-
        forall(between(1, 10, Y),
               (   forall(between(1, 10, X),
                  sumpts(X, Y, Squares, 0)),
               nl
               )).
    
    sumpts(_, _, [], S) :- write(S).
    sumpts(X, Y, [[X1,Y1, X2,Y2]|Qs], A) :-
        ( ( X >= X1, X =< X2, Y >= Y1, Y =< Y2 )
        ->  B is A+X2-X1+1
        ;   B is A
        ),
        sumpts(X, Y, Qs, B).
    
    square(D, [X1,Y1, X2,Y2]) :-
        X1 + D - 1 #= X2,
        Y1 + D - 1 #= Y2.
    
    not_overlap([_]).
    not_overlap([A,B|L]) :-
        not_overlap(A, [B|L]),
        !, not_overlap([B|L]).
    
    not_overlap(_, []).
    not_overlap(Q, [R|Rs]) :-
        not_overlap_c(Q, R),
        not_overlap_c(R, Q),
        not_overlap(Q, Rs).
    
    not_overlap_c([X1,Y1, X2,Y2], Q) :-
        not_inside(X1,Y1, Q),
        not_inside(X1,Y2, Q),
        not_inside(X2,Y1, Q),
        not_inside(X2,Y2, Q).
    
    not_inside(X,Y, [X1,Y1, X2,Y2]) :-
        X #< X1 #\/ X #> X2 #\/ Y #< Y1 #\/ Y #> Y2.
    

    here is the last lines displayed when running ?- aggregate_all(count,pack_squares,C)., notably C counts total placements

    ...
    0002255555
    0002255555
    [6,6,10,10]
    [7,2,10,5]
    [4,3,6,5]
    [5,1,6,2]
    0000220000
    0000224444
    0003334444
    0003334444
    0003334444
    0000055555
    0000055555
    0000055555
    0000055555
    0000055555
    C = 169480.
    

提交回复
热议问题