prolog深度第一次迭代加深

use*_*815 10 prolog depth-first-search iterative-deepening state-space recursive-backtracking

我试图实现深度优先深度搜索状态空间图.我有一个带有三个顶点的图形,它们是两个激活边和两个禁止边.每个节点都有一个二进制值,统称这是图的状态.通过查看其中一个节点是高于阈值还是低于阈值(通过对所有传入节点求和计算),图形可以转换到新状态.每个转换最多只有一个节点会发生变化.由于它们是三个节点,它们是三个状态转换边缘,在状态转换图中留下每个状态.国家图

我认为我的state_change/3工作正常,例如我可以查询:

?-g_s_s(0,1,1,Begin),node(Arc),state_change(g_s(Begin),Second,Arc).
Run Code Online (Sandbox Code Playgroud)

它给了我三个正确的答案:

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)]) 
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用Bratkos Prolog中为AI书提供的谓词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)];
Run Code Online (Sandbox Code Playgroud)

然后在下一个级别所有具有三个节点的路径,显示它需要到达节点的两个弧,然后在下一个级别所有具有四个节点的路径显示它需要的三个弧等

如果这有用,我还将我的代码放在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).
Run Code Online (Sandbox Code Playgroud)

小智 1

由于状态空间是有限的,因此只有有限多个最小循环或终端路径。我想到以下选项来表示图中的最小循环。

\n\n

- 有理项:一些 Prolog 系统支持有理项,因此重复路径 [0,1,2,2,2,...] 可以表示为 X = [0,1|Y], Y=[2|Y ]。

\n\n

- 非有理项:当然,您也可以将重复路径表示为一对。前面的示例将是 ([0,1], [2])。

\n\n

检测循环模式并不仅查找某些内容是否循环,还查找正在循环的部分,可以通过以下代码进行存档。附加谓词将执行搜索:

\n\n
?- append(X, [2|Y], [0,1,2,3]).\nX = [0, 1],\nY = [3] \n
Run Code Online (Sandbox Code Playgroud)\n\n

所以我们知道,当我们已经找到了一条路径[0,1,2,3],当我们看到节点2时,我们就找到了一个环,我们可以用一个Omega词来表示找到的环,如下[ 0,1] [2,3] \xcf\x89。这是一个简单的回溯代码:

\n\n
path(P, P).\npath((C,[]), P) :-\n   last(C, X), edge(X, Y),\n   extend(C, Y, A, B), path((A,B), P).\n\nextend(C, Y, A, [Y|B]) :-\n   append(A, [Y|B], C), !.\nextend(C, Y, A, []) :-\n   append(C, [Y], A).\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是一个运行示例:

\n\n
?- path(([s(0,1,1)],[]), X).\nX = ([s(0,1,1)],[]) ;\nX = ([s(0,1,1),s(0,1,0)],[]) ;\nX = ([s(0,1,1),s(0,1,0),s(0,0,0)],[]) ;\nX = ([s(0,1,1),s(0,1,0)],[s(0,0,0)]) ;\nX = ([s(0,1,1)],[s(0,1,0)]) ;\nX = ([s(0,1,1),s(1,1,1)],[]) ;\n...\n
Run Code Online (Sandbox Code Playgroud)\n