def dp_search(digraph, start, end, toPrint = False, visited = None, memo = None): """ search of a weighted graph number of paths is bounded by approximately 3 ** 9000 this will not finish on the full graph this is for testing on small graphs visited is a list of strings representing the nodes that have been visited in this path of the recursion tree visited is used to prevent looping """ global num_calls num_calls += 1 if toPrint: if num_calls % 100000 == 0:print(num_calls) # if toPrint: # print("start: {}; end: {};".format(start.get_streets(), end.get_streets())) if visited == None: visited = [str(start)] # print(type(visited)) else: visited = visited + [str(start)] # print(str(start)) if memo == None: memo = {} #new dict path = Path(start) if start == end: return path shortest = None for node in digraph.children_of(start): if str(node) not in visited: #avoid cycles try: new_path = memo[(node, end)] except(KeyError): new_path = dp_search(digraph, node, end, toPrint, visited, memo)#find the shortest for this child if new_path == None: #no valid path was found continue #try the next child if shortest == None or new_path < shortest: memo[(node, end)] = new_path shortest = new_path if shortest != None:#a shortest path was found path.add_path(digraph, shortest) else:#no children of this node found a valid path path = None # pop up return path
def dynamic_search(digraph, start, end, toPrint = False, visited = None, memo = None): """ dynamic programming search of a weighted graph visited is a list of strings representing the nodes that have been visited in this path of the recursion tree visited is used to prevent looping memo is a dictionary of calculated shortest paths; node->path memo is used to prevent recalculation """ if toPrint: print("start: {}; end: {};".format(start.get_streets(), end.get_streets())) if memo == None: memo = {} if visited == None: visited = [str(start)] # print(type(visited)) else: visited += [str(start)] # print(str(start)) path = Path(start) if start == end: return path shortest = None for node in digraph.children_of(start): if str(node) not in visited: #avoid cycles try: new_path = memo[(node, end)] #see if a best shortest path has been calculated from this node except(KeyError): new_path = dynamic_search(digraph, node, end, toPrint, visited, memo)#find the shortest for this child if new_path == None: #no valid path was found continue #try the next child if shortest == None or new_path < shortest: memo[(node, end)] = new_path shortest = new_path if shortest != None:#a shortest path was found path.add_path(digraph, shortest) else:#no children of this node found a valid path path = None # pop up return path