std::vector<unsigned> find_minimal_time_path(std::vector<std::vector<unsigned> > &paths) { double min_travel_time = std::numeric_limits<double>::infinity(); std::vector<unsigned> min_time_path; for (std::vector<std::vector<unsigned>>::const_iterator it = paths.begin(); it != paths.end(); ++it) { double currtime = compute_path_travel_time((*it)); // Do not consider paths that are empty (ex. currtime = 0) if (currtime < min_travel_time && currtime != 0) { min_travel_time = currtime; min_time_path = (*it); } } return min_time_path; }
// 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; }