prolog学习_八皇后问题

来源:互联网 发布:windows 编程语言 编辑:程序博客网 时间:2024/05/22 00:05

初步学习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(1).             %标记皇后的位置,只能是第一列到第八列中的一个position(2).position(3).position(4).position(5).position(6).position(7).position(8).
% 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转化为列表Blast_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=:=0),                    (position(A)),                    (position(A),last_one(C,X),A=\=C,A=\=C+B,A=\=C- B,B1 is B+1,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<8),                (safe(X,A,1),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运行:
这里写图片描述
查询:(每次键入冒号得到更多的结果)
这里写图片描述


完整的程序:

position(1).             %标记皇后的位置,只能是第一列到第八列中的一个position(2).position(3).position(4).position(5).position(6).position(7).position(8).% 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转化为列表Blast_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=:=0),                    (position(A)),                    (position(A),last_one(C,X),A=\=C,A=\=C+B,A=\=C- B,B1 is B+1,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<8),                (safe(X,A,1),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).
0 0
原创粉丝点击