我有一个nxn区域。并且我想列出在该区域中彼此不接触的可能kxk m个正方形(k 输入和输出应该是这样的:(k:小方块的大小,n:大方块的大小,m:小方块的数量)>func(k,n,m,O).
>func(1,3,2,O).
O =[1-1,1-3];
O =[1-1,2-3];
O =[1-1,3-1];
O =[1-1,3-2];
O =[1-1,3-3];
O =[1-2,3-1];
O =[1-2,3-2];
O =[1-2,3-3];
O =[1-3,2-1];
O =[1-3,3-1];
O =[1-3,3-2];
O =[1-3,3-3];
O =[2-1,2-3];
O =[2-1,3-3];
O =[2-3,3-1];
O =[3-1,3-3];
No.
答案 0 :(得分:1)
我发布了一个显示可能的Prolog编码的解决方案,风格为 generate and test 。有一些插槽可以放置适当的算术,只是为了完成你的作业。
%% placing
place_squares(Big, Small, Squares) :-
place_not_overlapping(Big, Small, [], Squares).
place_not_overlapping(Big, Small, SoFar, Squares) :-
available_position(Big, Small, Position),
\+ overlapping(Small, Position, SoFar),
place_not_overlapping(Big, Small, [Position|SoFar], Squares).
place_not_overlapping(_Big, _Small, Squares, Sorted) :-
sort(Squares, Sorted).
overlapping(Size, R*C, Squares) :-
member(X*Y, Squares),
... % write conditions here
available_position(Big, Small, Row*Col) :-
Range is Big - Small + 1,
between(1, Range, Row),
between(1, Range, Col).
放置后,很容易显示
%% drawing
draw_squares(Big, Small, Squares) :-
forall(between(1, Big, Row),
(forall(between(1, Big, Col),
draw_point(Row*Col, Small, Squares)),
nl
)).
draw_point(Point, Small, Squares) :-
( nth1(I, Squares, Square),
contained(Point, Square, Small)
) -> write(I) ; write('-').
contained(R*C, A*B, Size) :-
... % place arithmetic here
请求尺寸的结果和图纸
?- place_squares(5,2,Q),draw_squares(5,2,Q).
1122-
1122-
3344-
3344-
-----
Q = [1*1, 1*3, 3*1, 3*3] ;
1122-
1122-
33-44
33-44
-----
Q = [1*1, 1*3, 3*1, 3*4] ;
1122-
1122-
33---
3344-
--44-
Q = [1*1, 1*3, 3*1, 4*3] .
...
对place_squares / 3输出进行排序,以便于显示,并且可以用来摆脱对称性,并获得所有解决方案的计数:
9 ?- setof(Q, place_squares(5,2,Q), L), length(L, N).
L = [[], [1*1], [1*1, 1*3], [1*1, 1*3, 3*1], [1*1, 1*3, 3*1, ... * ...], [1*1, 1*3, ... * ...|...], [1*1, ... * ...|...], [... * ...|...], [...|...]|...],
N = 314.
您可以注意到这会接受具有“备用”空间的电路板。您可以过滤掉这些不完整的解决方案,以完成您的任务。