AI/Unit 1/Umaretiya_r_lab_0.py
2020-12-15 03:02:42 -05:00

139 lines
3.7 KiB
Python

# Name: Rushil Umaretiya
# Date: 09/18/2020
# Each Vertex object will have attributes to store its own name and its list of its neighboring vertices.
class Vertex:
def __init__(self, name, vertices):
self.name = name
self.vertices = vertices
def __str__(self):
return f'{self.name} {self.vertices}'
def __repr__(self):
return str(self.name)
# If the file exists, read all edges and build a graph. It returns a list of Vertexes.
def build_graph(filename):
try:
file = open(filename, 'r')
except:
return []
lines = file.read().strip().splitlines()
vertices = []
# Sorry about this solution Ms. Kim, it's not very efficient, but it makes sense.
# Create all the source verticies
for line in lines:
line = line.strip().split()
for vertex in vertices:
if vertex.name == line[0]:
break
else:
vertices.append(Vertex(line[0], []))
# Create all the ending verticies
for line in lines:
line = line.strip().split()
for vertex in vertices:
if vertex.name == line[1]:
break
else:
vertices.append(Vertex(line[1], []))
# Link them!
for line in lines:
line = line.strip().split()
source, end = None, None
for vertex in vertices:
if vertex.name == line[0]:
source = vertex
if vertex.name == line[1]:
end = vertex
if source != None and end != None:
break
source.vertices.append(end)
return vertices
# prints all vertices and adjacent lists of the given graph.
def display_graph(graph):
for vertex in graph:
print (vertex)
# checks if two Vertexes are reachable or not.
def is_reachable(fromV, toV, graph):
visited = []
Q = [fromV]
while len(Q) > 0:
state = Q.pop(0)
if state not in visited:
if state == toV:
return True
visited.append(state)
neighbours = state.vertices
for neighbour in neighbours:
Q.append(neighbour)
return False
# returns the length of the path from a Vertex to the other Vertex.
# If the other Vertex is not reachable, return -1. (Ex) Path cost of A to B to C is 2.
def path_cost(fromV, toV, graph):
if fromV == toV:
return 0
if not is_reachable(fromV, toV, graph):
return -1
visited = []
Q = [fromV]
while len(Q) > 0:
state = Q.pop(0)
if state not in visited:
if state == toV:
return len(visited)
visited.append(state)
neighbours = state.vertices
for neighbour in neighbours:
Q.append(neighbour)
# Test cases
g = build_graph(input("filename: ")) # build a graph
# To check if you build the graph with object correctly
for v in g:
print (v, v.vertices)
display_graph(g) # display the graph (edge list)
fromV, toV = None, None
print ("If you want to stop checking, type -1 for vertex values")
fromV_val, toV_val = input("From vertex value: "), input("To vertex value: ") # Get vertex values from user
while fromV_val != '-1':
# Find from and to Vertexes at graph
for v in g:
if v.name == fromV_val: fromV = v
if v.name == toV_val: toV = v
if fromV is None or toV is None:
print ("One or more vertex value does not exist.")
else:
print ("From {} to {} is reachable?".format(fromV_val, toV_val), is_reachable(fromV, toV, g))
print ("Path cost from {} to {} is".format(fromV_val, toV_val), path_cost(fromV, toV, g))
# Reset to test another case
fromV_val, toV_val = input("\nFrom vertex value: "), input("To vertex value: ")
fromV, toV = None, None