def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ # Initialize frontier to just the starting position start = Node(state=source, parent=None, action=None) stack_frontier = StackFrontier() queue_frontier = QueueFrontier() stack_frontier.add(start) queue_frontier.add(start) # Count length in path for both technicks to determine the shortest one stack_frontier_path = [] queue_frontier_path = [] #Keep looping until solution found stack_frontier_path = search_frontier(stack_frontier, stack_frontier_path, target) queue_frontier_path = search_frontier(queue_frontier, queue_frontier_path, target) if len(stack_frontier_path) <= len(queue_frontier_path) and len( stack_frontier_path) != 0: return stack_frontier_path elif len(queue_frontier_path) != 0: return queue_frontier_path else: return None
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ # Initialize frontier to just the starting position start = Node(star=source, movie=None, parent=None) frontier = StackFrontier() # Start our search with the source frontier.add(start) # Initialize an empty explored set explored = set() # Keep looping until solution found while True: # If nothing left in frontier, then no path if frontier.empty(): return None # Choose a node from the frontier node = frontier.remove() # Mark node as explored explored.add(node.star) # Add neighbors to frontier for movie_id, person_id in neighbors_for_person(node.star): if not frontier.contains_star(person_id) and person_id not in explored: child = Node(star=person_id, movie=movie_id, parent=node) # If node is the goal, then we have a solution if person_id == target: return generate_path(child) frontier.add(child)
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ start = Node(state=source, parent=None, action=None) frontier = StackFrontier() frontier.add(start) explored = set() while True: if frontier.empty(): raise Exception("no solution") node = frontier.remove() if node.state == target: path = [] while node.parent is not None: path.append((node.action, node.state)) node = node.parent path.reverse() return path explored.add(node.state) for action, state in neighbors_for_person(node.state): if not frontier.contains_state(state) and state not in explored: child = Node(state=state, parent=node, action=action) frontier.add(child)
def shortest_path(source, target): start = Node(state=source, parent=None, action=None) frontier = StackFrontier() frontier.add(start) explored = set() if source == target: actions = [(start.action, target)] while True: if frontier.empty(): return None current_node = frontier.remove() explored.add(current_node.state) for movie_id, person_id in neighbors_for_person(current_node.state): if person_id not in explored and not frontier.contains_state( person_id): if person_id == target: target_node = Node(state=person_id, parent=current_node, action=movie_id) actions = [] while target_node.parent is not None: actions.append((target_node.action, target_node.state)) target_node = target_node.parent actions.reverse() return actions else: frontier.add( Node(state=person_id, parent=current_node, action=movie_id))
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ start = Node(state=source, parent=None, action=None) frontier = StackFrontier() frontier.add(start) nodesexplored = set() while True: if frontier.empty(): return None node = frontier.remove() if source == target: solutions = [] while node.parent is not None: solutions.append((node.action, node.state)) solutions.reverse() return solutions for movie_id, person_id in neighbors_for_person(node.state): if not (person_id in nodesexplored): child = Node(person_id, node, movie_id) frontier.add(child)
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ # TODO # Keep track of number of states explored num_explored = 0 # Initialize frontier to just the starting position start = Node(state=source, parent=None, action=None) frontier = StackFrontier() frontier.add(start) # Initialize an empty explored set explored = set() # Keep looping until solution found while True: # If nothing left in frontier, then no path if frontier.empty(): raise Exception("no solution") # Choose a node from the frontier node = frontier.remove() num_explored += 1 # If node is the goal, then we have a solution if node.state == target: person_id = [] movie_id = [] while node.parent is not None: person_id.append(node.state) movie_id.append(node.action) node = node.parent movie_id.reverse() person_id.reverse() solution = [] solution = tuple(zip(movie_id, person_id)) return list(solution) # Mark node as explored explored.add(node.state) # Add neighbors to frontier for action, state in neighbors_for_person(node.state): if not frontier.contains_state(state) and state not in explored: child = Node(state=state, parent=node, action=action) frontier.add(child)
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ # path = [] # for current_elem in neighbors_for_person(source): # movie_id = current_elem[0] # person_id = current_elem[1] # if person_id == target: # path.append([movie_id, person_id]) # elif movie_id not in movies and person_id not in people: # current_path = shortest_path(person_id, target) # if current_path is not None: # path.append(current_path) # if len(path) == 0: # return None # return path start = Node(state=source, parent=None, action=None) frontier = StackFrontier() frontier.add(start) explored = set() while True: if frontier.empty(): return None node = frontier.remove() if node.state == target: # actions = [] # cells = [] # while node.parent is not None: # actions.append(node.action) # cells.append(node.state) # node = node.parent # actions.reverse() # cells.reverse() # return actions, cells solution = [] while node.parent is not None: solution.append((node.action,node.state)) node = node.parent solution.reverse() return solution explored.add(node.state) for action, state in neighbors_for_person(node.state): if not frontier.contains_state(state) and state not in explored: child = Node(state=state, parent=node, action=action) frontier.add(child)
def shortest_path(source, target): """Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target.""" num_explored = 0 # Initialise frontier to the starting position start_movieid = people[source]["movies"] start = Node(state=source, parent=None, action=start_movieid) end_movieid = people[target]["movies"] end = Node(state=target, parent=None, action=end_movieid) frontier = StackFrontier() frontier.add(start) # Initilize an empty emplored set explored = set() # Loop till solution is found while True: #If no possible path, returns None. if frontier.empty(): raise Exception("no solution") # Choose a node from the frontier node = frontier.remove() num_explored += 1 #If node is the goal, then solution found solution = [] for movieid in end.action: if movieid in node.action: movie_person = set() #Follow parent nodes to find solution while node.parent: personid = names[node.state] movie_person = node.action, personid node = node.parent solution.append(movie_person) solution.reverse() return solution # Mark node as explored explored.add(node.state) # Add neighbours to frontier for movie_id, person_id in neighbors_for_person(names[node.state]): if not frontier.contains_state( person_id) and person_id not in explored: child = Node(state=person_id, parent=node, action=movie_id) frontier.add(child) return solution
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ # Keep count of steps num_explored = 0 # Initialize frontier to just the starting position start = Node(state=source, parent=None, action=None) frontier = StackFrontier() frontier.add(start) # Initialize an empty explored set explored = set() # Keep looping until solution found while True: # If nothing left in frontier, then no path if frontier.empty(): raise Exception("no solution") # Choose a node from the frontier node = frontier.remove() num_explored += 1 # If node is the goal, then we have a solution if node.state == target: actions = [] cells = [] while node.parent is not None: actions.append(node.action) cells.append(node.state) node = node.parent actions.reverse() cells.reverse() retVal = [ ] # list of tuples [(movie_id, person_id),(movie_id, person_id),(movie_id, person_id)] for i in range(len(actions)): retVal.append((actions[i], cells[i])) return retVal # Mark node as explored explored.add(node.state) # Add neighbors to frontier for action, state in neighbors_for_person(node.state): if not frontier.contains_state(state) and state not in explored: child = Node(state=state, parent=node, action=action) frontier.add(child)
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ # Keep track of steps num_of_steps = 0 # Initialize frontier to initial_node initial_node = Node(state=source, parent=None, action=None) frontier = StackFrontier() frontier.add(initial_node) # Make new explored set explored = set() while True: # Return no path if frontier empty if frontier.empty(): raise Exception("no solution") # Remove a node to explore node = frontier.remove() num_of_steps += 1 # If node is goal, make the path if node.state == target: cells = [] actions = [] while node.parent is not None: cells.append(node.state) actions.append(node.action) node = node.parent cells.reverse() actions.reverse() answer = [] for x in range(len(actions)): answer.append((actions[x], cells[x])) return answer # Mark node as explored explored.add(node.state) for action, state in neighbors_for_person(node.state): if not action or not state: return None elif not frontier.contains_state(state) and state not in explored: child = Node(state=state, parent=node, action=action) frontier.add(child)
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ # Initialize frontier to just the starting position start = Node(state=source, parent=None, action=None) frontier = StackFrontier() frontier.add(start) # Initialize an empty explored set explored = set() # Keep looping until solution found while True: # If nothing left in frontier, then no path if frontier.empty(): raise Exception("no solution") # Choose a node from the frontier node = frontier.remove() # If node is the goal, then we have a solution if node.state == target: moviess = [] actors = [] while node.parent is not None: moviess.append(node.action) actors.append(node.state) node = node.parent moviess.reverse() actors.reverse() solution = [] for i in range(len(moviess)): solution.append((moviess[i], actors[i])) return solution # Mark node as explored explored.add(node.state) # Add neighbors to frontier for movie_id, person_id in neighbors_for_person(node.state): if not frontier.contains_state( person_id) and person_id not in explored: child = Node(state=person_id, parent=node, action=movie_id) frontier.add(child)
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ # Initialize frontier to just the starting position start = Node(state=source, parent=None, action=None) frontier = StackFrontier() frontier.add(start) solution = [] # Initialize an empty explored set explored = set() # Keep looping until solution found while True: # If nothing left in the frontier, then no path if frontier.empty(): return None node = frontier.remove() # Look at neighbors for action, state in neighbors_for_person(node.state): if not frontier.contains_state(state) and state not in explored: child = Node(state=state, parent=node, action=action) frontier.add(child) if node.state == target: actions = [] cells = [] while node.parent is not None: actions.append(node.action) cells.append(node.state) node = node.parent actions.reverse() cells.reverse() for i in range(0, len(actions)): solutions += [(actions[i], state[i])] return solutions if child.state == target: path = [] while child.parent is not None: path.append((child.action, child.state)) child = child.parent path.reverse() return path explored.add(node.state)
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. Credit: adapted from CS50AI's maze.solve() function """ # Initialize frontier to just the starting position start = Node(state=source, parent=None, action=None) # Use breadth-first search to find shortest path frontier = StackFrontier() frontier.add(start) # Initialize an empty explored set explored = set() # Keep looping until solution found while True: # If nothing left in frontier, then no path if frontier.empty(): return None # Choose a node from the frontier node = frontier.remove() # Mark node as explored explored.add(node.state) # Add neighbors to frontier for movie, person in neighbors_for_person(node.state): if not frontier.contains_state(person) and person not in explored: child = Node(state=person, parent=node, action=movie) # If node is the goal, then we have a solution if child.state == target: path = [] while child.parent is not None: path.append((child.action, child.state)) child = child.parent path.reverse() return path # Otherwise add node to the frontier else: frontier.add(child)
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ # Initialize an empy frontier of the type specified at the top # of the module if SEARCH_TYPE == "DepthFirst": frontier = StackFrontier() elif SEARCH_TYPE == "BreadthFirst": frontier = QueueFrontier() else: raise Exception("Illegal search type") initialState = Node((None, source), None, None) # Starting node/person frontier.add( initialState) # Add the starting person id (source) to frontier exploredSet = set() # Store explored nodes # Search for the end state/person until no more nodes to explore # meaning there is no path to from start node to end node while not frontier.empty(): # Remove the current node from the frontier and add it to the # exploredSet currentNode = frontier.remove() exploredSet.add(currentNode.state) # Get neighbors of current node and add to frontier neighbors = neighbors_for_person(currentNode.state[1]) for neighbor in neighbors: if neighbor[1] == target: endNode = Node(neighbor, currentNode, None) return getSolutionPath(endNode) if not frontier.contains_state(neighbor) and (neighbor not in exploredSet): neighborNode = Node(neighbor, currentNode, None) # TODO what is an action frontier.add(neighborNode) return None # No solution found
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ #Initialize a BFS. frontier = StackFrontier() frontier.add(Node(state=source,parent=None,action=None)) #Setup the explored section explored = set() #Until a solution is found while True: #If the frontier is empty and no solution is found then there is no connection between the source and target. if frontier.empty(): raise Exception("No Valid Solution") #Extract a node from the frontier. node = frontier.remove() #If the node's person_id matches the id of the target the solution has been found. if node.state == target: movies = [] names = [] while node.parent is not None: movies.append(node.action) names.append(node.state) node = node.parent movies.reverse() names.reverse() solution = [] i = 0 while i < len(movies): solution.append((movies[i],names[i])) i += 1 return solution #Add the explored node to the explored set after exploring it. explored.add(node.state) #Find the movies that the actor has played in and what other actors are in those movies. for movie, name in neighbors_for_person(node.state): if not frontier.contains_state(name) and name not in explored: frontier.add(Node(state=name,parent=node,action=movie))
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ frontier = StackFrontier() start = Node(state=source,parent=None,action=None) solution = set() explored = set() frontier.add(start) while True: if frontier.empty() : raise Exception("No solution") node = frontier.remove() sourceNeighbors = neighbors_for_person(node.state) explored.add(node.state) for movie,person in sourceNeighbors : if target == person and node.state==source : solution.add((movie,source)) solution.add((movie,person)) return solution elif target == person and node.state != source : movieperson = [] while node.parent is not None: movieperson.append((node.action,node.state)) movieperson.reverse() solution = movieperson return solution else: if not frontier.contains_state(person) and person not in explored: frontier.add(Node(state=person,parent=node,action=movie))
def shortest_path(source, target): num_explored = 0 start = Node(state=source, parent=None, action=None) frontier = StackFrontier() frontier.add(start) explored = set() while True: if frontier.empty(): raise Exception("no solution") node = frontier.remove() num_explored += 1 if target == node.state: actions = [] states = [] result = [] while node.parent is not None: actions.append(node.action) states.append(node.state) node = node.parent actions.reverse() states.reverse() for action, state in zip(actions, states): result.append((action, state)) return result explored.add(node.state) for action, state in neighbors_for_person(node.state): if not frontier.contains_state(state) and state not in explored: child = Node(state=state, parent=node, action=action) frontier.add(child) raise NotImplementedError
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ Num_explored = 0 start = Node(state=source, parent=None, action=None) frontier = StackFrontier() frontier.add(start) explored = set() while True: if frontier.empty(): raise Exception("no solution)") node = frontier.remove() Num_explored += 1 print(Num_explored) if node.state == target: print("here is solution") solution = [] while node.parent is not None: solution.append((node.action, node.state)) print("getting ready...\n") node = node.parent return solution explored.add(node.state) for movie, state in neighbors_for_person(node.state): if not frontier.contains_state(state) and state not in explored: child = Node(state=state, parent=node, action=movie) frontier.add(child)
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ if source == target: return None num_explored_states = 0 start = Node(state=source, parent=None, action=None) frontier = StackFrontier() frontier.add(start) explored = set() while True: if frontier.empty(): return None node = frontier.remove() num_explored_states += 1 explored.add(node.state) for action, state in neighbors_for_person(node.state): if not frontier.contains_state(state) and state not in explored: child = Node(state=state, parent=node, action=action) if child.state == target: movie_list = [] people_path = [] while child.parent is not None: movie_list.append(child.action) people_path.append(child.state) child = child.parent movie_list.reverse() people_path.reverse() return list(zip(movie_list, people_path)) frontier.add(child)
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ sourcempid = list(neighbors_for_person(source)) #(movieId, personId), returns a set start = Node(state = source,parent=None,action=None) #start.state gives the person id stackFrontier = StackFrontier() stackFrontier.add(start) explored = set() while True: #checks if frontier is empty if stackFrontier.empty(): return None #removes the node while storing it into node node = stackFrontier.remove() explored.add(node.state) #Add other personId to frontier for tup in list(neighbors_for_person(node.state)): if not stackFrontier.contains_state(tup[1]) and tup[1] not in explored: child = Node(state=tup[1], parent=node, action=tup[0]) if child.state == target: #checks if the movies match cells = [] while child.parent is not None: cells.append((child.action,child.state)) child = child.parent cells.reverse() return cells else: stackFrontier.add(child)
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ # Initialize frontier to just the starting position start = Node(state=source, parent=None, action=None) frontier = StackFrontier() # frontier = QueueFrontier() frontier.add(start) # Keep track of number of states explored num_explored = 0 # Initialize an empty explored set exploreds = set() # keep looping until solution found while True: # if nothing left in frontier there is no path if frontier.empty(): return None # Remove a node from the frontier node = frontier.remove() num_explored += 1 # if node is the target, return the solution if node.state == target: solutions = [] # Follow parent nodes to find path while node.parent is not None: solutions = [(node.action, node.state)] + solutions node = node.parent return solutions else: # Add the node to the explored set exploreds.add(node.state) # Add neighbors to frontier neighors = neighbors_for_person(node.state) for action, state in neighors: if not frontier.contains_state( state) and state not in exploreds: child = Node(state=state, parent=node, action=action) frontier.add(child)
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ degrees = 0 start = Node(source, None, None, degrees) frontier = StackFrontier() frontier.add(start) explored = set() nodes_explored = 0 pairs = [] while True: if frontier.empty(): return None node = frontier.remove() nodes_explored += 1 print("Inside degree:", node.degree, "Nodes explored:", nodes_explored) if node.state == target: actions = [] cells = [] while node.parent is not None: actions.append(node.action) cells.append(node.state) node = node.parent actions.reverse() cells.reverse() for i in range(len(actions)): pairs.append((actions[i], cells[i])) return pairs explored.add(node.state) for movie_id, person_id in neighbors_for_person(node.state): if not frontier.contains_state(person_id) and person_id not in explored and node.degree < 6: child = Node(state=person_id, parent=node, action=movie_id, degree=node.degree + 1) frontier.add(child)
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ # Initialize frontier to just the starting position , start = Node(state=source, parent=None, action=None) frontier = StackFrontier() frontier.add(start) # Initialize an empty explored set explored = set() while True: if frontier.empty(): raise Exception("no solution") node = frontier.remove() # Mark node as explored explored.add(node.state) # Add neighbors id for a given name to frontier for movie_id, person_id in neighbors_for_person(node.state): if not frontier.contains_state( person_id) and person_id not in explored: if person_id == target: child = Node(state=person_id, parent=node, action=movie_id) list_solution = [] while node.parent is not None: list_solution.append((node.movie_id, node.person_id)) node = node.parent list_solution.reverse() return list_solution else: frontier.add( Node(state=person_id, parent=node, action=movie_id))
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ myqueue = StackFrontier() explored = set() finalList = [] node = Node(source, None, None) myqueue.add(node) while (not myqueue.empty()): node = myqueue.remove() explored.add(node.state) if node.state == target: movies = [] stars = [] while node.parent != None: finalList = [] movies.append(node.action) stars.append(node.state) node = node.parent movies.reverse() stars.reverse() for i in range(len(movies)): finalList.append((movies[i], stars[i])) return finalList for action, state in neighbors_for_person(node.state): if action == None and state == None: return None else: if state not in explored: nei = Node(state, node.state, action) myqueue.add(nei) return None
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ # TODO algo = 'BFS' explored = set() start = Node(source, parent=None, action=None) frontier = QueueFrontier() if algo == 'BFS' else StackFrontier() frontier.add(start) # Keep looping until solution found while True: # If nothing left in frontier, then no path if frontier.empty(): raise Exception("no solution") # Choose a node from the frontier node = frontier.remove() # If node is the goal, then we have a solution if node.state == target: path = [] while node.parent is not None: path.append((node.action, node.state)) node = node.parent path.reverse() return path # Mark node as explored explored.add(node.state) # Add neighbors to frontier for movie_id, person_id in neighbors_for_person(node.state): if not frontier.contains_state( person_id) and person_id not in explored: child = Node(state=person_id, parent=node, action=movie_id) if person_id == target: frontier.seed(child) else: frontier.add(child)
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ start = Node(source, None, None) frontier = StackFrontier() frontier.add(start) explored = set() while True: if frontier == None: raise Exception("None") node = frontier.remove() explored.add(node.state) neighbors = neighbors_for_person(node.state) for movie_id, person_id in neighbors: if not frontier.contains_state(person_id) and person_id not in explored: child = Node(person_id, node, movie_id) if child.state == target: path =[] node = child while node.parent is not None: path.append((node.action, node.state)) node = node.parent path.reverse() return path frontier.add(child)
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ start = Node(source, None, None) frontier = StackFrontier() frontier.add(start) explored = set() while True: if frontier.empty(): raise Exception("no solution") node = frontier.remove() if node == target: return node explored.add(node.state) # TODO raise NotImplementedError
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ import time frontier = StackFrontier() # frontier = QueueFrontier() start = Node(state=source, action=None, parent=None, step=0) frontier.add(start) explored_nodes = dict() explored_num = 0 solution = None hit_count = dict() start_time = time.time() # List all options which step is 3 for Emma and Jeniffer # solutions = [] while True: if frontier.empty(): print("Hit count: ", hit_count) print("Time cost: ", time.time() - start_time) print("Num of explored nodes: ", explored_num) return None if solution == None else solution[0] # return None if len(solutions)==0 else solutions node = frontier.remove() # Explored {person_id:(step, movie_id)} is recorded explored_nodes[node.state] = node.step explored_num += 1 parent_id = node.state for neighbor in neighbors_for_person(parent_id): # If the person is 5 steps away (or even more) from the source, give it up because of Six Degrees of Kevin Bacon, and it can definitely improve the performance if node.step > 5: break # If can find a shorter path/step than the explored (person_id, step) for the certain person, explore it, otherwise, give it up to improve performance if neighbor[1] != parent_id and not frontier.contains_state( neighbor[1]) and ( neighbor[1] not in explored_nodes.keys() or node.step + 1 < explored_nodes[neighbor[1]]): child = Node(state=neighbor[1], action=neighbor[0], parent=node, step=node.step + 1) if child.state == target: step = child.step # Recode the hit count for different steps/length of the path if step in hit_count.keys(): hit_count[step] += 1 else: hit_count[step] = 1 # Organize the being returned result via the node's parent link links = [] while child.parent is not None: links.append((child.action, child.state)) child = child.parent links.reverse() # Always fetch the shortest path if have.!!!! if solution == None or solution[1] > step: solution = (links, step) # if step == 3: # solutions.append(links) # If the child is the target, not explore other neighbors any more. break else: frontier.add(child)
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ # number of states explored steps = 0 # create start node and initialize frontier start = Node(state=source, parent=None, action=None) frontier = StackFrontier() # add start position to frontier frontier.add(start) # positions explored explored = set() # create loop to run until solution is found (or no solution) while True: # return error if no solution is found if frontier.empty(): raise Exception("no solution") # take last item added to list and increment number of steps by one node = frontier.remove() steps += 1 # if the target has been found, create lists to track pahtway for starts and associated movies if node.state == target: movies = [] stars = [] # work backwards until start state is reached, indicated by parent = None while node.parent is not None: movies.append(node.action) stars.append(node.state) node = node.parent # reverse lists because we were starting with solution movies.reverse() stars.reverse() # create a list of tuples to maintain association between movies and stars solution = zip(movies, stars) solution = list(solution) # return solution return solution # if the solution hasn't been found, add node to the explored list explored.add(node.state) if not node.state == target: # check all neighbors for the current node for movie_id, person_id in neighbors_for_person(node.state): # skip adding neighbors to the frontier if they are already there if not frontier.contains_state( person_id) and person_id not in explored: # add neighbors to the frontier, documenting their person_id as the state, parent, as the current node and action as movie_id child = Node(state=person_id, parent=node, action=movie_id) frontier.add(child)
def __init__(self, grid_size, start, end, walls): super().__init__(grid_size, start, end, walls) self.frontier = StackFrontier()