/* Generate a list [1, 2, ..., N] to L. Permute L to Board. Check Board if it is safe. */ queens( N, Board ) :- !, range( N, L ), permutation( L, Board ), safe( Board ). range( N, L ) :- decrease( N, Temp ), reverse( Temp, L ). % Generate a increasing list. decrease( 0, [] ) :- !. decrease( N, [H | L] ) :- N = H, Next is N - 1, decrease( Next, L ). safe( [_] ) :- !. % Check if all queens are safe. safe( [Queen | Others] ) :- !, nohit( Queen, 1, Others ), safe( Others ). nohit( _, _, [] ) :- !. % Check if queens could not attack each other. nohit( Column, Row_D, [Queen | Others] ) :- !, nohit( Column, Row_D, Queen ), Row_D_Next is Row_D + 1, nohit( Column, Row_D_Next, Others ). nohit( Column, Row_D, Target ) :- !, Diag1 is Column + Row_D, Diag1 =\= Target, Diag2 is Column - Row_D, Diag2 =\= Target.
之後只要用
以四佾來說,它會印出:
queens( 4, B ).
就可以列出當棋盤大小為四佾時,四個皇后不會互相攻擊的縱座標或橫座標[?]。以四佾來說,它會印出:
B = [2,4,1,3] B = [3,1,4,2]意即第一組解為(1,2)(2,4)(3,1)(4,3)和第二組解為(1,3)(2,1)(3,4)(4,2)。
引數的數字可以依棋盤大小任意更改。由於Prolog是採DFS的方式搜尋,太大的棋盤會跑很久。
沒有留言:
張貼留言