无向图,检查节点

时间:2017-06-27 12:39:10

标签: c# algorithm

我正在尝试检查是否存在从一个顶点到其他几个顶点的任何顶点的路径(在我的特定情况下,我需要检查是否有从墙顶到任何其他砖块的路径)在地上,每块砖都是顶点)

我找到了一些算法,但我需要简化版本来检查路径是否存在。 (如果我也可以拥有多条可能的路径,那就太好了。)

我是这些图表的新手,并且在询问这些搜索算法之前已经搜索了很多,但我无法弄清楚如何在我的情况下实现它们。

编辑1:我忘了添加我可以拥有数百个砖块(顶点),并且需要以最快的方式检查路径是否存在。我搜索过Dijkstra的算法,看起来太复杂了。由于某种原因,有更多关于定向图的教程和解释,所以这就是我在这里写问题的原因。

现在我有顶点类:

public class Vertex : MonoBehaviour {

public string id;

public float x; // Horizontal coord
public float y; // Vertical coord

public Vertex(string id, float x, float y)
{
    this.id = id;
    this.x = x;
    this.y = y;
}
}

和边缘类:

public class Edge : MonoBehaviour {

public Vertex Vertex1; // Vertex one
public Vertex Vertex2; // Vertex two

public Edge(Vertex Vertex1, Vertex Vertex2)
{
    this.Vertex1 = Vertex1;
    this.Vertex2 = Vertex2;
}
}

不知道如何在图表中表示它们,因为作为输入我有三维墙壁并且在一些砖块被破坏后我需要检查顶部砖块是否有通往任何底砖的路径在地板上,因为如果没有墙将基本崩溃。所以看起来我必须检查所有路径的3个维度。

编辑2:

在顶点类我添加了邻居列表public List<Vertex> Neighbours;    但仍然无法弄清楚如何在3d中表示图形,所以至少你可以告诉我它是如何在2d中表示的。

ps(谢谢大家的评论和回答,我非常感谢他们)。

5 个答案:

答案 0 :(得分:2)

通过一些预处理,您可以在接近恒定的时间内回答这些查询,这在您必须测试几对节点时很有用(看起来像你这样做)。

预处理很简单:使用V项初始化不相交集(V是顶点数),然后对每个边(x,y)调用union(x, y)。这几乎是边缘数量的线性(“几乎”意味着它与反Ackerman因子不同,它非常接近常数,实际上也可能是常数)。

要查找xy之间是否有路径,请测试find(x) == find(y)

你可以通过将邻接矩阵提高到V'次幂来找到任意对之间可能的路径数(使用任何快速求幂算法,但它仍然相对较慢)。

答案 1 :(得分:1)

很简单

  1. 将源顶点放入队列
  2. 检查队列是否为空,你完成了,如果不是
  3. 则没有路径
  4. 检查它是否是来自目标集的顶点之一,如果是,则完成,路径存在,如果不存在,则将该顶点的所有邻居放入队列重复陡峭2

答案 2 :(得分:1)

要查找任何路径,您可以使用深度优先搜索。要查找最短路径,可以使用广度优先搜索。要查找所有路径(因此路径数),您可以使用上述任一方法并修改为(a)在找到目标节点后继续,以及(b)查看其他路径是否可以到达目标节点(尽管可能已经到达目标节点)到达之前)。要找到节点最小权重的路径(在加权图中),您可以使用Dijkstra算法(无负边缘),Bellman-Ford(负边缘OK)或Floyd-Warshall(无负周期)。

答案 3 :(得分:1)

你只想测试路径的存在,所以从图论的角度来看,你最好的选择是使用BFS。

你有一个源顶点 src 和一组 S tgt 目标顶点。

由于你的图表在BFS结束时是无向的,你将拥有包含 src 的连通组件的顶点集。只需检查 S tgt 是否是该集的子集。

总结一下:

  1. S bfs 成为顶点的空哈希集
  2. src 开始执行BFS:
    1. 当您发现顶点 v 时,请将其插入 S bfs
  3. 执行 S bfs S tgt 的交集,以获取可从中找到的所有目标顶点 SRC

答案 4 :(得分:0)

由于您正在寻求一个简单的解决方案,我会使用广度优先搜索。一个不太简单的解决方案将涉及诸如All-Pairs最短路径算法之类的东西来确定图中每对节点之间的最短路径。

相关问题