我应该使用迭代加深深度优先搜索(IDDFS)迭代有向图吗?

时间:2011-04-26 15:40:19

标签: algorithm graph artificial-intelligence neural-network

示例:我有20个人作为对象,每个人都知道0-n其他人。链接的方向很重要! A人可能知道B,但B可能不知道A.这是有向图。

编辑: 为简化起见,我的节点对象(在本例中为Person对象)能够存储任意信息。我知道这不是最好的设计,但现在没问题。

所以在最糟糕的情况下,每个人都与其他人联系,每个人都认识其他人。 这不是真正的用例,但我想为此编写一个测试来学习和玩耍。在生产环境中,对象的数量将限制在大约20个,但这些对象相互连接的方式是无限的。

这以简化的方式说明了问题: graph thanks to source

以一个特定的人作为起点,我想要遍历整个图表并检查每个可能的路径,而不会陷入无限循环。

让我们假设A知道B,谁知道C,谁知道A.输出可能是:

知道B知道C知道A(好但我们不想以无限循环结束所以我们在此停止) 知道C知道A 知道T知道R知道V

这将是愚蠢的,必须予以消除: 知道B知道C知道A知道C知道A知道T知道R知道V ...

我有几个疯狂的想法如何解决这个问题。但...

问题)我必须使用迭代加深深度优先搜索(IDDFS)吗?


Jon非常友好地指出DFS on Wikipedia

我在文章中坚持这一部分: wikipedia

  

从A开始的深度优先搜索,   假设在左边缘   在右边之前选择显示的图形   边缘,并假设搜索   记住以前访问过的节点和   不会重复它们(因为这是一个   小图),将访问节点   以下顺序:A,B,D,F,E,C,   G.在此搜索中遍历的边   形成一个Trémaux树,一个结构   图中的重要应用   理论

具体说明:

  

“(因为这是一张小图)”

好的,如果这是一张巨大的图表呢?

5 个答案:

答案 0 :(得分:3)

编辑:我应该提到作者的标题和问题已经发生了很大变化,这个答案中的一些信息可能与100%无关。

正如乔恩已经提到的,这确实是一张图。事实上是有向图。

我建议您查看Adjacency matrices,它们将为您提供有关如何获得解决方案的直接见解。 我想你原来的 lazy 解决方案可能类似于Adjacency list;这很好,但不容易实现,也可能更难以遍历。两者之间存在两个主要差异。

邻接列表将占用更多空间,但在较大网络中可能更好地最小化未连接节点上的计算;而邻接矩阵更友好,但存储每个边缘的数据,无论它是否存在(连接)。

我在使用邻接列表时发现的主要问题不是它们的理论空间,而是在C ++中,我将每个连接的节点存储为每个节点内的向量中的指针;一旦网络变大,这可能会失控,并且对可视化以及管理新节点和删除节点非常不友好。 与邻接矩阵相比,邻接矩阵对所有节点都有一个引用(可以存储在单个节点向量中)并且可以很容易地修改。


如果您的问题确实是关于遍历的话,那么如果您的图形被实现为邻接矩阵,作为向量的向量,则遍历很简单。见下面的伪代码:

读取(对于每个神经元)神经元轴突连接的所有神经元(即神经元输出)

for (size_t i = 0; i < n; ++i) { // adjacency matrix is n * n
    Neuron& neuron = nodes[i];
    for (size_t j = 0; i < n; ++i) {
        Axon_connection& connection = edges[j][i];
        if (connection.exists()) {
            ...
        }
    }
}

要读取所有(对于每个神经元)神经元,神经元的树突连接到(即神经元输入)

for (size_t i = 0; i < n; ++i) { // adjacency matrix is n * n
    Neuron& neuron = nodes[i];
    for (size_t j = 0; i < n; ++i) {
        Dendrite& dendrite = edges[j][i];
        if (dendrite.exists()) {
            ...
        }
    }
}

注意第二种方法对于大型网络可能不是缓存友好的,具体取决于您的实现。 exists方法只是确保邻接矩阵位设置为true,然后您可以实现其他数据,例如这些边缘中的强度。

答案 1 :(得分:2)

我的朋友,你在最后一两天发布了很多similar questions。我建议你花一点时间阅读一本关于图论的入门教科书,或者找一些关于这个主题的lectures

然后,您至少会知道如何识别和分类标准问题。所有你想要的东西都是回到这些资源的链接 - 它不值得任何人写出新的博览会。如果您有特定问题,或者对某个特定问题有所了解,那么请问我们会很乐意提供帮助,但您需要在中途与我们会面。

要回答您的问题,您可以像以前在树上执行的那样在任意图形上执行深度优先搜索和广度优先搜索 - 您只需要跟踪您访问过的节点。在您遇到的任何代码/伪代码中注意这一点。你不必跟踪树上访问过的笔记(就像在你的其他问题中一样),因为树是图形的一个特殊实例(一个连接的非循环图形),它不能与之相关联。 34。

答案 2 :(得分:2)

在回答你原来的问题时,理论上肯定有可能解决。但是,如果你是在最短的路径之后,那么这看起来很像travelling salesman problem NP-hard

在任何情况下,都有许多不同的图遍历算法(DFS,IDDFS,BFS等)可以使用。

答案 3 :(得分:1)

您的数据结构确实是图表。

我讨厌提供这样一个简单的答案,但问题是如此基本,以至于维基百科上的Graph Traversal绰绰有余。解释了两种基本方法,也有伪代码。

答案 4 :(得分:1)

执行此操作的一种方式(而不是必须,最好的方法)是修改图形。

例如,假设该图最初编码A - > B - > C。如果边缘A - > C不存在,则添加边缘A - > C。

您可以为图中的每个节点执行此操作,以明确说明哪些节点彼此了解。