【问题标题】:Graph Searching algorithm图搜索算法
【发布时间】:2009-08-17 16:47:42
【问题描述】:

问题来了:
我必须通过以下考虑找到从起点到目的地的路径。

在给定的图中,一个点可以是:

  • (1) 一个检查点--> 这个点必须 是否在计算的最终路径中

  • (2) A Mine--> 这点不应该
    是否在计算的最终路径中

  • (3) 中性点--> 这个点
    可能/可能不会出现在决赛中
    计算路径

我需要一个算法来解决这个问题。

【问题讨论】:

  • “检查点”,嗯?必须按顺序访问吗?
  • 到目前为止你做了什么来尝试创建算法?
  • 您知道给定图表上的检查点总数吗?我假设你必须看到所有这些。
  • 你需要最短路径吗?遍历和边的成本是多少,在图上是否对称
  • @Nick Lewis:检查点将按照接近起点的顺序给出。所以,我想没有什么特别的订单。
    @LFSR Consulting:我试图为此修改 Dijkstra 的。它还没有成功。 
    @BlueNovember:是的。输入如下: 1. 终点。 2.检查点数。 3.那么多检查点坐标。 4.危险点数。 5.那么多坐标。 
    @Kazoom:它在图上不是对称的,我只需要遍历所有不通过危险点的检查点。并不是真的要求它必须是 shprtest 路径

标签: graph-theory traversal


【解决方案1】:

首先清除地雷并列出检查点。

那么您几乎可以肯定必须进行深度优先或广度优先搜索。哪一个取决于图表。我建议尝试广度优先搜索,并采用适当的修剪启发式方法。搜索者从起点开始,然后只要有选择,它就会复制自己并双向进行。它保留两个列表:它访问过的检查点,以及自上次检查点以来访问过的中性节点。当它访问一个中性节点时,它会将其检查点列表写在墙上,并删除任何属于它自己子集的列表。如果遇到以下情况之一,它将自行终止:

  • 它访问已经在其列表之一上的节点。
  • 它在墙上看到一个检查点列表,它是它自己的超集。
  • 它在没有访问所有检查站的情况下到达目的地。

这应该足以让您入门。根据图表,还有其他可能值得的优化(例如消除死角)。

编辑:当我看到最后一个条件会使某些图表变得不可能时,我就抓住了它。)

【讨论】:

    【解决方案2】:

    如果您的检查点需要按特定顺序访问,Dijkstra 算法 是一个简单的解决方案。您可以针对图形的子集使用该算法。子集将是图,其中开始和结束节点是检查点(或图的打开或关闭节点)。您可以使用边权重来表示不应访问的节点。

    但是,我建议 A Pathfinding* 因为它可能更适合您尝试做的事情。那里有很多示例代码。

    这是一个很好的入门教程:

    A* Pathfinding for Beginners

    您可以将您的地雷和检查点表示为图表中的权重,或使用启发式方法。这很可能取决于检查点是否有序。

    Gamedev.net 是您的朋友。祝你好运!

    【讨论】:

      【解决方案3】:

      好吧,我认为您可以使用Dijkstra's algorithm(或类似的东西,我建议使用 Dijkstra,因为它详尽且笼统,而且您没有提供有关数据的太多信息)来找到最短路径...这些修改:

      1. 检查点的值等于中性点数的负数。
      2. 地雷的值等于中性点的数量。
      3. 中性点的值为 1。

      Dijkstra 会找到最短路径(权重最小的路径),保证穿过所有检查站并避开所有地雷。

      虽然它不是一个快速算法,所以如果您的地图太大,它可能无法工作。

      【讨论】:

      • 经典的 Dijkstra 不适用于负边缘。请参见此处:en.wikipedia.org/wiki/Dijkstra%27s_algorithm 另外 - 在您的解决方案中可能存在负循环 - 所以 Bellman-Ford 也不会这样做。
      • 地雷不应该有无限大的权重,因为它们不能出现在最终路径中吗?
      • 我认为负循环问题可以通过跟踪已经访问过的检查点来解决。
      • 还有一件事 - Dijkstra 中的权重应该在边缘上,而不是在节点上。您指的是不同的算法吗?
      • 嗯,边可以简单地成为进入节点的成本。
      【解决方案4】:

      我个人会为此使用深度优先搜索 (DFS)。 Dijkstras 算法用于计算最短路径,基于一些边缘距离函数(您没有提到节点之间的任何距离,所以我假设没有)。

      可以这样修改 DFS(假设 s 是您的源,t 是目标):

      • 首先删除所有“我的”节点及其相邻边。如果无法访问某个矿井节点,则最好将其移除,因为路径中不能使用来自它的传入或传出边。
      • 从节点 s 执行 DFS。
      • 执行 DFS 后,您将拥有一组节点序列,例如[s, a, b, d, e, t], [s, b, d, t, e] 等等。
      • 如果这些序列中的任何一个包含节点 t 之前的所有检查点节点,那么这是一条合适的路径。
      • 如果 DFS 结果中没有这样的序列,则没有满足条件的路径。您要么错过检查站,要么参观矿场才能到达目的地。

      这可能不是最有效的算法,但应该适用于寻找路径。也不能保证您从 DFS 结果中选择的路径是最佳路径。

      (假设可以按任何顺序访问检查点)

      【讨论】:

      • DFS 跟踪节点是否被访问过,如果节点被标记为之前被访问过,则不会访问该节点。例如。在节点 n1-n2-n3-n1 的 3 个循环中,节点 n1 可能首先被访问(并标记为已访问),然后是 n2 和 n3,但在 n3 时,DFS 不会重新访问 n1,因为它被标记为“已访问” "。
      • 抱歉回复晚了,我会澄清我原来的评论。我认为标准 dfs 将产生有效但不一定最短的路径。在您的示例中,即使 n1-n3 更短,n1-n2-n3-n1 的循环是否会产生 n1-n2-n3 作为有效路线? (顺便说一句,你是我在沃里克认识的那个汤姆吗?如果是的话,小世界!-理查德)
      • 确实是我!这是一个非常小的世界。虽然我猜这就是 intertubes 在工作的奇迹。 :-) 我明白你对产生非最佳路径的循环的意思。为了找到最短路径,可以通过某种方式修改 DFS,以便在选择路径时考虑边缘权重,尽管这可能必须使用某种形式的前瞻。
      猜你喜欢
      • 1970-01-01
      • 2016-10-03
      • 1970-01-01
      • 2011-08-16
      • 2012-07-30
      • 1970-01-01
      • 1970-01-01
      • 2021-03-23
      相关资源
      最近更新 更多