【发布时间】:2014-11-05 09:10:07
【问题描述】:
我正在尝试实现状态空间图的深度优先迭代深化搜索。 我有一个包含三个顶点的图,它们是两个激活边和两个抑制边。每个节点都有一个二进制值,这就是图的状态。该图可以通过查看其中一个节点是高于阈值还是低于阈值(通过对所有传入节点求和来计算)转换到新状态。每次转换最多会改变一个节点。由于它们是三个节点,因此它们是三个状态转换边,将每个状态留在状态转换图中。
我认为我的 state_change/3 工作正常,例如我可以查询:
?-g_s_s(0,1,1,Begin),node(Arc),state_change(g_s(Begin),Second,Arc).
它给了我三个正确答案:
Begin = [node(v1, 0), node(v2, 1), node(v3, 1)],
Arc = v1,
Second = g_s([node(v1, 1), node(v2, 1), node(v3, 1)]) ;
Begin = [node(v1, 0), node(v2, 1), node(v3, 1)],
Arc = v2,
Second = g_s([node(v1, 0), node(v2, 0), node(v3, 1)]) ;
Begin = [node(v1, 0), node(v2, 1), node(v3, 1)],
Arc = v3,
Second = g_s([node(v1, 0), node(v2, 1), node(v3, 0)])
我正在尝试使用 Bratkos Prolog for A.I book 中给出的谓词 id_path,即问题 11.3 的解决方案,但我在使用/调整它时遇到问题。 我想创建一条从起始节点到其他节点的路径,而不会进入循环 - 我不希望它有重复元素或在路径不存在时卡住。我想让路径说起始状态,然后您可以从起始状态访问一系列状态。如果有一个自我循环,我希望每一种到达那里的方式都包含一次。即我想跟踪我到达状态空间的方式,并使其独一无二,而不仅仅是状态空间在路径中是唯一的。
例如,从 011 开始,我希望通过弧线找到长度为 1 的所有三个路径。
?-id_path(g_s([node(v1,0),node(v2,1),node(v3,1)],Last,[Temp],Path).
Path = [[node(v1,0),node(v2,1),node(v3,1)],to([node(v1,1),node(v2,1),node(v3,1)],v1)];
Path =[[node(v1,0),node(v2,1),node(v3,1)], to([node(v1,0),node(v2,0),node(v3,1)],v2)];
Path=[[node(v1,0),node(v2,1),node(v3,1)],to([node(v1,1),node(v2,1),node(v3,0)],v3)];
然后在下一级所有具有三个节点的路径,显示它需要到达节点的两条弧线,然后在下一级所有具有四个节点的路径,显示它需要的三个弧等等
如果这有帮助,我也将我的代码放入 SWISH 中? (第一次尝试这个?!)
http://pengines.swi-prolog.org/apps/swish/p/HxBzEwLb.pl#&togetherjs=xydMBkFjQR
a(v1,v3). %a activating edge
a(v3,v1).
i(v1,v2). %a inhibition edge
i(v2,v3).
nodes([v1,v2,v3]).
node(X):- nodes(List),member(X,List). %to retrieve a node in graph a) or an arc in graph b)
g_s_s(X,Y,Z,g_s([node(v1,X),node(v2,Y),node(v3,Z)])). %graph_state_simple - I use this to simply set a starting graph state.
sum_list([], 0).
sum_list([H|T], Sum) :-
sum_list(T, Rest),
Sum is H + Rest.
invert(1,0).
invert(0,1).
state_of_node(Node,g_s(List),State):-
member(node(Node,State),List).
%all activating nodes in a graph state for a node
all_a(Node,As,Ss,g_s(NodeList)):-
findall(A, a(A,Node),As),
findall(S,(member(M,As),member(node(M,S),NodeList)),Ss).
%all inhibiting nodes in a graph state for a node
all_i(Node,Is,Ss,g_s(NodeList)):-
findall(I, i(I,Node),Is),
findall(S,(member(M,Is),member(node(M,S),NodeList)),Ss).
%sum of activating nodes of a node in a state
sum_a(Node,g_s(NodeList),Sum):-
all_a(Node,_As,Ss,g_s(NodeList)),
sum_list(Ss,Sum).
%sum of inhibiting nodes of a node in a state
sum_i(Node,g_s(NodeList),Sum):-
all_i(Node,_Is,Ss,g_s(NodeList)),
sum_list(Ss,Sum).
above_threshold(Threshold,Node,g_s(NodeList),TrueFalse):-
sum_a(Node,g_s(NodeList),Sum_A),
sum_i(Node,g_s(NodeList),Sum_I),
TrueFalse = true,
Threshold < (Sum_A-Sum_I),
!.
above_threshold(Threshold,Node,g_s(NodeList),TrueFalse):-
sum_a(Node,g_s(NodeList),Sum_A),
sum_i(Node,g_s(NodeList),Sum_I),
TrueFalse = false,
Threshold >= (Sum_A-Sum_I).
%arc needs to be instantiated
state_change(g_s(State1),g_s(State1),Arc):-
above_threshold(0,Arc,g_s(State1),true),
state_of_node(Arc,g_s(State1),1).
state_change(g_s(State1),g_s(State2),Arc):-
above_threshold(0,Arc,g_s(State1),false),
state_of_node(Arc,g_s(State1),1),
my_map(State1,State2,Arc).
state_change(g_s(State1),g_s(State2),Arc):-
above_threshold(0,Arc,g_s(State1),true),
state_of_node(Arc,g_s(State1),0),
my_map(State1,State2,Arc).
state_change(g_s(State1),g_s(State1),Arc):-
above_threshold(0,Arc,g_s(State1),false),
state_of_node(Arc,g_s(State1),0).
%
my_map([],[],_).
my_map([X|T],[Y|L],Arc):-
X= node(Node,Value1),
Node =Arc,
invert(Value1,Value2),
Y = node(Node,Value2),
my_map(T,L,Arc).
my_map([X|T],[Y|L],Arc):-
X= node(Node,Value1),
Node \= Arc,
Y = node(Node,Value1),
my_map(T,L,Arc).
%this is the def in the book which I can not adapt.
path(Begin,Begin,[start(Begin)]).
path(First, Last,[First,Second|Rest]):-
state_change(First,Second,Arc),
path(Second,Last,[Second|Rest]).
%this is the def in the book which I can not adapt.
id_path(First,Last,Template,Path):-
Path = Template,
path(First,Last,Path)
; copy_term(Template,P),
path(First,_,P),
!,
id_path(First,Last,[_|Template],Path).
【问题讨论】:
-
我的路径和 id_path 不起作用。所以我正在尝试调试它们。我希望能够生成不会无限循环的路径。
-
要在这里寻求调试帮助,应该提供一个产生问题的代码/调用的最小示例。乍一看,
id_path/4调用了path/3,但除了它自己(递归地)没有调用id_path/4。因此,如果path/3不起作用,让我们从那里开始,稍后再回到id_path/4。 -
path的书例是:path(First,First,[First])。 path(First,Last,[First,Second|Rest]):- s(First,Second), path(Second,Last,[Second|Rest])。不同之处在于我相当于 s/2 是 state_change/3 我还想将弧线放在状态空间图中找到的路径中
-
回到大局。
path/3是不是没有找到你想要的路径,没有找到你不想要的路径,或者以其他方式行为不端(例如陷入无限循环)? -
如果我使用 path/3 作为本书指定它不起作用,因为我需要实例化 state_change/3 的第三个参数,否则它会给出不正确的行为。因此,如果我修改 path/3 以事先调用 node(Arc) ,那么我认为它在查找路径时按预期工作,但会进入无限循环。例如:g_s_s(1,1,1,Begin),path(g_s(Begin),Last,Path)。只会返回 g_s([node(v1, 1), node(v2, 1), node(v3, 1)]。我想以某种方式在其中合并状态空间弧,以便通过弧的每一步都是唯一的。
标签: prolog depth-first-search recursive-backtracking state-space iterative-deepening