如何在SWI-Prolog中使用优先级队列?

时间:2013-08-28 09:32:01

标签: prolog priority-queue a-star

我正在尝试在SWI-Prolog中实现A *算法。我有一个图形,其中每个状态由以下值组成(Cost_So_Far,启发式,“无关紧要”,“无关紧要”,“无关紧要”)并且我想将状态插入到优先级队列中到启发式,这是一个整数。我怎么能这样做?

3 个答案:

答案 0 :(得分:1)

一种简单的方法是使用Key-Value对列表,其格式为:

[1-state(Cost_so_far, ...), 2-state(...), 3-state(...)]

启发式的整数值是关键,函子状态(你需要的任何arity)都是值。请注意,这是保持对列表的传统方法。您可以使用匹配将它们取出,例如,队列头部的状态为:

[Heuristic-state(A, B, C)|QueueRest]

每次在队列顶部添加新状态时,您应该使用内置的keysort/2进行排序(非常有效)。

答案 1 :(得分:1)

您可以使用“堆”库,它是“优先级队列”概念的实现。理查德·奥基夫(Richard O'Keefe)周围有一堆Prolog实现。 SWI-Prolog还在Lars Buitinck的“堆”库中附带堆实现。 Logtalk(在几个Prolog系统上运行,包括SWI-Prolog)还包括源自Richard原始实现的最大和最小堆。使用启发式值作为Boris建议的密钥,堆应该比每次添加新对时必须使用的列表更有效。

一些有用的链接:

SWI-Prolog heaps library

Logtalk heap protocol

Logtalk min-heap and max-heap implementations

答案 2 :(得分:0)

这是优先级队列的基本实现。 我刚刚开始学习序言。 如果有更好的方法来实现优先级队列。请在下方留言。

takeout(X,[X|R],R).
takeout(X,[F|Fs],[F|S]):- takeout(X,Fs,S).


delete_elem([H|T]):- min_p([H|T],99,MinP) , search_minp(MinP , [H|T] , Num) , takeout((Num,MinP),[H|T],Z) , write(Z).


ins([],L,L).
ins([(Num,Priority)|T],L,[(Num,Priority)|Z] ):- ins(T,L,Z).
/* here i used ins function to append (Num,Priority) to a existing queue
if [(99,2) , (90,1) , (96, 3)] this is priority queue. if want to add (93,4)
ins([(93,4)] , [(99,2) , (90,1) , (96, 3)] ,Z).
Z = [(99,2) , (90,1) , (96, 3) , (93,4)]
*/

min_p([],Min,Min).
min_p([(Num,Priority)|Z],X,Y):- Priority < X , Min is Priority , min_p(Z,Min,Y).
min_p([(Num,Priority)|Z],X,Y):- Priority > X , min_p(Z,X,Y).

/* min_p here I used to find the minimum priority from the given priority queue.
X should be INT_MAX
min_p([(99,2) , (90,1) , (96, 3) , (93,4)],999,Y).
Y = 1 .
*/


search_minp(Priority,[(Num,P)|T],Num):- Priority is P.
search_minp(Priority,[(Num,P1)|T],X):- search_minp(Priority,T,X).

/* search_minp is used to search element corresponding to minimum priority.
if this is our priority queue [(99,2) , (90,1) , (96, 3) , (93,4)]
search_minp(1,[(99,2) , (90,1) , (96, 3) , (93,4)],Z).
Z = 90.
*/