Advertisement
Guest User

find_path.py

a guest
Jan 22nd, 2017
181
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.88 KB | None | 0 0
  1. # An algorithm to find whether or not a path exists between two vertices A and B
  2.  
  3. # A graph will be implemented as a dictionary, where the keys are the vertex values and the values are lists that list al of the vertices that the key vertex is connected to.
  4.  
  5. # Example: See http://i.imgur.com/ZGx58Lj.gif. It will be implemented as
  6. graph1 = {
  7.             'A': ['C', 'D'],
  8.             'B': ['D', 'F'],
  9.             'C': ['A', 'G'],
  10.             'D': ['A', 'B', 'E', 'H'],
  11.             'E': ['D', 'G', 'H'],
  12.             'F': ['B', 'H'],
  13.             'G': ['C', 'E'],
  14.             'H': ['D', 'E', 'F'],
  15.             'J': ['I'],
  16.             'I': ['J', 'K'],
  17.             'K': ['I']
  18.          }
  19.  
  20. # We want to write a function find_path that accepts a graph and two vertices to either return False if there exists no path, or a list containing one path if there exists a path.
  21.  
  22. # Idea: Do a breadth first search algorithm, starting from node1. Keep track of "node" and "previous" information in the queue
  23.     # Whenever adding a node to the queue, we must make sure that
  24.         # (0) if it's equal to node2, then return true
  25.         # (1) it's not already 'visited'
  26.         # (2) it's not already in the queue
  27.  
  28. from collections import deque
  29.  
  30. def find_path(graph, v1, v2):
  31.     # Create a visisted_from dictionary, that keeps track of whether a vertex was visited or not.
  32.         # If it was visited, then the value is its source node
  33.         # If it was not visited, then the value is False
  34.     visited_from = { vertex : False for vertex in graph if vertex != v1}
  35.  
  36.     # Queue for keeping track of which vertex to check next in breadth first search
  37.     queue = deque([])
  38.  
  39.     # Initialize queue with the starting node
  40.     for vertex in graph[v1]:
  41.         # Elements of the queue look like [vertex, source_node]
  42.         queue.append([vertex, v1])
  43.         visited_from[vertex] = v1
  44.  
  45.     while queue:
  46.         vertex, source = queue.popleft()
  47.  
  48.         if vertex == v2:
  49.             path = [source, v2]
  50.             while visited_from.get(source, False):
  51.                 path.insert(0, visited_from[source])
  52.                 source = visited_from[source]
  53.             return path
  54.  
  55.         visited_from[vertex] = source
  56.  
  57.  
  58.         for adjacent_vertex in graph[vertex]:
  59.             if visited_from.get(adjacent_vertex, True):
  60.                 continue
  61.             elif vertex in [ vertex_info[0] for vertex_info in queue ]:
  62.                 continue
  63.             else:
  64.                 queue.append([adjacent_vertex, vertex])
  65.  
  66.     return False
  67.  
  68. print(find_path(graph1, 'A', 'H'))
  69. # => ['A', 'D', 'H']
  70.  
  71. print(find_path(graph1, 'A', 'B'))
  72. # => ['A', 'D', 'B']
  73.  
  74. print(find_path(graph1, 'H', 'C'))
  75. # => ['H', 'D', 'A', 'C']
  76.  
  77. print(find_path(graph1, 'B', 'G'))
  78. # => ['B', 'D', 'E', 'G']
  79.  
  80. print(find_path(graph1, 'C', 'F'))
  81. # => ['C', 'A', 'D', 'B', 'F']
  82.  
  83. print(find_path(graph1, 'G', 'K'))
  84. # => False
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement