Advertisement
user_137

BFS

Apr 25th, 2014
145
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.83 KB | None | 0 0
  1. from collections import deque as dq
  2.  
  3. def directedBFS(digraph, start, end, maxTotalDist, maxDistOutdoors):
  4.  
  5.     def update_distances_dict(path):
  6.         if distances.has_key(path):
  7.             return distances[path]  # path already memorized
  8.         t, o = 0, 0
  9.         while len(path) > 1:
  10.             original_path = path[:]
  11.             bit = path[-1]
  12.             path = path[:-1]
  13.             if distances.has_key((bit, path[-1])):
  14.                 a, b = distances[(bit, path[-1])]
  15.             elif distances.has_key((path[-1], bit)):
  16.                 a, b = distances[(path[-1], bit)]
  17.             else:
  18.                 a, b = maxDist, maxDist
  19.             t += a
  20.             o += b
  21.             if distances.has_key(path):
  22.                 a, b = distances[path]
  23.                 t += a
  24.                 o += b
  25.                 distances[original_path] = (t, o)
  26.                 break
  27.         return t, o
  28.  
  29.     start = Node(start)
  30.     end = Node(end)
  31.     q = dq([[start]])
  32.     #import ipdb; ipdb.set_trace()  # XXX BREAKPOINT
  33.     path = [[start, -1, 0, 0]]  # list of lists, node, dist, odist, child number
  34.     lpath = set([start])  # use set instead of list for in comparison (faster)
  35.     spath = []  # list of nodes for current shortest path
  36.     td, od, finished = 0, 0, 0
  37.     distances = {}  # dictionary for td and od values (faster access)
  38.     # this dictionary will store td and od with keys = path effectively
  39.     # memoizing the distance lookup element of the BFS
  40.     maxDist = 0
  41.     for n_dict in digraph.edges.iteritems():
  42.         for n_list in n_dict:
  43.             if isinstance(n_list, list):
  44.                 for e_list in n_list:
  45.                     twodistances = (float(e_list[1][0]), float(e_list[1][1]))
  46.                     distances[(n_dict[0], e_list[0])] = twodistances
  47.                     maxDist += twodistances[0]
  48.     tdspath = maxDist; odspath = maxDist
  49.  
  50.     while len(q) != 0:
  51.         tmpPath = q.popleft()
  52.         lastNode = tmpPath[len(tmpPath) - 1]
  53.         td, od = update_distances_dict(tuple(tmpPath))
  54.         if td <= tdspath and td <= maxTotalDist and od <= maxDistOutdoors:
  55.             if lastNode == end:
  56.                 # calc length and add to dict distances
  57.                 # update best tdspath and spath if better
  58.                 # don't add back to q, wait to fall out the end
  59.                 #return tmpPath
  60.                 if td < tdspath:
  61.                     tdspath = td
  62.                     spath = tmpPath[:]
  63.                     odspath = od
  64.             else:
  65.                 for linkNode in digraph.childrenOf(lastNode):
  66.                     if linkNode not in tmpPath:
  67.                         newPath = tmpPath + [linkNode]
  68.                         q.append(newPath)
  69.     if spath != [start] and spath:
  70.         return [str(i) for i in spath]
  71.     else:
  72.         raise ValueError('No such path!')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement