I'm trying to implement a uniform cost search algorithm using node-edge-graph structure. And these are my classes
class Node:
def __init__(self, name: str, edges:list = [] ) -> None:
self.name = name
self.edges = edges
class Edge:
def __init__(self, start_node: Node, end_node: Node, weight: int) -> None:
self.start_node = start_node
self.end_node = end_node
self.weight = weight
class Graph:
def __init__(self, nodes:list = [], edges:list = []) -> None:
self.node_list = nodes
self.edge_list = edges
def add_node(self, node: Node) -> None:
self.node_list.append(node)
def add_edge(self,start_node:Node, end_node: Node, weight: int) -> None:
edge = Edge(start_node, end_node, weight)
self.edge_list.append(edge)
start_node.edges.append(edge)
end_node.edges.append(edge)
def get_node(self, name: str) -> Node:
for node in self.node_list:
if name == node.name:
return node
else:
raise CityNotFoundError(name)
def get_edges(self, node:str) -> list:
for node in self.node_list:
return node.edges
def get_weight(self, start: str, end: str) -> int:
start_node = self.get_node(start)
for edge in start_node.edges:
if edge.end_node.name == end:
return edge.weight
I implement a build_graph(filepath:str)->Graph
function that reads a csv file and builds a graph:
def build_graph(path: str) -> Graph:
file = open(path, "r")
next(file)
graph = Graph()
read_cities = list()
for line in file:
vars = line.strip().split(",")
city1 = vars[0]
city2 = vars[1]
distance = int(vars[2])
if city1 not in read_cities:
node1 = Node(city1)
read_cities.append(city1)
if city2 not in read_cities:
node2 = Node(city2)
read_cities.append(city2)
start_node = graph.get_node(city1)
end_node = graph.get_node(city2)
graph.add_edge(start_node, end_node, distance)
return graph
Finally this is my uniform_cost_search(graph, start, end)
function
def uniform_cost_search(graph: Graph, start: Node, end: Node):
if start not in graph.node_list:
raise CityNotFoundError(start.name)
if end not in graph.node_list:
raise CityNotFoundError(end.name)
frontier = PriorityQueue()
explored = set()
path = list()
frontier.put((0, start, path.append(start)))
while not frontier.empty():
cost, current_node, node_path = frontier.get()
if current_node == end:
return node_path, cost
explored.add(current_node)
for edge in graph.get_edges(current_node.name):
neighbor = edge.end_node
weight = edge.weight
if neighbor not in explored:
total_cost = cost + weight
path.append(neighbor)
frontier.put((total_cost, neighbor, path))
raise CityNotFoundError(end)
When I run my code I'm having an error like this
Traceback (most recent call last):
File "c:\Users\kamil\Desktop\PythonProjects\Project-1\last.py", line 115, in <module>
graph = build_graph(file_path)
^^^^^^^^^^^^^^^^^^^^^^
File "c:\Users\kamil\Desktop\PythonProjects\Project-1\last.py", line 73, in build_graph
graph.add_edge(start_node, end_node, distance)
File "c:\Users\kamil\Desktop\PythonProjects\Project-1\last.py", line 32, in add_edge
start_node.edges.append(edge)
AttributeError: 'NoneType' object has no attribute 'edges'
^^^^^^^^^^^^^^^^
Does not start_node have a list named edges that I declared as it is? Why is this happening?