来自广播公司的所有消息都通过路由器 A ,所以 A 看到每个消息的所有四个副本。路由器 C 只接收到其收听者每个消息的一个副本。然而,路由器 B 和 D 将收到每个消息的三个副本,因为路由器 B 和 D 在收听者 1,2和3 的最短路径上。当广播主机必须每秒发送数百条消息用于无线电广播,这是很多额外的流量。
用于实现 Prim 算法的 Python 代码如 Listing2 所示。Prim 算法类似于Dijkstra 算法,它们都使用优先级队列来选择要添加到图中的下一个顶点。
from pythonds.graphs import PriorityQueue, Graph, Vertex
def prim(G,start):
pq = PriorityQueue()
for v in G:
v.setDistance(sys.maxsize)
v.setPred(None)
start.setDistance(0)
pq.buildHeap([(v.getDistance(),v) for v in G])
while not pq.isEmpty():
currentVert = pq.delMin()
for nextVert in currentVert.getConnections():
newCost = currentVert.getWeight(nextVert)
if nextVert in pq and newCost<nextVert.getDistance():
nextVert.setPred(currentVert)
nextVert.setDistance(newCost)
pq.decreaseKey(nextVert,newCost)
Listing 2
下面的图(Figure 11 到 Figure 17)展示了在我们的样本树上运行的算法。我们从起始顶点开始。到所有其他顶点的距离被初始化为无穷大。看看 A 的邻居,我们可以更新另外两个顶点 B 和 C 的距离,因为通过 A 到 B 和 C 的距离小于无限。这将 B 和 C 移动到优先级队列的前面。通过将 B 和 C 的前导链接设置为指向 A 来更新前导链接。重要的是要注意,我们还没有正式向生成树添加 B 或 C。在将节点从优先级队列中删除之前,不会将其视为生成树的一部分。
因为 B 有最小的距离,我们看看 B。检查 B 的邻居,我们看到 D 和 E 可以更新。D 和 E 都获得新的距离值,并更新它们的前导链接。移动到优先级队列中的下一个节点,我们找到 C。只有仍在优先级队列中的节点是 F,因此我们可以更新到 F 的距离,并调整优先级队列中的 F 的位置。
现在我们检查与节点 D 相邻的顶点。我们发现可以更新 E 并且将从距离 6 减小到 4。当我们这样做时,我们将 E 上的前趋链接改变为指向 D,从而准备移植到生成树中不同的位置。算法的其余部分按照预期进行,将每个新节点添加到树中。