假设您有一个输入文件:
<total vertices>
<x-coordinate 1st location><y-coordinate 1st location>
<x-coordinate 2nd location><y-coordinate 2nd location>
<x-coordinate 3rd location><y-coordinate 3rd location>
...
如何使用Prim的算法找到这些位置的MST?我知道这个问题通常使用邻接矩阵来解决。如果适用,任何参考文献都会很棒。
答案 0 :(得分:0)
如果你已经知道了,很容易。创建邻接矩阵adj [i] [j] =位置i和位置j之间的距离
答案 1 :(得分:0)
我将描述一些Prim的实现,希望能让你到达某个地方。
首先,您的问题并未指定边缘输入程序的方式。您有顶点总数和这些顶点的位置。你怎么知道哪些是连接的?
假设你有边(以及那些边的权重。就像上面所说的@doomster,它可能是点之间的平面距离,因为它们是坐标),我们可以开始考虑我们的实现。维基百科描述了导致三种不同运行时间的三种不同数据结构:http://en.wikipedia.org/wiki/Prim&#39; s_algorithm #Time_complexity
最简单的是邻接矩阵。正如您可能从名称中猜到的那样,矩阵描述的是&#34;相邻&#34;的节点。确切地说,有|v|
行和列(其中|v|
是顶点数)。 adjacencyMatrix[i][j]
的值因使用情况而异。在我们的例子中,它是节点i
和j
之间边缘的权重(即距离)(这意味着你需要以某种方式索引顶点。例如,你可能会将顶点添加到列表中并使用它们在列表中的位置。
现在使用这个邻接矩阵我们的算法如下:
v
创建新列表。
v
并将其添加到父字典中,并将其作为父字典(即&#34; root&#34;)。w
(对于非连接节点,您必须将其邻接矩阵值设置为某个特殊值.0,-1,int
max等)更新其&#34 ;距离&#34;在字典中adjacencyMatrix[v][w]
。这个想法是,它不是“无限远”。我们知道我们可以从v
到达那里。x
min(adjacencyMatrix[x][neighbor], distance[neighbor])
,并将其父级更新为x
。基本上,如果有更快的方式到达neighbor
那么应该更新距离字典以反映这一点;如果我们然后将neighbor
添加到新列表中,我们知道我们实际添加了哪个边缘(因为父词典表明其父级是x
)。我承认从维基百科页面到实际实施有一点飞跃,如上所述。我认为解决这个差距的最好方法就是强行执行代码。我的意思是,如果伪代码说&#34;找到min [blah]使得[foo]为真&#34;然后编写你需要执行的任何代码,并将其粘贴在一个单独的方法中。它绝对是低效的,但它是一个有效的实现。图算法的问题在于有30种方法可以实现它们,它们在性能上都有很大不同;维基百科页面只能概念性地描述算法。好处是,一旦你以一些方式实现它,你就可以快速找到优化(&#34;哦,如果我在这个单独的数据结构中跟踪这种状态,我可以进行这种查找方式!快&#34;)。顺便说一句,这个的运行时间是O(|V|^2)
。我太懒了,无法详细说明这种分析,但是因为:
O(|V|)
更糟糕的O(|V|)
次并花费O(|V|)
时间来查看字典以找到最小节点。所以基本上多次找到最小节点的总时间是O(|V|^2)
。O(|E|)
,因为我们只处理每个边缘一次。由于|E|
为O(|V|^2)
,因此O(|V|^2)
O(|V|)
O(|V| + |E|) = O(|E|)
O(|V|^2)
堆的实现是O(|E|log(|V|)
,它与上面非常相似。唯一的区别是更新距离是O(log|V|)
而不是O(1)
(因为它是堆),但是找到/删除min元素是O(log|V|)
而不是O(|V|)
(因为它是一堆)。时间复杂度在分析中非常相似,您最终会得到O(|V|log|V| + |E|log|V|) = O(|E|log|V|)
之类的内容。
实际上......我有点困惑为什么邻接矩阵实现关心它是一个邻接矩阵。它也可以使用邻接列表来实现。我认为关键部分是如何存储距离。在上面概述的实现中,我可能会离开,但我很确定它实现了Prim的算法满足维基百科所概述的时间复杂性约束。