天天看点

prolog学习_八皇后问题

初步学习prolog语言,感觉上手还是挺容易的,虽然不是很深,但基本的语法结构比较简单,然后看了一些入门资料:

prolog语言,耐心看完你就入门了

链接:http://pan.baidu.com/s/1mijQUrY 密码:3yb5

prolog环境搭建:

链接:http://pan.baidu.com/s/1cj5tGa 密码:7olj

prolog语言教程:

链接:http://pan.baidu.com/s/1c2DTwSK 密码:tpav

然后看到一篇关于prolog解决数独和八皇后问题的文章:先看下这个链接吧

尝试自己写一个八皇后问题prolog程序,当作学习吧

position().             %标记皇后的位置,只能是第一列到第八列中的一个
position().
position().
position().
position().
position().
position().
position().
           
% if P then Q else R
%if_then_else结构

if_then_else(P,Q,R):- call(P),!,Q.      
if_then_else(P,Q,R):- R.
           

有关于if_then_else结构的prolog知识,可以看if_then_else

list_append(A,B):- append([],[A],B).           %将数字A转化为列表B

last_one(A,X):- append(_,[A],X).         %A等于表X的最后一个元素

first_part(A,X):- last_one(B,X),append(A,[B],X).   %得到A等于表X的除最后一个元素的前部分表
           

有关append()以及list的相关知识,同样可以看一下

list

append

%在已有棋局X下添加一行,A为满足条件的皇后的列号,B用于递归的参数

%如果X的长度为0,即目前要放的是第一行,则八个位置均可。否则取X最后一个元素,需要A满足不在其同一列以及不在同一对角线上要求,在递归判断前一行,直到第一行。

% if(length(X)==0)

% {

% A = position();

% }

% else

% {

% C=last_one_of(X);

% B++,判断 A是否与C同行,同列,同对角线

% B1 = B

% 如果安全

% 递归safe(X前安全部分,A,B1)

% }

safe(X,A,B):- 
    if_then_else((length(X,L),L=:=),
                    (position(A)),
                    (position(A),last_one(C,X),A=\=C,A=\=C+B,A=\=C- B,B1 is B+,first_part(Y,X),safe(Y,A,B1))).
           

%求出所有八皇后问题的解。X为现有棋盘,Y为在X基础上添加一行的棋盘,直到添加了8行。每一次先判断在X下可以放的位置有哪些,在将其转化为列表,再将其添加到X后

% queen(X,Y)

% if(length(X)<8)

% {

% safe(X,A,1)

% B=A

% Z=X+B

% queens(Z,Y)

% }

%

% else

% {

% Y = X

% }

queens(X,Y):-
    if_then_else((length(X,L),L<),
                (safe(X,A,),list_append(A,B),append(X,B,Z),queens(Z,Y)),
                (append(X,[],Y))).
           

入口查询:结果X=[Y1,Y2,Y3,Y4,Y5,Y6,Y7,Y8]

eight_queens([(_,Y1),(_,Y2),(_,Y3),(_,Y4),(_,Y5),(_,Y6),(_,Y7),(_,Y8)]):-
    queens([],X),
    append([],[Y1,Y2,Y3,Y4,Y5,Y6,Y7,Y8],X).
           

其实还是挺简单的啦

运行过程:

consut运行:

prolog学习_八皇后问题

查询:(每次键入冒号得到更多的结果)

prolog学习_八皇后问题

完整的程序:

position().             %标记皇后的位置,只能是第一列到第八列中的一个
position().
position().
position().
position().
position().
position().
position().

% if P then Q else R
%if_then_else结构

if_then_else(P,Q,R):- call(P),!,Q.      
if_then_else(P,Q,R):- R.



list_append(A,B):- append([],[A],B).           %将数字A转化为列表B

last_one(A,X):- append(_,[A],X).         %A等于表X的最后一个元素

first_part(A,X):- last_one(B,X),append(A,[B],X).   %得到A等于表X的除最后一个元素的前部分表


%在已有棋局X下添加一行,A为满足条件的皇后的列号,B用于递归的参数
%如果X的长度为0,即目前要放的是第一行,则八个位置均可。否则取X最后一个元素,需要A满足不在其同一列以及不在同一对角线上要求,在递归判断前一行,直到第一行。
%  if(length(X)==0)
%        {
%            A = position();
%         }
%  else
%        {
%             C=last_one_of(X);
%             B++,判断 A是否与C同行,同列,同对角线
%             B1 = B
%             如果安全
%             递归safe(X前安全部分,A,B1)
%         }
%

safe(X,A,B):- 
    if_then_else((length(X,L),L=:=),
                    (position(A)),
                    (position(A),last_one(C,X),A=\=C,A=\=C+B,A=\=C- B,B1 is B+,first_part(Y,X),safe(Y,A,B1))).

%求出所有八皇后问题的解。X为现有棋盘,Y为在X基础上添加一行的棋盘,直到添加了8行。每一次先判断在X下可以放的位置有哪些,在将其转化为列表,再将其添加到X后


% queen(X,Y)
%   if(length(X)<8)
%        {
%             safe(X,A,1)
%             B=A
%             Z=X+B
%             queens(Z,Y)
%         }
%
%   else
%         {
%             Y = X
%         }


queens(X,Y):-
    if_then_else((length(X,L),L<),
                (safe(X,A,),list_append(A,B),append(X,B,Z),queens(Z,Y)),
                (append(X,[],Y))).


%X=[Y1,Y2,Y3,Y4,Y5,Y6,Y7,Y8]    
eight_queens([(_,Y1),(_,Y2),(_,Y3),(_,Y4),(_,Y5),(_,Y6),(_,Y7),(_,Y8)]):-
    queens([],X),
    append([],[Y1,Y2,Y3,Y4,Y5,Y6,Y7,Y8],X).



           

继续阅读