I'm trying to implement kruskal's algorithm in Python 3.7.
So I wrote a programm "bfs" to do breadth first search which I want to use to check that the edges that are added to the minimum spanning tree in kruskal's algorithm don't create a circle.
from collections import deque #we import a queue structure
def bfs(G, startnode, endnode=None):
B = {startnode}
Q = deque([startnode])
L = []
while Q:
v = Q.pop()
L.append(v)
#If a final node was specified we will end the search there (including the final node)
if v == endnode:
break
for neighbor in G.neighbors(v):
if not neighbor in B:
B.add(neighbor)
Q.appendleft(neighbor)
return L
The code above should be correct and is posted for the sake of completness. Following up we have kruskal's algorithm implementation:
import networkx as nx
def kruskal_bfs(G):
V =nx.Graph()
edges=sorted(G.edges(data=True), key=lambda t: t[2].get('weight', 1)) #sorts the edges (from stackoverflow)
E_F = set([]) #mimimum spanning tree
for edge in edges:
E_F.add((edge[0],edge[1])) #add edge to the mimumum spanning tree
V.add_edges_from(list(E_F)) #combine it with the nodes for bfs
startnode = edge[0]
if bfs(V,startnode) == bfs(V, ):
E_F.remove(edge)
V.remove_edges_from(list(V.edges())) #reset edges of V
return E_F
The part where I have if bfs(V,startnode) == bfs(V, ):
is where I'm kinda stuck, how can I complete this if condition. I tried extending bfs
to include some form of "circle detection". That did not work however.
Instead of adding the edge and checking for a circle, compare the trees before you add the edge and add it only if the vertices are not connected.
Also, working with UNION-FIND
will be more efficient.