如何在Prolog中直接访问相邻垂直点表示有向循环图

如何在Prolog中直接访问相邻垂直点表示有向循环图,prolog,cyclic-graph,Prolog,Cyclic Graph,我需要在Prolog中用循环构造有向图(在运行时),我不知道如何表示它。我的要求是,我需要在一个恒定的时间内从一个顶点到达他的邻居 是否可以将其表示为树,例如: t(左,右)但如何求解循环 我可以列出边: 图([a,b,c,d],[e(a,b),e(b,c),e(c,a),e(c,d)])或者仅仅是[a->[b],b->[c],c->[a,d],d->[]但是如何避免在搜索邻居时调用列表上的函数“member”,这需要线性时间 感谢您的帮助如果图形的顶点少于Prolog允许的最大arity(例如

我需要在Prolog中用循环构造有向图(在运行时),我不知道如何表示它。我的要求是,我需要在一个恒定的时间内从一个顶点到达他的邻居

是否可以将其表示为树,例如:

t(左,右)
但如何求解循环

我可以列出边:

图([a,b,c,d],[e(a,b),e(b,c),e(c,a),e(c,d)])
或者仅仅是
[a->[b],b->[c],c->[a,d],d->[]
但是如何避免在搜索邻居时调用列表上的函数“member”,这需要线性时间


感谢您的帮助

如果图形的顶点少于Prolog允许的最大arity(例如SWI Prolog具有无限arity),则可以将边表示为参数的索引:

可能是

G = graph(a-[2],b-[3],c-[1,4],d-[2]).
然后使用(边、G、垂直边)访问邻居

当然,任何序言都允许您使用事实来描述图形。这也是非常大的图形的首选方式

:- dynamic edge/2.

edge(a,b).
edge(b,c).
edge(c,a).
edge(c,d).
edge(d,b).
编辑edge/2关系表示还可以获得自动索引的(潜在的巨大)好处


更多的编辑我完全忘记了。非常强大,我们正朝着这个方向发展。

除了@ CHAC提出的表示之外,您还可以考虑使用属性变量(如果Prolog系统支持它),尤其是如果您需要在计算过程中将更多属性附加到顶点或边上。在该表示法中,您将为每个顶点使用唯一变量,必要时(使用put_attr/3)附加一个类似“名称”的属性,并附加一个类似“边”的附加属性,例如可以是顶点列表或术语列表边(E,顶点),其中,E也是一个变量,如果需要跟踪影响边缘的信息,可以附加更多属性。

在许多Prolog系统中,如,,,都有
库(ugraphs)
。(请随意在这里添加更多参考!)在那里,图形表示为成对的
顶点邻域
。乍一看,您可能会觉得这不是一个非常有效的表示。毕竟,对单个顶点的访问与列表的长度成正比。但是,直接访问顶点很少引起兴趣。大多数情况下,一张图表都会一次性处理,这通常会分摊访问成本。

。首先,OP讨论“在运行时”构造图,因此要么使用动态谓词,要么构造并传递一些复杂的Prolog术语。第二,“恒定时间”访问在涉及大型图形时可能很重要。因此,可能策略应该是使用chac建议的第二种表示形式在Prolog中实现,然后在速度成为问题时切换到C/C++(或其他支持指针算法的语言)中的实现。优化前的清晰性和正确性!这看起来很有趣。一个小例子怎么样?中讨论的一个例子是寻找有向图的强连通分量。发布的解决方案位于此处:。有关更多示例,如最大匹配和最大流算法,请参阅SWI Prolog中的库(clpfd)。这些算法(也是SCC示例)都需要顶点的附加信息,例如,它是否在堆栈中,是否被访问等,而属性变量使您可以轻松附加和修改这些属性。