def _octile(self, id1, id2): """ Returns the octile distance in KM between the two ID'd vertices. (x1, y1) [1] | | | [3] | . | . | . | . | . | 45( . [ ]----------[2] returns dist(1, 3) + dist(2, 3) """ x1, y1 = self.coords[id1] x2, y2 = self.coords[id2] dx, dy = abs(x2 - x1), abs(y2 - y1) if dx > dy: x3 = max(x1, x2) - dy y3 = y1 elif dx > dy: x3 = x1 y3 = max(y1, y2) - dx else: return haversine(x1, y1, x2, y2) return haversine(x3, y3, x2, y2) + haversine(x3, y3, x1, y1)
def worker(landmarks, graph, graph_coords, pids, out_q, counter): """ The worker function, invoked in a process. 'nums' is a list of numbers to factor. The results are placed in a dictionary that's pushed to a queue. """ lm_est = {} for lm_id, lm_coord in landmarks: lm_est[lm_id] = {} x, y = lm_coord for pid, coord in graph_coords.items(): lm_est[lm_id][pid] = haversine(x, y, coord[0], coord[1]) qtree = point_dict_to_quadtree(graph_coords, multiquadtree=True) lm_dists = defaultdict(list) l = len(graph_coords) for pid in pids: counter.value += 1 print counter.value, '/', l, ':', pid for landmark, _ in landmarks: try: d = lm_exact_dist(pid, landmark, graph, graph_coords, lm_est) except KeyError: d = None lm_dists[pid].append(d) out_q.put(lm_dists)
def _manhattan(self, id1, id2): """ Returns the Manhattan distance in KM between the two ID'd vertices. (x1, y1) [1] | | | | (x2, y2) [3]-----------[2] (x1, y2) returns dist(1, 3) + dist(2, 3) """ x1, y1 = self.coords[id1] x2, y2 = self.coords[id2] x3, y3 = x1, y2 return haversine(x3, y3, x2, y2) + haversine(x3, y3, x1, y1)
def _euclidean(self, id1, id2): """ Returns the distance in KM between the two ID'd vertices. Arguments: id1, id2 -- IDs matching vertices in self.coords """ x1, y1 = self.coords[id1] x2, y2 = self.coords[id2] return haversine(x1, y1, x2, y2)
def find_closest_node(target, quadtree, rng=.01): x, y = target close_nodes = quadtree.query_range(x - rng, x + rng, y - rng, y + rng) best_node = None best_dist = float("inf") for point, nodes in close_nodes.items(): dist = haversine(point[0], point[1], target[0], target[1]) if dist < best_dist: best_dist = dist best_node = nodes if best_node: return best_node[0] else: return None
def find_closest_node(target, quadtree, rng=.01): x, y = target close_nodes = quadtree.query_range(x - rng, x + rng, y - rng, y + rng) best_node = None best_dist = float("inf") for point, nodes in close_nodes.iteritems(): dist = haversine(point[0], point[1], target[0], target[1]) if dist < best_dist: best_dist = dist best_node = nodes if best_node: return best_node[0] else: return None
def planar_landmark_selection(k, origin, coords, graph, qtree): origin_id = find_closest_node(origin, qtree) origin = coords[origin_id] sectors = section_plane(k, origin, coords) landmarks = [] for sector in sectors: max_dist = float("-inf") best_candidate = None for pid, coord in sector: cur_dist = haversine(origin[0], origin[1], coord[0], coord[1]) if cur_dist > max_dist and exact_dist(pid, origin_id, graph, coords): max_dist = cur_dist best_candidate = coord landmarks.append(best_candidate) return landmarks
def farthest_landmark_selection(k, origin, coords): landmarks = [origin] for _ in xrange(k): max_dist = float("-inf") best_candidate = None for pid, coord in coords.items(): cur_dist = 0 for lm in landmarks: cur_dist += haversine(lm[0], lm[1], coord[0], coord[1]) if cur_dist > max_dist and not coord in landmarks: max_dist = cur_dist best_candidate = coord landmarks.append(best_candidate) if len(landmarks) > k: landmarks.pop(0) return landmarks
def farthest_landmark_selection(k, origin, coords): landmarks = [origin] for _ in xrange(k): max_dist = float("-inf") best_candidate = None for pid, coord in coords.iteritems(): cur_dist = 0 for lm in landmarks: cur_dist += haversine(lm[0], lm[1], coord[0], coord[1]) if cur_dist > max_dist and not coord in landmarks: max_dist = cur_dist best_candidate = coord landmarks.append(best_candidate) if len(landmarks) > k: landmarks.pop(0) return landmarks
def landmark_distances(landmarks, graph, graph_coords): lm_est = {} for lm_id, lm_coord in landmarks: lm_est[lm_id] = {} x,y = lm_coord for pid, coord in graph_coords.iteritems(): lm_est[lm_id][pid] = haversine(x, y, coord[0], coord[1]) qtree = point_dict_to_quadtree(graph_coords, multiquadtree=True) lm_dists = defaultdict(list) l = len(graph_coords) for i, pid in enumerate(graph_coords): print i, '/', l, ':', pid for landmark, _ in landmarks: try: d = lm_exact_dist(pid, landmark, graph, graph_coords, lm_est) except KeyError: d = None lm_dists[pid].append(d) return lm_dists
def landmark_distances(landmarks, graph, graph_coords): lm_est = {} for lm_id, lm_coord in landmarks: lm_est[lm_id] = {} x, y = lm_coord for pid, coord in graph_coords.items(): lm_est[lm_id][pid] = haversine(x, y, coord[0], coord[1]) qtree = point_dict_to_quadtree(graph_coords, multiquadtree=True) lm_dists = defaultdict(list) l = len(graph_coords) for i, pid in enumerate(graph_coords): print i, '/', l, ':', pid for landmark, _ in landmarks: try: d = lm_exact_dist(pid, landmark, graph, graph_coords, lm_est) except KeyError: d = None lm_dists[pid].append(d) return lm_dists
def exact_dist(source, dest, graph, coords): dest_x, dest_y = coords[dest] pred_list = {source : 0} closed_set = set() unseen = [(0, source)] # keeps a set and heap structure while unseen: _, vert = heappop(unseen) if vert in closed_set: # needed because we dont have a heap with decrease-key continue elif vert == dest: return pred_list[vert] closed_set.add(vert) for arc, arc_len in graph[vert]: if arc not in closed_set: new_dist = (pred_list[vert] + arc_len) if arc not in pred_list or new_dist < pred_list[arc]: pred_list[arc] = new_dist x, y = coords[arc] heappush(unseen, (new_dist + haversine(x, y, dest_x, dest_y), arc)) return None # no valid path found
def _find_closest_vertex(self, target, rng=.01): """ Using the query_range function of the given quadtree, locate a vertex in the graph that is closest to the given point. Arguments: target -- (x, y) point to be matched to the graph. Returns: The ID of the vertex that is closest to the given point. """ x, y = target close_vertices = self.qtree.query_range(x - rng, x + rng, y - rng, y + rng) best_vertex = None best_dist = float("inf") for point, vertices in close_vertices.iteritems(): dist = haversine(point[0], point[1], target[0], target[1]) if dist < best_dist: best_dist = dist best_vertex = vertices[0] return best_vertex
def exact_dist(source, dest, graph, coords): dest_x, dest_y = coords[dest] pred_list = {source: 0} closed_set = set() unseen = [(0, source)] # keeps a set and heap structure while unseen: _, vert = heappop(unseen) if vert in closed_set: # needed because we dont have a heap with decrease-key continue elif vert == dest: return pred_list[vert] closed_set.add(vert) for arc, arc_len in graph[vert]: if arc not in closed_set: new_dist = (pred_list[vert] + arc_len) if arc not in pred_list or new_dist < pred_list[arc]: pred_list[arc] = new_dist x, y = coords[arc] heappush(unseen, (new_dist + haversine(x, y, dest_x, dest_y), arc)) return None # no valid path found
def _find_closest_vertex(self, target, rng=.01): """ Using the query_range function of the given quadtree, locate a vertex in the graph that is closest to the given point. Arguments: target -- (x, y) point to be matched to the graph. Returns: The ID of the vertex that is closest to the given point. """ x, y = target close_vertices = self.qtree.query_range(x - rng, x + rng, y - rng, y + rng) best_vertex = None best_dist = float("inf") for point, vertices in close_vertices.items(): dist = haversine(point[0], point[1], target[0], target[1]) if dist < best_dist: best_dist = dist best_vertex = vertices[0] return best_vertex
def worker(landmarks, graph, graph_coords, pids, out_q, counter): """ The worker function, invoked in a process. 'nums' is a list of numbers to factor. The results are placed in a dictionary that's pushed to a queue. """ lm_est = {} for lm_id, lm_coord in landmarks: lm_est[lm_id] = {} x,y = lm_coord for pid, coord in graph_coords.iteritems(): lm_est[lm_id][pid] = haversine(x, y, coord[0], coord[1]) qtree = point_dict_to_quadtree(graph_coords, multiquadtree=True) lm_dists = defaultdict(list) l = len(graph_coords) for pid in pids: counter.value += 1 print counter.value, '/', l, ':', pid for landmark, _ in landmarks: try: d = lm_exact_dist(pid, landmark, graph, graph_coords, lm_est) except KeyError: d = None lm_dists[pid].append(d) out_q.put(lm_dists)