魔术六角不能限制自己 [英] Magic Hexagon can't constrain itself

查看:153
本文介绍了魔术六角不能限制自己的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图解决Prolog中的 Magic Hexagon 问题,在维度5中,现在(?)。我首先通过使用2D列表创建布局。然后,我尝试约束每个元素的列表(这实际上是一个列表)。
然而,我不能让它工作,这里是我的代码,之后的所有更新

 code>: -  use_module(library(clpfd))。 

求解(Dim): -
长度(L,5),%define 5对角线
偏移量为Dim - 2,
Flag为0,
fill(L,Offset,Dim,Flag),
writeln(L),
constraint_sum(L,38),
writeln

constraint_sum([],_)。
constraint_sum([H | T],Sum): -
label(H),
sum_list(H,Sum),
constraint_sum(T,Sum)。

fill([],_,_,_)。
fill([H | T],Len,Dim,Flag): -
Flag == 0,
Len< Dim,
length(H,Len),
H ins 1..19,
all_different(H),
NewLen是Len + 1,
fill ,NewLen,Dim,Flag)。
fill([H | T],Len,Dim,_): -
length(H,Len),
H ins 1..19,
all_different ,
NewLen是Len-1,
Flag是1,
填充(T,NewLen,Dim,Flag)。

,我得到:

$

[[_ G2537,_G2581,_G2617],[_ G2857,_G2893,_G2929,_G2965] p>

[_ G3263,_G3299,_G3335,_G3371,_G3407],[_ G3757,_G3793,_G3829,_G3865],



[_G4157,_G4193,_G4229]]



[[1,18,19],[1,2,16,19],[ ,19],[1,2,16,19],[1,18,19]]



true。




..你可以看到问题是元素不是唯一的,因为我使用 all_different()但是我不知道怎么做!

解决方案

我打赌 - 是一个错误,因为问题页面指出只有一个解决方案。

 : -  module(magic_exagon,[magic_exagon / 0] )。 
: - use_module(library(clpfd))。

magic_exagon: -
magic_exagon(3,38)。

magic_exagon(N,Sum): -
R是N * 2-1,
findall(L,(1,R,C),c_cells N,R,L)),Rows),
flatten(Rows,Cells),
length(Cells,Max),
Cells ins 1..Max,
all_different单元格),

get_diags(Rows,N,R,1,LeftDiags),

reverse(Rows,Rev),
maplist(reverse,Rev,RevRows ),
get_diags(RevRows,N,R,1,RightDiags),

maplist(sum_diags(Sum),Rows),
maplist(sum_diags ,
maplist(sum_diags(Sum),RightDiags),

标签(单元格),
显示(rows,Rows)。

c_cells(C,N,R,L): -
(C> N→M是N + RC; M是N + C-1) b长度(L,M)。

sum_diags(Sum,Diag): -
sum(Diag,#=,Sum)。

get_diags([],_,_,_,[])。
get_diags(Rows,N,R,C,[Diag | Diags]): -
c_cells(C,N,R,Diag),
capture(Diag,Rows,RestWithEmpty)
drop_empties(RestWithEmpty,Rest),
C1是C + 1,
get_diags(Rest,N,R,C1,Diags)。

捕获([],Rest,Rest)。
capture([Cell | Diag],[[Cell | Cs] | Rows],[Cs | Rest]): -
捕获(Diag,Rows,Rest)。

drop_empties([[| | RestT],Rest): - !,drop_empties(RestT,Rest)。
drop_empties(Rest,Rest)。

show(K,Ds): - writeln(K),maplist(writeln,Ds)。

get_diags / 5对索引很难做。我设计了一个算法来捕获来自操场的diag。



编辑



以简单的方式显示对角线

  ... 
标签$ b show(rows,Rows),
show(left,LeftDiags),
show(right,RightDiags)。

,我们获得

 ? -  magic_exagon。 
rows
[3,16,19]
[17,6,7,8]
[18,4,1,5,10]
[12 ,2,11,13]
[9,14,15]
left
[3,17,18]
[16,6,4,12]
[19,7,1,2,9]
[8,5,11,14]
[10,13,15]
right
[15,13, 10]
[14,11,5,8]
[9,2,1,7,19]
[12,4,6,16]
[18, 17,3]


I am trying to solve the Magic Hexagon problem in Prolog, in dimension 5, for now(?). I first create the layout, by using a 2D list. Then I try to constraint every element of that list (which is actually a list). However, I can't make it work, here is my code, after all the updates:

:- use_module(library(clpfd)).

solve(Dim) :-
    length(L, 5), % define 5 diagonals
    Offset is Dim - 2,
    Flag is 0,
    fill(L, Offset, Dim, Flag),
    writeln(L),
    constraint_sum(L, 38),
    writeln(L).

constraint_sum([], _).
constraint_sum([H|T], Sum) :-
    label(H),
    sum_list(H, Sum),
    constraint_sum(T, Sum).

fill([], _, _, _).
fill([H|T], Len, Dim, Flag) :-
    Flag == 0,
    Len < Dim,
    length(H, Len),
    H ins 1..19,
    all_different(H),
    NewLen is Len + 1,
    fill(T, NewLen, Dim, Flag).
fill([H|T], Len, Dim, _) :-
    length(H, Len),
    H ins 1..19,
    all_different(H),
    NewLen is Len - 1,
    Flag is 1,
    fill(T, NewLen, Dim, Flag).

and I am getting:

1 ?- solve(5).

[[_G2537,_G2581,_G2617],[_G2857,_G2893,_G2929,_G2965],

[_G3263,_G3299,_G3335,_G3371,_G3407],[_G3757,_G3793,_G3829,_G3865],

[_G4157,_G4193,_G4229]]

[[1,18,19],[1,2,16,19],[1,2,3,13,19],[1,2,16,19],[1,18,19]]

true .

..as you can see the problem is that the elements are not unique, since I have used all_different() for every list separately and not for the whole list, but I do not know how do that!

解决方案

my bet - but I think there is a bug, since the problem page states there is only a solution.

:- module(magic_exagon, [magic_exagon/0]).
:- use_module(library(clpfd)).

magic_exagon :-
    magic_exagon(3, 38).

magic_exagon(N, Sum) :-
    R is N*2-1,
    findall(L, (between(1,R,C), c_cells(C,N,R,L)), Rows),
    flatten(Rows, Cells),
    length(Cells, Max),
    Cells ins 1..Max,
    all_different(Cells),

    get_diags(Rows, N,R,1, LeftDiags),

    reverse(Rows, Rev),
    maplist(reverse, Rev, RevRows),
    get_diags(RevRows, N,R,1, RightDiags),

    maplist(sum_diags(Sum), Rows),
    maplist(sum_diags(Sum), LeftDiags),
    maplist(sum_diags(Sum), RightDiags),

    label(Cells),
    show(rows, Rows).

c_cells(C,N,R,L) :-
    ( C > N ->   M is N+R-C ; M is N+C-1 ),
    length(L,M).

sum_diags(Sum, Diag) :-
    sum(Diag, #=, Sum).

get_diags([], _,_,_, []).
get_diags(Rows, N,R,C, [Diag|Diags]) :-
    c_cells(C, N, R, Diag),
    capture(Diag, Rows, RestWithEmpty),
    drop_empties(RestWithEmpty, Rest),
    C1 is C+1,
    get_diags(Rest, N,R,C1, Diags).

capture([], Rest, Rest).
capture([Cell|Diag], [[Cell|Cs]|Rows], [Cs|Rest]) :-
    capture(Diag, Rows, Rest).

drop_empties([[]|RestT], Rest) :- !, drop_empties(RestT, Rest).
drop_empties(Rest, Rest).

show(K,Ds) :- writeln(K), maplist(writeln, Ds).

get_diags/5 is tricky to do with indexing. I devised an algorithm to capture a diag from the playground. We cannot use findall/3 after variables have been attributed, hence the recursive loop.

edit

To display diagonals, an easy way

...
label(Cells),
show(rows, Rows),
show(left, LeftDiags),
show(right, RightDiags).

and we get

?- magic_exagon.
rows
[3,16,19]
[17,6,7,8]
[18,4,1,5,10]
[12,2,11,13]
[9,14,15]
left
[3,17,18]
[16,6,4,12]
[19,7,1,2,9]
[8,5,11,14]
[10,13,15]
right
[15,13,10]
[14,11,5,8]
[9,2,1,7,19]
[12,4,6,16]
[18,17,3]

这篇关于魔术六角不能限制自己的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆