def calculate_transition_costs(self, source, targets): if not targets: return [] # All measurements in targets should be the same, since they # are grouped by measurement ID target_measurement = targets[0].measurement max_route_distance = self.calculate_max_route_distance( source.measurement, target_measurement) route_results = road_routing.road_network_route_many( (source.edge, source.location), [(tc.edge, tc.location) for tc in targets], self.get_road_edges, max_path_cost=max_route_distance) # Geodesic distance based on WGS 84 spheroid great_circle_distance = vincenty( (source.measurement.lat, source.measurement.lon), (target_measurement.lat, target_measurement.lon)).meters costs = [] for target, (path, route_distance) in zip(targets, route_results): if route_distance < 0: # Not reachable costs.append(-1) continue target.path[source] = path if ALGORITHM.name == 'HMM': # delta = abs(math.log(max(1, route_distance)) - math.log(max(1, great_circle_distance))) delta = abs(route_distance - great_circle_distance) costs.append(delta / self.beta) elif ALGORITHM.name == 'ST': delta = abs( math.log(max(1, route_distance)) - math.log(max(1, great_circle_distance))) costs.append(delta) elif ALGORITHM.name == 'FV': delta = 2 * self.sigma_z * self.sigma_z * route_distance / self.beta costs.append(delta) # They should be equivalent (only for testing): # for cost, target in zip(costs, targets): # single_cost = self.calculate_transition_cost(source, target) # assert abs(cost - single_cost) < 0.0000001 return costs
def calculate_transition_costs(self, source, targets): if not targets: return [] # All measurements in targets should be the same, since they # are grouped by measurement ID target_measurement = targets[0].measurement max_route_distance = self.calculate_max_route_distance( source.measurement, target_measurement) route_results = road_routing.road_network_route_many( (source.edge, source.location), [(tc.edge, tc.location) for tc in targets], self.get_road_edges, max_path_cost=max_route_distance) # Geodesic distance based on WGS 84 spheroid great_circle_distance = distance.vincenty( (source.measurement.lat, source.measurement.lon), (target_measurement.lat, target_measurement.lon)).meters costs = [] for target, (path, route_distance) in zip(targets, route_results): if route_distance < 0: # Not reachable costs.append(-1) continue target.path[source] = path delta = abs(route_distance - great_circle_distance) costs.append(math.exp(-delta / self.beta) / self.beta) # They should be equivalent (only for testing): # for cost, target in zip(costs, targets): # single_cost = self.calculate_transition_cost(source, target) # assert abs(cost - single_cost) < 0.0000001 return costs