Algorithm 检查边是否存在于无向图中的好方法

Algorithm 检查边是否存在于无向图中的好方法,algorithm,data-structures,Algorithm,Data Structures,我使用的是邻接列表表示法 基本上 A:[B,C,D] means A is connected to B,C and D 现在,我尝试添加一个方法(在python中)来在图形中添加边 但在我添加边缘之前。我想检查两条边是否连接。 例如,我想在两个节点D和A之间添加一条边(不知道A和D是连接的) 因此,由于哈希/字典中没有键“D”,它将返回false 现在,非常天真地,我可以检查D和A,然后A和D。。但那是非常糟糕的。 或者,无论何时连接两个节点,我都可以复制 即连接A和e时。。A:[

我使用的是邻接列表表示法

基本上

     A:[B,C,D] means A is connected to B,C and D
现在,我尝试添加一个方法(在python中)来在图形中添加边

但在我添加边缘之前。我想检查两条边是否连接。 例如,我想在两个节点D和A之间添加一条边(不知道A和D是连接的)

因此,由于哈希/字典中没有键“D”,它将返回false

现在,非常天真地,我可以检查D和A,然后A和D。。但那是非常糟糕的。 或者,无论何时连接两个节点,我都可以复制

即连接A和e时。。A:[E]创建E:[A]

但这不是很节省空间

基本上,我想让这个图独立于方向

是否有任何数据结构可以帮助我解决这个问题


我希望我的问题有意义。

对于无向图,可以使用一个简单的边列表,其中存储所有边对。这将节省空间并降低性能,但您应该知道,您不能同时拥有这两者,因此您必须始终做出权衡

否则,您可以使用三角形邻接矩阵,但为了避免浪费一半的空间,您必须以特定的方式存储它(通过开发一种在不浪费空间的情况下检索边存在的有效方法)。你确信这是值得的,而且不仅仅是过早的优化吗

邻接列表基本上是很好的,即使你必须存储每个无向边两次,你的图有多大


看看我的答案:,这样你就可以选择你喜欢哪一个。

对于无向图,你可以使用一个简单的边列表,在其中存储所有的边对。这将节省空间并降低性能,但您应该知道,您不能同时拥有这两者,因此您必须始终做出权衡

否则,您可以使用三角形邻接矩阵,但为了避免浪费一半的空间,您必须以特定的方式存储它(通过开发一种在不浪费空间的情况下检索边存在的有效方法)。你确信这是值得的,而且不仅仅是过早的优化吗

邻接列表基本上是很好的,即使你必须存储每个无向边两次,你的图有多大


看看我的答案:,这样你就可以选择你喜欢哪一个。

你遇到了一个经典的空间与时间的权衡

正如您所说,如果您没有找到D->A,您可以搜索A->D。这将导致执行时间最多加倍。或者,在插入A->D时,也可以创建D->A,但这需要额外的空间


在最坏的情况下,为了权衡时间,您将进行2次查找,这仍然是O(N)(数据结构越好,查找速度越快)。对于空间权衡,您将(在最坏的情况下)在每组节点之间创建一个链路,大约为O(N^2)。因此,我只需要进行两次查找。

您遇到了一个经典的空间与时间权衡

正如您所说,如果您没有找到D->A,您可以搜索A->D。这将导致执行时间最多加倍。或者,在插入A->D时,也可以创建D->A,但这需要额外的空间


在最坏的情况下,为了权衡时间,您将进行2次查找,这仍然是O(N)(数据结构越好,查找速度越快)。对于空间权衡,您将(在最坏的情况下)在每组节点之间创建一个链路,大约为O(N^2)。因此,我只需要进行两次查找。

假设每个
contains()
方法都非常扩展,并且您希望不惜一切代价避免执行这些操作,可以使用,并检查是否存在边,这样可以减少
contains()
调用的数量

其思想是:每个节点将拥有自己的bloom过滤器,它将指示哪些边连接到它。检查布卢姆过滤器是相当容易和便宜的,而且在添加边时也可以对其进行修改

如果你检查了布卢姆过滤器-它说“否”-你可以安全地添加边缘-它不存在。
但是,bloom过滤器有误报-因此,如果bloom过滤器说“边缘存在”-您必须检查列表是否确实存在


注:
(1) 如果使用bloom过滤器,则删除边缘将是一个问题。
(2) Bloom过滤器为您提供了很好的时间/空间权衡-随着过滤器大小的增加,误报的数量会减少。

(3) 然而,当一条边确实存在时-无论过滤器的大小如何,您都必须使用
contains()
方法。

假设每个
contains()
方法都非常扩展,并且您希望不惜一切代价避免这样做,您可以使用,并检查是否存在一条边-由此,减少
contains()
调用的数量

其思想是:每个节点将拥有自己的bloom过滤器,它将指示哪些边连接到它。检查布卢姆过滤器是相当容易和便宜的,而且在添加边时也可以对其进行修改

如果你检查了布卢姆过滤器-它说“否”-你可以安全地添加边缘-它不存在。
但是,bloom过滤器有误报-因此,如果bloom过滤器说“边缘存在”-您必须检查列表是否确实存在


注:
(1) 如果使用bloom过滤器,则删除边缘将是一个问题。
(2) Bloom过滤器为您提供了很好的时间/空间权衡-随着过滤器大小的增加,误报的数量会减少。

(3) 但是,当边确实存在时—无论过滤器的大小如何,您都必须使用
contains()
方法。

假设可以比较节点名称,您可以始终存储边,以便第一个端点小于第二个端点。那么您只需要执行一个查找。这绝对适用于字符串。

假设您的节点名