简体   繁体   中英

Kruskels MST algorithm in python seems to be not quite right

I was implementing the Kruskel's algorithm in Python. But it isn't giving correct answers for dense graphs. Is there any flaw in the logic?? The algo I am using is this:

1) Store all vertices in visited

2) Sort all the edges wrt their weights

3) Keep picking the smallest edge until all vertices, v, have visited[v]=1

This is what I have tried:

def Kruskal(weighted_graph):
    visited = {}
    for u,v,_ in weighted_graph:
        visited[u] = 0
        visited[v] = 0

    sorted_edges = deque(sorted(weighted_graph, key = lambda x:x[2]))
    mstlist = []
    sumi=0
    while 0 in visited.values():
        u,v,w = sorted_edges.popleft()
        if visited[u] == 0  or visited[v] == 0:
            mstlist.append((u,v))
            visited[u] = 1
            visited[v] = 1
            sumi += w
    return (sumi,mstlist)

input is a list of tuples..a single tuple looks like this (source,neighbor,weight) The Minimum spanning tree sum which I am calculating is coming out to be wrong for dense graphs. Please help. Thank you!

Your condition for adding the edge is if visited[u] == 0 or visited[v] == 0 , so you require that one of the adjacent nodes is not connected to any edge you have added to your MST so far. For the algorithm to work correctly, however, it is sometimes necessary to add edges even if you have already "visited" both nodes. Consider this very simple graph:

[
    (A, B, 2),
    (B, C, 3),
    (C, D, 1),
]

visual representation:
[A]---(2)---[B]---(3)---[C]---(1)---[D]
  • Your algorithm would first add the edge (C, D) , marking C and D as visited.
  • Then, it would add the edge (A, B) , marking A and B as visited.
  • Now, you're only left with the edge (B, C) . The MST for this graph obviously contains this edge. But your condition fails -- both B and C are marked as visited. So, your algorithm doesn't add that edge.

In conclusion, you need to replace that check. You should check whether the two nodes that the current edge connects are already connected by the edges that you have added to your MST so far. If they are, you skip it, otherwise you add it.

Usually, disjoint-set data structures are used for implementing this with a good run time complexity (see the pseudocode on wikipedia ). However, your code so far already has bad run time complexity as 0 in visited.values() has to linearly search through the values of the dictionary until it either reaches the end or finds an element with value 0, so it might be enough for you to do something simpler.

You can find some implementations of the algorithm using disjoint-set data structures on the internet, eg here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM