我正在尝试计算未加权图上两个顶点之间的最短路径。我的图表来自 csv 文件,我将所有信息放在字典结构中: 编辑:
类图:
def __init__(self, directed=False):
self._directed = directed
self._number = 0
self._vertices = {}
def insert_vertex(self, x):
v = Vertex(x)
self._vertices[v] = {}
self._number = len(self._vertices)
return v
def insert_edge(self, u, v, x=None):
e = Edge(u, v, x)
self._vertices[u][v] = e
self._vertices[v][u] = e
def incident_edges(self, v, outgoing=True):
for edge in self._vertices[v].values():
if not self._directed:
yield edge
else:
x, y = edge.endpoints()
if (outgoing and x == v) or (not outgoing and y == v):
yield edge
def is_directed(self):
return self._directed
def vertex_count(self):
return self._number
def vertices(self):
return self._vertices.keys()
def edge_count(self):
total = sum(len(self._vertices[v]) for v in self._vertices)
return total if self._directed else total // 2
def edges(self):
result = set()
for secondary_map in self._vertices.values():
result.update(secondary_map.values())
return result
def get_edge(self, u, v):
edge = self._vertices[u].get(v)
if edge != None and self._directed:
_, x = edge.endpoints
if x != v:
edge = None
return edge
def degree(self, v, outgoing=True):
adj = self._vertices
if not self._directed:
count = len(adj[v])
else:
count = 0
for edge in adj[v].values():
x, y = edge.endpoints()
if (outgoing and x == v) or (not outgoing and y == v):
count += 1
return count
def remove_edge(self, u, v):
if u in self._vertices.keys() and v in self._vertices[u].keys():
del self._vertices[u][v]
del self._vertices[v][u]
def remove_vertex(self, v):
if v in self._vertices.keys():
lst = [i for i in self.incident_edges(v)]
for i in lst:
x, y = i.endpoints()
self.remove_edge(x,y)
del self._vertices[v]
#return v
def github_csv():
lista = []
with open('Github1.csv', 'r') as csv_file:
data = csv.DictReader(csv_file)
next(data)
for row in data:
lista.append(row)
rel_dict = {}
for d in lista:
if d["follower"] in rel_dict.keys():
rel_dict[d['follower']].append(d['followed'])
else:
rel_dict[d['follower']] = [d['followed']]
return rel_dict
git_hub() 的输出是:
{'9236': ['1570', '13256', '45703', '10005', '30355', '1564', '11917'], '13256': ['9236', '1570', '1563', '22390', '4140', '28106', '11914', '10005', '1567', '1565', '28464', '14922', '41223', '1564', '14613', '1569', '1934', '32872', '11917', '109144', '144589']}
def build_graph():
graph = Graph(True)
git = github_csv()
for k,v in git.items():
k_vertex = graph.insert_vertex(k)
for v_item in v:
v_item_vertex = graph.insert_vertex(v_item)
graph.insert_edge(k_vertex,v_item_vertex)
graph.printG()
return graph
输出类似于:
vertex 59216 grau_in: 1 grau_out: 1
(4140, 59216)
vertex 59570 grau_in: 1 grau_out: 1
(4140, 59570)
我正在使用以下内容来计算两个顶点之间的最短路径:
def shortest_path(graph, start, goal):
explored = []
queue = [[start]]
if start == goal:
print("Same Node")
return
while queue:
path = queue.pop(0)
node = path[-1]
if node not in explored:
neighbours = graph[node]
for neighbour in neighbours:
new_path = list(path)
new_path.append(neighbour)
queue.append(new_path)
if neighbour == goal:
print("Shortest path = ", *new_path)
return
explored.append(node)
print("So sorry, but a connecting" \
"path doesn't exist :(")
return
输出为:
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "C:\Program Files\JetBrains\PyCharm Community Edition 2020.2.3\plugins\python-ce\helpers\pydev\_pydev_bundle\pydev_umd.py", line 197, in runfile
pydev_imports.execfile(filename, global_vars, local_vars) # execute the script
File "C:\Program Files\JetBrains\PyCharm Community Edition 2020.2.3\plugins\python-ce\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "C:/Users/sandr/PycharmProjects/ProjetoEDA/main.py", line 334, in <module>
shortest_path(graph,'1563','133')
File "C:/Users/sandr/PycharmProjects/ProjetoEDA/main.py", line 271, in shortest_path
neighbours = graph[node]
TypeError: 'Graph' object is not subscriptable
有人可以帮助我理解我做错了什么吗?
答案 0 :(得分:0)
Class 本身不支持 [] 操作符,这意味着如果你定义了一个类 Foo 你不能这样做
foo = Foo()
a = foo[1] # throw subscriptable error
如果你想能够做graph[node],你需要定义getitem方法。有关 post 或 this post
的更多信息在你的代码中,你把图形作为图形的一个属性,所以如果你没问题,你可以使用graph._vertices[node]。您的图在您的 Graph 类中表示为 {Vertex: {Vertex: Edge}},因此节点必须是 Vertex 类的实例并返回一个看起来像 {Vertex: Edge} 的字典。
为了不迷失在自己的代码中,我建议您使用类型提示,然后您就会确切地知道自己在做什么。我知道这有点复杂,因为您必须安装 Visual Studio 代码和 pyright,但您肯定会更有效率,因为您将准确了解所用对象的类型。这将使调试更加容易。
答案 1 :(得分:0)
从您的代码的一般流程来看,我认为您希望 graph[node]
神奇地返回一系列相邻节点。同样,您需要了解您已实现(或选择)的接口。 Graph
中没有这样的设施。相反,您需要遍历 incident_edges
,处理每个此类边的目标节点。
for neighbour_edge in graph.incident_edges(node):
# access the edge endpoint that is *not* "node"
neighbour = neighbour_edge.??? # Again, your posting is incomplete. You'll have to do this part.