prolog学习_八皇后问题

这篇博客介绍了如何使用Prolog编程语言解决经典的八皇后问题。作者分享了学习Prolog的基本语法和环境搭建过程,并提供了八皇后问题的Prolog程序实现,通过递归判断每个皇后的位置,确保它们不在同一行、列或对角线上。博客中还提到了if_then_else结构和list操作的知识。读者可以通过提供的链接获取更多学习资源。

初步学习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转化为列表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=:=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转化为列表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=:=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).



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值