Пример #1
0
	def computeDistances(self, src_node, dest_node_list): # uses Dijkstra

		g = self._graph

		dest_node_ids = set([a.getLeafId() if a is not None else -1 for a in dest_nodes ])

		if src_node is None or not any(dest_nodes):
			return [None]*len(dest_list)

		search_front_queue = SortedList()

		search_front_queue.add((0,src_node.getLeafId()))
		search_front_p = {}
		target_distances = {}
		frozen = set()

		loops = 0

		while search_front_queue:
			loops += 1
			d,a = search_front_queue.pop(0)
			if a in frozen: # ignore duplicates
				continue

			# target found
			if a == dest_node_ids:
				target_distances[a] = d
				dest_node_ids.remove(a)
				if len(dest_node_ids) == 0:
					break

			frozen.add(a)

			node = g.getNode(a)

			for adj in node.getAdjacencies().keys():
				if adj in frozen: # don't try to even check nodes that have been already frozen
					continue

				new_d = d + node.distanceTo(g.getNode(adj))

				# route to adj through a is longer than what we already had. Dismiss
				if adj in search_front_p and new_d > search_front_p[adj]:
					continue

				search_front_p[adj] = new_d
				# this might add duplicate adj items (ideally we would delete any previous insertion)
				# because we can't easily erase from the queue.
				search_front_queue.add((new_d, adj))

		distances = []
		for t in dest_node_ids:
			try:
				distances.append(target_distances[t])
			except:
				distances.append(None)

		return distances
Пример #2
0
	def computeRoute(self, src_node, dest_node): # uses A*

		graph = self._graph

		src_node_id = src_node.getLeafId()
		dest_node_id = dest_node.getLeafId()

		frontier = SortedList()
		frontier.add((0,src_node_id,src_node))
		cost_so_far = {src_node_id:0}
		came_from = {}

		#loops = 0
		
		while frontier:
			#loops += 1
			g,node_id,node = frontier.pop(0)
			
			if node == dest_node:
				break

			for adj_id,portal in node.getAdjacencies().iteritems():
				adj = graph.getNode(adj_id)

				new_cost = cost_so_far[node_id] + node.distanceTo(adj)

				if adj_id not in cost_so_far or new_cost < cost_so_far[adj_id]:
					cost_so_far[adj_id] = new_cost
					h = node.distanceTo(dest_node) # the A* heuristic
					priority = new_cost + h
					frontier.add((priority,adj_id,adj))
					came_from[adj_id] = (node_id,portal)

		p = dest_node_id
		route = [(p,None)] # stores tuples: node_number, exit portal
		while p in came_from:
			prev,portal = came_from[p]
			route.append((prev, portal))
			p = prev

		route.reverse()

		return route