Exemple #1
0
void Graph::extendPath(std::vector<int> &path, int sink, int est_dist, bool rev = 0) const{
        bool tarfound = 0;
        while (true) {
                std::vector<int> next;
                if (rev) {
                        next = getInEdges(path.back());
                } else {
                        next = getOutEdges(path.back());
                }
                int good_next = -2;
                for (int i = 0; i < next.size(); ++i) {
                        if (std::find(path.begin(), path.end(), next[i]) != path.end()) {
                                return;
                        }
                        if (next[i] == sink || getSizeOfNode(next[i]) - (k_ - 1) < 2 * est_dist) {
                                if (good_next > -2) {
                                        good_next = -1;
                                } else {
                                        good_next = i;
                                }
                        }
                }
                if (good_next > -1) {
                        path.push_back(next[good_next]);
                        if (!tarfound && next[good_next] == sink) {
                                tarfound = 1;
                        }
                } else {
                        return;
                }
        }
}
Exemple #2
0
int reachStatus(NFA nfa, int status_index, wchar_t c)
{
    int i, e_index;
    assert(nfa);
    assert(status_index>=0 && status_index<Array_length(nfa->statusArray));
    
    Status  currStatus;
    Array_T outEdges;
    Edge    e;

    currStatus = Array_get(nfa->statusArray, status_index);
    outEdges = getOutEdges(currStatus);
    if (!outEdges)
        return -1;

    for (i=0; i<Array_length(outEdges); i++)
    {
        e_index = *(int*)Array_get(outEdges, i);
        e = Array_get(nfa->edgeArray, e_index);
        if (crossEdge(e, c))
        {
            return getStatusID(gettoStatus(e));
        }
    }
    return -1;
}
Exemple #3
0
static void DFS(Status fromS, NFA nfa, Array_T closure, int inverse[], int color[], int set)
{
    int     i, index, from, to;
    Edge    e;
    Status  toS;

    from = getStatusID(fromS);
    color[from] = 1;
    inverse[from] = set;
    Array_append(closure, &from);
    
    Array_T edgeArray   =   getEdgeArray(nfa);
    Array_T outEdges_indice = getOutEdges(fromS);
    if (!outEdges_indice)
        return;

    for (i=0; i<Array_length(outEdges_indice); i++)
    {
        index   =   *(int*)Array_get(outEdges_indice, i);  
        e       =   (Edge)Array_get(edgeArray, index);
        if (isEpsilon(e))
        {
            toS     =   gettoStatus(e);
            to      =   getStatusID(toS);
            if (color[to] == 0)
                DFS(toS, nfa, closure, inverse, color, set);
        }
    }
}
	    /**
	     * @brief Returns all vertices, that are adjacent (connected) to *vertex*
	     *
	     */
	    std::vector<Vertex> getAdjacentVertices(const Vertex vertex){
		std::vector<Vertex> adjacentVertices;
		for(std::pair<Vertex, Edge> e: getOutEdges(vertex)){
		    adjacentVertices.push_back(e.first);
		}

		return adjacentVertices;
	    }
std::vector<DirectedFlowGraph::DirectedFlowEdge> DirectedFlowGraph::getAllEdges(
    const Node& start_node)
{
  std::vector<DirectedFlowGraph::DirectedFlowEdge> out_edges, in_edges, result;

  out_edges = getOutEdges(start_node);
  in_edges = getInEdges(start_node);

  result.insert(result.end(), out_edges.begin(), out_edges.end());
  result.insert(result.end(), in_edges.begin(), in_edges.end());
  return result;
}
Exemple #6
0
std::string Graph::concatenateNodes(std::vector<int> const &path) const{
        if (path.size() == 0) {
                return "";
        }
        std::string result = getSequenceOfNode(path[0]);
        for (int i = 1; i < path.size(); ++i) {
                if (path[i] == 0) {
                        continue;
                }
                std::vector<int> next = getOutEdges(path[i - 1]);
                if (std::find(next.begin(), next.end(), path[i]) == next.end()) {
                        std::cout << "Path does not exist\n";
                }
                result += getSequenceOfNode(path[i]).substr(k_ - 1);
        }
        return result;
}
Exemple #7
0
//dijkstra, but take special care if source == sink,
//we do not want trivial paths!
//considers seq length, not nodecount!
//the limit parameter is a hard cut-off for the length of allowed paths
std::vector<int> Graph::findMinSeqLenPath(int source, int sink, int limit) const{
        std::map<int/*node*/, std::pair<int/*dist*/, int/*prev*/>> nodes;
        std::deque<int> queue;
        //only relevant when source == sink
        int cycle_len = -1;
        int visited = 1;
        nodes[source] = (std::pair<int, int>(0, -1));
        queue.push_back(source);
        auto compare_nodes_dijkstra = [&](int a,int b)-> bool {
                return nodes[a].first < nodes[b].first;
        };
        int max_visited = 100;
        while (!queue.empty() && visited < max_visited) {
                int node = queue.front();
                queue.pop_front();
                if (node == sink && (cycle_len > 0 || node != source)) {
                        //we are done
                        break;
                }
                std::vector<int> nbs = getOutEdges(node);
                for (int i = 0; i < nbs.size(); ++i) {
                        int dist = nodes[node].first + getSizeOfNode(nbs[i]) - (k_ - 1);
                        if (dist < limit) {
                                std::map<int, std::pair<int, int>>::iterator it = nodes.find(nbs[i]);
                                if (it == nodes.end()) {
                                        //nbs[i] has not yet been reached
                                        nodes[nbs[i]] = std::pair<int, int>(dist, node);
                                        queue.push_back(nbs[i]);
                                        ++visited;
                                } else {
                                        //nbs[i] has already been reached
                                        //no need to push to queue!
                                        if (dist < (*it).second.first) {
                                                (*it).second.first = dist;
                                                (*it).second.second = node;
                                                
                                        }
                                        //we found a cycle
                                        if (source == sink && source == nbs[i]) {
                                                if (cycle_len < 0 || dist < cycle_len) {
                                                        cycle_len = dist;
                                                        (*it).second.second = node;
                                                }
                                        }
                                }
                        }
                }
                std::sort(queue.begin(), queue.end(), compare_nodes_dijkstra);
        }
        std::vector<int> path;
        path.push_back(sink);
        std::map<int, std::pair<int, int>>::iterator it = nodes.find(sink);
        if (it == nodes.end() || (source == sink && cycle_len == -1)) {
                path.push_back(0);
                path.push_back(source);
        } else {
                //sink is found
                path.push_back((*it).second.second);
                while (path.back() != source) {
                        path.push_back(nodes[path.back()].second);
                }
        }
        std::reverse(path.begin(), path.end());
        return path;
}
Exemple #8
0
// The same kind of process as DirectedPath but takes an input of 
// a vector of destinations, and the weight of each intersection
// is not added with the hueristic estimation.
// the function will return a path as soon as one of the destination
// is reached , which means that this destination can be reached in 
// the least time.
vector<unsigned> Dijkstra(unsigned startid, vector<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);
    priority_queue<pair<unsigned, double>, vector<pair<unsigned, double>>, comparenorm> Q;
    vector<unsigned> Path;
	vector<unsigned> testdraw;//DEBUG
   dist[startid] = 0;
    Q.push(make_pair(startid, 0));
    unsigned destination = endid[0];
    bool found = false;
    unordered_map<unsigned, unsigned>* outedges;
    /**************************DEBUG USE***************************/
//    bool DEBUG = 0; //enable to draw the process of computing the path
    /***************************************************************/
    while (!Q.empty()) {
//        vector<unsigned> testdraw;
        unsigned currentid = Q.top().first;
        Q.pop();
        for (vector<unsigned>::iterator iter = endid.begin(); iter != endid.end(); iter++) {
            if (currentid == *iter) {
                destination = *iter;
                found = true;
            }
        }
        if (found) break;
        if (flag[currentid] != 1) {
            flag[currentid] = 1;
            outedges = &getOutEdges(currentid);
            
            for (unordered_map<unsigned, unsigned>::const_iterator iter = outedges->begin(); iter != outedges->end(); iter++) {
                unsigned path_segment = iter->first;
                unsigned nextid = iter->second;

                double travel_time = find_segment_travel_time(path_segment) + dist[currentid];

                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 ((dist[nextid] == 0) || (travel_time < dist[nextid])) {
                    dist[nextid] = travel_time;
                    prev[nextid] = make_pair(currentid, path_segment);
                    Q.push(make_pair(nextid, dist[nextid]));
                }

                
            }
        }
    }

    unsigned iter = destination;
    while ((iter != startid) && (dist[destination] != 0)) {
        pair<unsigned, unsigned> idandpath = prev[iter];
        Path.insert(Path.begin(), idandpath.second);
        iter = idandpath.first;      
    }
//	if (DEBUG) {
//	DrawPath(Path, t_color(255, 0, 0));
//	}
    return Path;
}
Exemple #9
0
// 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;
}