Graph 如何在图中找到最小生成树的总数?

Graph 如何在图中找到最小生成树的总数?,graph,minimum-spanning-tree,spanning-tree,Graph,Minimum Spanning Tree,Spanning Tree,我不想找到所有的最小生成树,但我想知道它们有多少,下面是我考虑的方法: 使用prim或kruskal算法找到一个最小生成树,然后找到所有生成树的权重,当它等于最小生成树的权重时,递增运行计数器 我找不到任何方法来计算所有生成树的权重,而且生成树的数量可能非常大,所以这种方法可能不适合这个问题。 由于最小生成树的数量是指数型的,所以将它们计算起来不是一个好主意 所有权重均为正值 我们还可以假设,在图表中,权重出现的次数不会超过三次 顶点数将小于或等于40000 边缘数将小于或等于100000

我不想找到所有的最小生成树,但我想知道它们有多少,下面是我考虑的方法:

  • 使用prim或kruskal算法找到一个最小生成树,然后找到所有生成树的权重,当它等于最小生成树的权重时,递增运行计数器
我找不到任何方法来计算所有生成树的权重,而且生成树的数量可能非常大,所以这种方法可能不适合这个问题。 由于最小生成树的数量是指数型的,所以将它们计算起来不是一个好主意

  • 所有权重均为正值
  • 我们还可以假设,在图表中,权重出现的次数不会超过三次
  • 顶点数将小于或等于40000
  • 边缘数将小于或等于100000
图中只有一个最小生成树,其中顶点的权重不同。我认为求最小生成树数的最好方法一定是使用这个性质

编辑

我找到了解决这个问题的方法,但我不确定它为什么有效。谁能解释一下吗

解决方案:寻找最小生成树的长度的问题是众所周知的;寻找最小生成树的两个最简单的算法是Prim算法和Kruskal算法。在这两种算法中,Kruskal的算法按权重的递增顺序处理边。然而,考虑Kruskal算法的一个重要的关键点是:当考虑按权重排序的边的列表时,边缘可以被贪婪地添加到生成树中(只要它们不以某种方式连接已经连接的两个顶点)。

使用Kraskar算法考虑部分生成的生成树。我们已经插入了一些长度小于N的边,现在必须选择几个长度为N的边。算法规定,如果可能,我们必须在长度大于N的任何边之前插入这些边。但是,我们可以按照我们想要的任何顺序插入这些边。还要注意的是,无论插入哪条边,它都不会改变图形的连通性。(让我们考虑两个可能的图,一个从顶点A到顶点B的边,另一个没有图。第二个图必须有A和B作为同一个连通分量的一部分;否则A到B的边将被插入到一个点。)< /P>


这两个事实一起意味着,我们的答案将是使用Kruskal算法插入长度K的边(对于K的每个可能值)的方法数的乘积。因为任意长度的边最多有三条,不同的情况可以强制执行,并且可以在每一步之后确定连接的组件,就像通常一样。

查看Prim的算法,它说重复添加具有最低权重的边。如果有多条边具有可以添加的最低重量,会发生什么情况?选择其中一棵可能会产生与选择另一棵不同的树

如果您使用prim算法,并将其作为起始边对每条边运行,还可以练习遇到的所有关系。然后,您将得到一个包含Prim算法能够找到的所有最小生成树的林。我不知道这是否等于包含所有可能最小生成树的森林


这仍然归结为找到所有最小生成树,但我看不到简单的方法来确定不同的选择是否会产生相同的树。

MST及其在图形中的计数得到了很好的研究。例如,请参阅:。

我正在尝试解决的问题有高达100000条边。因此,从每条边运行prim的算法需要很长时间。您可以通过检查是否有任何中间图是您已经遇到的中间图来加快速度。任何这样的图都肯定会产生我们已经拥有的最小生成树。虽然这会消耗你的内存。无论如何,它都会保持缓慢。您可以同时为每个起始边运行算法:首先创建一个由Prim算法第一步的结果生成的所有树组成的森林。(从40k个顶点生成大约20k棵树)然后对该林中的每棵树执行算法的下一步,并创建一个包含两条边的树的新林(可能会删除更多重复的树)。每一步都会不断地消除重复,这种结构还可以轻松地处理多个可能性作为下一步,通过将所有可能性添加到下一代林中,您可以通过确定不同的相同加权边是否是同一个圆的一部分来确定它们是否形成同一个生成树。这可以通过DFS找到,有两种方法,最简单的方法是运行DFS,然后沿着得到的树的边的方向向上倾斜,然后再次运行它