Hidoku(Hidato)是一个日语逻辑难题:在图中找到一条路径,该路径以正确的顺序恰好一次穿过所有字段。 -交互式/在线解决或打印出许多难题,包括解决方案,各种难度和图表大小,解决方案技术,链接,文献。
该学生项目的状态是我们已经执行了这些规则,但是正在努力加快prolog程序的速度。我们认为我们必须实施其他规则和启发式方法,但不知道应该使用哪种策略。
您可以在这里找到我们给定的难题:
我们定义了hidoku规则
/*-----------------Libraries-------------------------------------*/
:-use_module(library(clpfd)). % loading library
:-use_module(library(lists)). % loading library
/*---------create a list with all possible consecutive pairs of numbers of a given hidoku----------------------------*/
% clear element at X position of a list
remove_at(X,[X|Xs],1,Xs).
remove_at(X,[Y|Xs],K,[Y|Ys]) :- K > 1,
K1 is K - 1, remove_at(X,Xs,K1,Ys).
% create a list with numbers between I and K with every number two times
range(I,I,[I]).
range(I,K,[I,I|L]) :- I < K,I1 is I + 1, range(I1,K,L).
% create list P with all possible consecutive pairs between St and End
% List: [E1,E2,E3,E4,E5,...](E1,E2 -> 1.pair; E3,E4 -> 2.pair)
listeF1(St,End,P) :-
range(St,End,P_n),
remove_at(_,P_n,1,P).
%e.g.:listeF1(1,9,P).-> result:P= [1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9].
/*--------------test if neighbour --------------------------------------------------*/
indexOf([Element|_], Element, 1). % We found the element
indexOf([_|Tail], Element, Index):-
indexOf(Tail, Element, Index1), % Check in the tail of the list
Index is Index1+1. % and increment the resulting index
% changing the mod function that gives the divisor instead of the case 0
mod2(Z,M,X):-
Zn is mod(Z,M),
Zn=:=0,
X = M,
!.
mod2(Z,M,X):- X is mod(Z,M),Zn is mod(Z,M), Zn=\=0.
% testing if number 'ZahlA' and number 'ZahlB' of matrix are neighbours ('Cols' is the matrix size)
nachbarM(ZahlA,ZahlB,Matrix,Cols):-
flatten(Matrix, NewList),
indexOf(NewList,ZahlA,A),
Ax_id is ceiling(A/Cols),
mod2(A,Cols,Ay_id),
indexOf(NewList,ZahlB,B),
Bx_id is ceiling(B/Cols),
mod2(B,Cols,By_id),
C is abs(Ax_id-Bx_id),
D is abs(Ay_id-By_id),
E is C*C+D*D,
E<3.
/*-----------test if all consecutive numbers are neighbours--------------------------------------------------*/
alle_benachbart(L,Matrix,Cols) :-
[A1,A2|T]=L,
nachbarM(A1,A2,Matrix,Cols),
alle_benachbart(T,Matrix,Cols).
alle_benachbart([],Matrix,Cols).
% e.g. alle_benachbart([1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9],[[9,3,2],[8,1,4],[7,6,5]],3). % true
% e.g. alle_benachbart([1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9],[[1,2,3],[4,5,6],[7,8,9]],3). % false
% e.g. alle_benachbart([1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9],[[1,2,3],[6,5,4],[7,8,9]],3). % true
/* ----------hidoku rules for a 3x3 puzzle---------------------------------------------------------------*/
hidoku(Rows) :-
length(Rows,3),maplist(same_length(Rows), Rows),
append(Rows, Vs),
Vs ins 1..9, % ist eine Zahl von 1~N×M einzutragen
all_distinct(Vs), % jede Zahl genau einmal verwendet
listeF1(1,9,L_fol),
alle_benachbart(L_fol,Rows,3).
/*----------CMD-------how to try it---------------------------------------------------*/
% hidoku(Rows), maplist(label, Rows). %-> generate a solved hidoku without any given conditions
% hidoku(Rows), maplist(label, Rows),Rows=[[_,2,_],[6,_,8],[_,_,_]]. %-> solve the given problem 'Rows'
直到现在,我们的代码仅适用于3x3矩阵。对于我们的作业,对于每个给定的问题(最大大小为10 x 10),prolog求解器应该少于30秒。