Skip to content

rfamilara - Graphs modules #743

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 64 additions & 9 deletions projects/adventure/adv.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,61 @@
# traversal_path = ['n', 'n']
traversal_path = []

# Create an empty dictionary to save all the visited rooms
visited = {}
# Create an empty list that will save your reverse path, allowing you to backtrack when neccesary
backtrackPath = []
# Save all possible movement options as keys, with their opposite directions as values
movementOptions = {'n': 's', 's': 'n', 'w': 'e', 'e': 'w'}
# Saves the current room (Room Number) in visited as a key, with each possible exit DIRECTION as values
visited[player.current_room.id] = player.current_room.get_exits()

# While not every room has been explored...
while len(visited) < len(room_graph):

# If the current room has not been visited...
# Save it as visited, check off where you came from, and see where you can go now
if player.current_room.id not in visited:
# Saves the current room in visited as a key (ROOM NUMBER), with each possible exit as values (DIRECTIONS)
visited[player.current_room.id] = player.current_room.get_exits()
# Saves the last direction in backtrackPath as the previousRoom
previousRoom = backtrackPath[-1]
print("previousRoom(Checking Rooms Case): ", previousRoom)
print("backtrackPath: ", backtrackPath)
print("Currently in: ", player.current_room.id)
# Remove the direction you just came from as a possible exit
visited[player.current_room.id].remove(previousRoom)

elif len(visited[player.current_room.id]) > 0:
# Save the last of the current rooms exits as a variable
nextRoom = visited[player.current_room.id][-1]
print("nextRoom: ", nextRoom)
print("backtrackPath: ", backtrackPath)
print("Currently in: ", player.current_room.id)
# Remove that nextRoom from the current rooms exits
visited[player.current_room.id].pop()
# Add that to the answer path
traversal_path.append(nextRoom)
# Add the reverse movement to backtrackPath to keep track of where you're going!
backtrackPath.append(movementOptions[nextRoom])
# Go into that next room
player.travel(nextRoom)
print("Walking to:", nextRoom)

elif len(visited[player.current_room.id]) == 0:
# Save the direction you just came from as the previous room
previousRoom = backtrackPath[-1]
print("previousRoom(Backtracking Case): ", previousRoom)
print("backtrackPath: ", backtrackPath)
print("Currently in: ", player.current_room.id)
# Remove that direction from the backtrackPath
backtrackPath.pop()
# Add that to the answer path
traversal_path.append(previousRoom)
# Go back to the previous room
player.travel(previousRoom)
print("Walking BACK to:", previousRoom)



# TRAVERSAL TEST
Expand All @@ -51,12 +106,12 @@
#######
# UNCOMMENT TO WALK AROUND
#######
player.current_room.print_room_description(player)
while True:
cmds = input("-> ").lower().split(" ")
if cmds[0] in ["n", "s", "e", "w"]:
player.travel(cmds[0], True)
elif cmds[0] == "q":
break
else:
print("I did not understand that command.")
#player.current_room.print_room_description(player)
#while True:
# cmds = input("-> ").lower().split(" ")
# if cmds[0] in ["n", "s", "e", "w"]:
# player.travel(cmds[0], True)
# elif cmds[0] == "q":
# break
# else:
# print("I did not understand that command.")
36 changes: 35 additions & 1 deletion projects/ancestor/ancestor.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,37 @@
from util import Stack, Queue

def earliest_ancestor(ancestors, starting_node):
pass
# Create an empty queue
q = Queue()
# Create an list called 'path' housing the starting_node
path = [starting_node]
# Add that path(just the starting_node) to the queue
q.enqueue(path)
# While the queue is not empty
while q.size() > 0:
# Create a currentPath variable set to be our dequeued queue
currentPath = q.dequeue()
# Create an empty newPath list
newPath = []
# Create a changed variable set to False
changed = False
# Loop over each node in the currentPath
for node in currentPath:
# Loop through its ancestors
for ancestor in ancestors:
# If the value of the next ancestor is equal to the node:
if ancestor[1] == node:
# Append the current ancestor to the newPath
newPath.append(ancestor[0])
# Set its changed value to true
changed = True
# Add the new path to the queue
q.enqueue(newPath)
# If changed is False
if changed is False:
# If it has no parents
if currentPath[0] == starting_node:
return -1
# If it does return it
else:
return currentPath[0]
28 changes: 28 additions & 0 deletions projects/ancestor/util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

# Note: This Queue class is sub-optimal. Why?
class Queue():
def __init__(self):
self.queue = []
def enqueue(self, value):
self.queue.append(value)
def dequeue(self):
if self.size() > 0:
return self.queue.pop(0)
else:
return None
def size(self):
return len(self.queue)

class Stack():
def __init__(self):
self.stack = []
def push(self, value):
self.stack.append(value)
def pop(self):
if self.size() > 0:
return self.stack.pop()
else:
return None
def size(self):
return len(self.stack)

169 changes: 158 additions & 11 deletions projects/graph/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,68 +13,215 @@ def add_vertex(self, vertex_id):
"""
Add a vertex to the graph.
"""
pass # TODO
# This will hold the edges
self.vertices[vertex_id] = set()


def add_edge(self, v1, v2):
"""
Add a directed edge to the graph.
"""
pass # TODO
if v1 in self.vertices and v2 in self.vertices:
# There's an edge from v1 to v2
self.vertices[v1].add(v2)
else:
raise IndexError("nonexistent vert")

def get_neighbors(self, vertex_id):
"""
Get all neighbors (edges) of a vertex.
"""
pass # TODO
return self.vertices[vertex_id]

def bft(self, starting_vertex):
"""
Print each vertex in breadth-first order
beginning from starting_vertex.
"""
pass # TODO
# Create an empty queue
q = Queue()
# Init: enqueue the starting node
q.enqueue(starting_vertex)
# Create a set to store visited nodes
visited = set()
# While the queue isn't empty
while q.size() > 0:
# Dequeue the first item
currentNode = q.dequeue()
# If it's not been visited:
if currentNode not in visited:
# Do something with the node
print(currentNode)
# Add all neighbors to the queue
visited.add(currentNode)
# Add all neighbors to the queue
for nextNode in self.get_neighbors(currentNode):
if nextNode not in visited:
q.enqueue(nextNode)

def dft(self, starting_vertex):
"""
Print each vertex in depth-first order
beginning from starting_vertex.
"""
pass # TODO
# Create an empty stack
s = Stack()
# Create a set to store visited nodes
visited = set()
# Init: Push the starting node
s.push(starting_vertex)
# While the stack isn't empty
while s.size() > 0:
# Pop the first item
v = s.pop()
# If it's not been visited:
if v not in visited:
# Add all neighbors to the stack
visited.add(v)
# Do something with the node
print(v)
# Add all neighbors to the stack
for next_vert in self.get_neighbors(v):
s.push(next_vert)

def dft_recursive(self, starting_vertex):
def dft_recursive(self, starting_vertex, visited=set()):
"""
Print each vertex in depth-first order
beginning from starting_vertex.

This should be done using recursion.
"""
pass # TODO
# Add current node to visited
visited.add(starting_vertex)
# Print current node
print(starting_vertex)
# Save all current node neighbors to a variable
neighbors = self.get_neighbors(starting_vertex)
# While the current node has neighbors
while len(neighbors) > 0:
# For each neighnbor
for each in neighbors:
# If it has not been visited already
if each not in visited:
# Rerun the function, replacing the current node with the neighbor
self.dft_recursive(each, visited)
# If it has been visited
else:
return

def bfs(self, starting_vertex, destination_vertex):
"""
Return a list containing the shortest path from
starting_vertex to destination_vertex in
breath-first order.
"""
pass # TODO
# Create empty queue
q = Queue()
# Enqueue the starting node
q.enqueue([starting_vertex])
# Create a set for visited vertices
visited = set()
# While queue is not empty
while q.size() > 0:
# Create current path variable set to first node in q
currentPath = q.dequeue()
# Set the last node in the currentPath to a variable
lastNode = currentPath[-1]
# If it hasnt been visited
if lastNode not in visited:
# Check if it is the destination
if lastNode == destination_vertex:
# Return the path if it is
return currentPath
# If it is not the target
else:
# Add the lastNode to visited
visited.add(lastNode)
# Set the lastNode neighbors to variable
neighbors = self.get_neighbors(lastNode)
# For each of lastNodes neighbors
for neighbor in neighbors:
# Copy the path current path
copy = currentPath[:]
# Add the neighbor
copy.append(neighbor)
# Add the copy to the q
q.enqueue(copy)

def dfs(self, starting_vertex, destination_vertex):
"""
Return a list containing a path from
starting_vertex to destination_vertex in
depth-first order.
"""
pass # TODO
# Create empty stack
s = Stack()
# Push the starting node
s.push([starting_vertex])
# Create a set for visited vertices
visited = set()
# While stack is not empty
while s.size() > 0:
# Create current path variable set to first node in s
currentPath = s.pop()
# Set the last node in the currentPath to a variable
lastNode = currentPath[-1]
# If it hasnt been visited
if lastNode not in visited:
# Check if it is the destination
if lastNode == destination_vertex:
# Return the path if it is
return currentPath
# If it is not the target
else:
# Add the lastNode to visited
visited.add(lastNode)
# Set the lastNode neighbors to variable
neighbors = self.get_neighbors(lastNode)
# For each of lastNodes neighbors
for neighbor in neighbors:
# Copy the path current path
copy = currentPath[:]
# Add the neighbor
copy.append(neighbor)
# Add the copy to the s
s.push(copy)

def dfs_recursive(self, starting_vertex, destination_vertex):
def dfs_recursive(self, starting_vertex, destination_vertex, path=Stack(), visited=set()):
"""
Return a list containing a path from
starting_vertex to destination_vertex in
depth-first order.

This should be done using recursion.
"""
pass # TODO
# Create a path, this will be None the first time this function runs
currentPath = path.pop()
# If currentPath is None
if currentPath == None:
# Make currentPath the starting vertex
currentPath = [starting_vertex]
# Check if the last node in the currentPath is not in visited
if currentPath[-1] not in visited:
# Add the last node to visited
visited.add(currentPath[-1])
# For each of the last nodes neighbors
for neighbor in self.get_neighbors(currentPath[-1]):
# If the neighbor is the destination
if neighbor == destination_vertex:
# Append that neighbor to the currentPath
currentPath.append(neighbor)
# Return the currentPath
return currentPath
# Create a copy of the currentPath
copy = currentPath.copy()
# Add the neighbor to the copy
copy.append(neighbor)
# Push the copy to the reoccuring path
path.push(copy)
# Rerun the function with updated values
return self.dfs_recursive(starting_vertex, destination_vertex, path, visited)


if __name__ == '__main__':
graph = Graph() # Instantiate your graph
Expand Down
Loading