// POI Intersection std::vector<std::pair<unsigned, unsigned> > closestIntersectiontoPOI(const std::vector<unsigned>& POI_IDs) { std::vector<std::pair<unsigned,unsigned> > POI_intersection_pair; for (std::vector<unsigned>::const_iterator it = POI_IDs.begin(); it != POI_IDs.end(); ++it) { LatLon POI_pos = getPointOfInterestPosition((*it)); double min_dist = std::numeric_limits<double>::infinity(); unsigned min_dist_intersection; // O(n) time complexity -- change to KD tree if lower time desired for (unsigned i = 0; i < getNumberOfIntersections(); i++) { LatLon intersection_pos = GVAR_intersection_positions[i]; double curdist = find_distance_between_two_points(POI_pos, intersection_pos); if (curdist < min_dist) { min_dist = curdist; min_dist_intersection = i; } } std::pair<unsigned,unsigned> poi_and_closest_intersection = { (*it), min_dist_intersection }; POI_intersection_pair.push_back(poi_and_closest_intersection); } return POI_intersection_pair; }
double heuristic_cost_straight_dist(unsigned const & point1, unsigned const & point2) { // Returns the time it takes to travel from intersection 1 to 2 (straight distance) double euclidean_dist = find_distance_between_two_points(point1, point2); // [M] euclidean_dist *= METERS_TO_KM; // [KM] euclidean_dist /= 100.0; // divided by [KM/h] -> [h] euclidean_dist *= 60.0; // multiplied by [min/h] -> [min] return euclidean_dist; }
min_priority_queue closestPOIstointer(unsigned intersect_id_start, std::vector<unsigned>& POI_IDs) { min_priority_queue queue; LatLon intersectpos = GVAR_intersection_positions[intersect_id_start]; for (std::vector<unsigned>::iterator it = POI_IDs.begin(); it != POI_IDs.end(); ++it) { double curdist = find_distance_between_two_points(intersectpos, getPointOfInterestPosition(*it)); queue.push(std::make_pair((*it), curdist)); } return queue; }
unsigned find_closest_intersection(t_point my_position, string input) { unsigned id = find_closest_intersection(my_position); vector<LatLon> POI_pos = find_POI_from_name(input); vector<unsigned> inter_ids = find_closest_intersection(POI_pos); double min_dist = 1e10; unsigned end_id = 0; for (vector<unsigned>::iterator iter = inter_ids.begin(); iter != inter_ids.end(); iter++){ LatLon id_pos = getIntersectionPosition(id); LatLon it_pos = getIntersectionPosition(*iter); double temp_dist = find_distance_between_two_points(id_pos, it_pos); if (temp_dist < min_dist) { min_dist = temp_dist; end_id = *iter; } } return end_id; }
// Use A* algorithm to calculate shortest path between intersections vector<unsigned> DirectedPath(unsigned startid, unsigned endid) { unordered_map<unsigned, bool> flag; //if node is visited unordered_map<unsigned, double> dist; //weight of edge unordered_map<unsigned, pair<unsigned, unsigned>> prev; //the previous node&edge of key prev[startid] = make_pair(startid, 0); LatLon end = getIntersectionPosition(endid); priority_queue<pair<unsigned, double>, vector<pair<unsigned, double>>, comparenorm> Q; // the node to be visited vector<unsigned> Path; Q.push(make_pair(startid, 0)); unordered_map<unsigned, unsigned>* outedges; //the out going edges of an intersection // unordered_map<unsigned, unordered_map<unsigned, pair<unsigned, unsigned>>>::iterator memo; // bool found_memo = false; // unsigned memoid = 0; /**************************DEBUG USE***************************/ bool DEBUG = 0; //enable to draw the process of computing the path /***************************************************************/ while (!Q.empty()) { unsigned currentid = Q.top().first; // accessing the weight of the edge, or distance Q.pop(); if (currentid == endid) break; if (flag[currentid] != 1) { flag[currentid] = 1; // memo = Memoize(currentid, endid); //unfinished implementation of memoization // if (memo != Memo.end()) { // found_memo = true; // memoid = currentid; // cout << "i broke out" <<endl; // break; // } // vector<unsigned> testdraw; //for debug use outedges = &getOutEdges(currentid); //obtain the outgoing edges and the other end point for (unordered_map<unsigned, unsigned>::const_iterator iter = outedges->begin(); iter != outedges->end(); iter++) { //for all the street segments around the current intersections //street segment id unsigned path_segment = iter->first; //the other end point intersection id unsigned nextid = iter->second; // how long it takes to travel through this segment double travel_time = find_segment_travel_time(path_segment) + dist[currentid]; //if the current street segment is on the same street with the next street segment if (getStreetSegmentStreetID(path_segment) != getStreetSegmentStreetID(prev[currentid].second)) travel_time += 0.25; // if (DEBUG) { // testdraw.push_back(path_segment); // DrawPath(testdraw, t_color(64, 153, 255)); // } // if the current path to next intersection is found to be faster than the // previous path, update the path and time if ((dist[nextid] == 0) || (travel_time < dist[nextid])) { dist[nextid] = travel_time; prev[nextid] = make_pair(currentid, path_segment); } // get the position of the next intersection id LatLon currentposition = getIntersectionPosition(nextid); // find the distance between the next intersection id and the end point double current_distance = find_distance_between_two_points(currentposition, end); double weight = ((dist[nextid]) + current_distance * 0.06 / 100); // put the intersection into the priority queue Q.push(make_pair(nextid, weight)); } } } // if(found_memo){ // unsigned iter = endid; // while (iter != memoid) { // pair<unsigned, unsigned> idandpath = ((memo->second).find(iter))->second; // Path.insert(Path.begin(), idandpath.second); // iter = idandpath.first; // } // endid = memoid; // } unsigned iter = endid; while ((iter != startid) && (dist[endid] != 0)) { pair<unsigned, unsigned> idandpath = prev[iter]; Path.insert(Path.begin(), idandpath.second); // if (DEBUG) { // bool OneWay = getStreetSegmentOneWay(idandpath.second); // StreetSegmentEnds ids = getStreetSegmentEnds(idandpath.second); // if (OneWay && (ids.from == iter)) { // cout << "ONEWAY PATH: " << idandpath.second << endl; // cout << "FROM: "<< ids.from << " TO: " << ids.to << endl; // cout << "INSTEAD OF: " << idandpath.first << " TO: " << iter <<endl; // bool connected = are_directly_connected(idandpath.first, iter); // cout << "ARE THEY DIRECTLY CONNECTED? " << connected << endl; // break; // } // } // Memo[iter] = prev; // prev.erase(iter); iter = idandpath.first; } if (DEBUG) { DrawPath(Path, t_color(255, 0, 0)); double computed_time = compute_path_travel_time(Path); if (computed_time == 0) cout <<"PATH FROM: "<< startid <<" TO "<< endid << " NOT FOUND"<<endl; } return Path; }