我编写了一个Graph类,它接受一个图形对象并返回所述图形对象的邻接列表。我正在使用这个类中的graph_str来构造一个函数 - 给定一个起点 - 执行prim的算法并输出父数组作为结果(访问的每个节点的父节点列表)。
prim的算法解释 - https://www.youtube.com/watch?v=cplfcGZmX7I
如果假设起点为零,我有这个工作,但我不确定如何制作它,以便如果起点是一个不同的数字,它将从那里开始。
我上课的是:
class Graph:
def __init__(self, graph_str):
self.graph_str = []
graph_str = graph_str.splitlines()
for i in graph_str:
i = (i.split())
self.graph_str.append(i)
directed_helper = self.graph_str[0]
directed_score = directed_helper[0]
weighted_helper = self.graph_str[0]
weighted_score = weighted_helper[1]
self.weighted = weighted_score
self.directed = directed_score
self.graph_str.pop(0)
if self.directed == ("D"):
self.directed = True
elif self.directed == ("U"):
self.directed = False
if self.weighted == ("W"):
self.weighted = True
elif self.weighted != ("W"):
self.weighted = False
if self.weighted == False:
self.edge_number = graph_str[0]
self.edge_number = list(self.edge_number)
self.edge_number = self.edge_number[2]
self.edge_number = int(self.edge_number)
self.adjacency_list = [[] for _ in range(self.edge_number)]
elif self.weighted == True:
self.edge_number = graph_str[0]
self.edge_number = list(self.edge_number)
self.edge_number = self.edge_number[4]
self.edge_number = int(self.edge_number)
self.adjacency_list = [[] for _ in range(self.edge_number)]
if self.weighted == False:
if self.directed == True:
for s in self.graph_str:
self.first_element = s[0]
self.first_element = int(self.first_element)
self.second_element = s[1]
self.second_element = int(self.second_element)
self.adjacency_list[self.first_element].append((self.second_element, None))
elif self.directed == False:
for t in self.graph_str:
self.first_element = t[0]
self.first_element = int(self.first_element)
self.second_element = t[1]
self.second_element = int(self.second_element)
self.adjacency_list[self.first_element].append((self.second_element, None))
self.adjacency_list[self.second_element].append((self.first_element, None))
elif self.weighted == True:
if self.directed == True:
for t in self.graph_str:
self.first_element = t[0]
self.first_element = int(self.first_element)
self.second_element = t[1]
self.second_element = int(self.second_element)
self.third_element = t[2]
self.third_element = int(self.third_element)
self.adjacency_list[self.first_element].append((self.second_element, self.third_element))
if self.directed == False:
for t in self.graph_str:
self.first_element = t[0]
self.first_element = int(self.first_element)
self.second_element = t[1]
self.second_element = int(self.second_element)
self.third_element = t[2]
self.third_element = int(self.third_element)
self.adjacency_list[self.first_element].append((self.second_element, self.third_element))
self.adjacency_list[self.second_element].append((self.first_element, self.third_element))
(self.adjacency_list)
到目前为止我写的函数是:
from collections import defaultdict
from heapq import *
def prim( graph, start):
conn = defaultdict( list )
nodes = []
parents_array = [None]
for n1,n2,c in graph.graph_str:
c = int(c)
conn[ n1 ].append( (c, n1, n2) )
conn[ n2 ].append( (c, n2, n1) )
for i in graph.graph_str:
a = i[0]
nodes.append(a)
mst = []
used = set( nodes[ 0 ] )
usable_edges = conn[ nodes[0] ][:]
heapify( usable_edges )
while usable_edges:
cost, n1, n2 = heappop( usable_edges )
if n2 not in used:
used.add( n2 )
mst.append( ( n1, n2, cost ) )
for e in conn[ n2 ]:
if e[ 2 ] not in used:
heappush( usable_edges, e )
for i in mst:
a = i[0]
parents_array.append(a)
return parents_array
现在举一些例子。此代码适用于以下示例,起点为0:
graph_str = """\
U W 7
0 1 5
0 2 7
0 3 12
1 2 9
2 3 4
1 4 7
2 4 4
2 5 3
3 5 7
4 5 2
4 6 5
5 6 2
"""
print(prim(Graph(graph_str), 0))
输出:
[None, 0, 0, 2, 5, 5, 2]
然而,我还是以起点开始工作。例如:
graph_str = """\
U W 3
0 1 1
1 2 2
2 0 3
"""
print(prim(Graph(graph_str), 0))
print(prim(Graph(graph_str), 1))
print(prim(Graph(graph_str), 2))
应输出:
[None, 0, 1]
[1, None, 1]
[1, 2, None]
任何帮助都会非常感激:)