【问题标题】:Should I use a Graph library?我应该使用图形库吗?
【发布时间】:2013-11-10 11:43:04
【问题描述】:

我正在为迷宫制作 DFS 和 BFS 求解器。

我不知道如何在 C++ 中实现 Graph 以及如何实现节点,这些节点将有多个子节点,具体取决于有多少相邻单元格是空的。

我一直在寻找一种初学者友好的方式来用 C++ 实现图形。字面上地。天。

我发现的一切对我来说都太复杂了,我只找到了我无法理解的高级东西。我发现的对初学者最友好的站点是this,但在这个站点中它使用的是 C,它甚至实现了我相信在 C++ 中已经有一个 Stack 类的堆栈。即使是这个网站我也很难理解。

我使用已经制作好的库的问题是我永远不会学习如何实际实现图形和节点,我认为这会极大地损害我对该主题的了解。

我在输入这个时正在下载 boost 库,所以如果我决定使用一个库,我可能会使用这个。

所以我不应该学习如何创建图形和节点而只使用 boost 库(或任何其他相关的),还是有真正的初学者友好的方式来学习如何为 DFS 算法构建图形和节点,尤其是对于迷宫?

【问题讨论】:

  • 当我在我的 CS 课程中有这个作业时,我在没有图形库的情况下解决了它......所以我认为你的问题的答案是:没有。
  • 您是否找到了任何其他语言的“一种对初学者友好的方式来实现图表”?哪一个?
  • @sehe 我只搜索了 C、C++ 和 Java,因为它们是我能理解的三种语言。我只能为初学者找到伪代码。

标签: c++ c graph artificial-intelligence depth-first-search


【解决方案1】:

由于 DFS 和 BFS 是微不足道的算法,因此无需从库中获取它们。是的,它们在BGL 中实现,但这个库主要用于更复杂的算法。此外,BGL 确实提供了一些图形表示,但实际上是以您可以使用自己的图形数据结构并仍然应用 BGL 算法的方式实现的。但不同的是:自己实现图形和算法!

对于 DFS 和 BFS,实现图形非常简单,因为您甚至不需要单独的边类型(没有为边所指向的位置存储额外的数据)。要实现图表,您需要一个 node 类型,它存储一个标志(以指示该节点是否被访问)和一个带有目标节点指示器的容器。大多数情况下,容器只存储指向目标节点的指针,这当然意味着指向的节点会留在内存中。

如果您只在一端添加/删除节点,则可以使用std::deque<Node>;如果您可以在图中的任何位置添加/删除节点,则可以使用std::list<Node>(为了实现 DFS 和 BFS,您只需添加节点可以在最后完成,即我会选择std::deque<Node>)。在节点内部,您只需存储std::vector<Node*>。在两个节点之间插入一条边时,您只需找到两个节点并将指向源节点std::vector<Node*> 的指针添加到目标Node。如果图形是无向的,您需要添加指向两个节点的 std::vector<Node*> 的指针。

顺便说一句,我不会将 DFS 或 BFS 称为“人工智能”。此外,您似乎正在寻找 C++ 解决方案,即 C 标记似乎也放错了位置。

【讨论】:

  • 我的主要问题是如何表示每个节点将拥有的孩子。这就是你对 vector 的意思吗?所以基本上我将有一个节点结构,它将具有以下属性: int row;整数列;布尔访问;向量;对吗?
  • @SiliconTouch:在图中,您实际上并没有孩子,但您有相邻节点。但是,是的,相邻节点的列表存储在Nodes std::vector<Node*> 中。每个节点中存储的其他内容取决于应用程序的需求。
  • 只是插话:我通常喜欢让整个图“只是”一个顶点向量(即邻接列表) - 通过在源或目标上对它们进行排序,它变成了一个“平面” (multi)-map" 所以你可以对它们进行非常有效的 std::lower_bound/std::upper_bound 查找
  • @DietmarKühl 在我看来,仅使用向量将节点连接在一起就很简单了。此外,我已经创建了 node 结构,它现在至少包含行、列、访问状态和 vector 数组。我想这是一个很好的起点,但我明天会再看一遍。
【解决方案2】:

看来您不必将 Node 实现为复杂的结构。 如果节点仅代表迷宫的一个单元格,您可以使用整数来标识特定单元格。

如果迷宫是 MxN 大小,您将有一个 MxN 长度的节点数组。

要表示节点之间的邻接关系,您可以使用邻接矩阵(在足够小的图形的情况下可以)或邻接列表(在您的情况下更有效,因为每个节点可以有 4 个或更少的相邻节点)。

您可以在 Google 中轻松搜索邻接表示。

因此,在这种情况下,您真的不需要任何复杂的东西来实施这些算法。 您只需要数组(但最好使用来自 STL 的向量容器)和来自 STL 的队列容器用于 BFS(DFS 使用堆栈,但您可以使用显式使用堆栈的递归)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多