Finding shortest paths of a C ++ directed graph

For the last week I have implemented Digraph by parsing the input file. The graph has no cycles. I successfully created a graph, used methods to return the number of vertices and edges, and rendered a topological view of the graph. The schedule consists of different core courses and their prerequisites. Here is my graph:

class vertex{
public:
    typedef std::pair<int, vertex*> ve;     
    std::vector<ve> adjacency;              
    std::string course;                     
    vertex(std::string c){
        course = c;
    }
};

class Digraph{
public:
    typedef std::map<std::string, vertex *> vmap;           
    vmap work;
    typedef std::unordered_set<vertex*> marksSet;           
    marksSet marks;
    typedef std::deque<vertex*> stack;                      
    stack topo;
    void dfs(vertex* vcur);                                 
    void addVertex(std::string&);                           
    void addEdge(std::string& from, std::string& to, int cost);     
    int getNumVertices();                                   
    int getNumEdges();                                      
    void getTopoSort();                                     

};

      

Implementation

//function to add vertex to the graph
void Digraph::addVertex(std::string& course){
    vmap::iterator iter = work.begin();
    iter = work.find(course);
    if(iter == work.end()){
        vertex *v;
        v = new vertex(course);
        work[course] = v;
        return;
    }
}

//method to add edges to the graph
void Digraph::addEdge(std::string& from, std::string& to, int cost){
    vertex *f = (work.find(from)->second);
    vertex *t = (work.find(to)->second);
    std::pair<int, vertex *> edge = std::make_pair(cost, t);
    f->adjacency.push_back(edge);
}

//method to return the number of vertices in the graph
int Digraph::getNumVertices(){
    return work.size();
}

//method to return the number of edges in the graph
int Digraph::getNumEdges(){
    int count = 0;
    for (const auto & v : work) {
         count += v.second->adjacency.size();
     }
     return count;
}

//recursive function used by the topological sort method
void Digraph::dfs(vertex* vcur) {
  marks.insert(vcur);
  for (const auto & adj : vcur->adjacency) {
    vertex* suc = adj.second;
    if (marks.find(suc) == marks.end()) {
      this->dfs(suc);
    } 
  }
  topo.push_front(vcur);
}

//method to calculate and print out a topological sort of the graph
void Digraph::getTopoSort(){
    marks.clear();
    topo.clear();
    for (const auto & v : work) {
        if (marks.find(v.second) == marks.end()) {
            this->dfs(v.second);
        }
    }
    // Display it
   for (const auto v : topo) {
    std::cout << v->course << "\n";
  }
}

      

In the last part of my implementation, I tried to do 2 things. Find the shortest path from the first vertex to all other vertices, and also find the shortest path that visits each vertex and returns to the first. I completely lost this implementation. I assumed from reading I need to use Dijkstra's algorithm to implement it. I've tried the last 3 days to no avail. Has my digraph installed a bad way to accomplish these steps? Any guidance is appreciated.

+3


source to share


1 answer


The fact that there are no loops makes the task much easier. Finding the shortest paths and the smallest "grand tour" is O (n).

Implement Dijkstra and run it without a "target" node; just keep driving until all nodes have been visited. Once each node is marked (with its distance to the root), you can start at any node and follow the shortest (and only) path back to the root, always going to the only neighbor whose distance is less than this one. If you want, you can easily build these paths as you go and tag each node the full path back to the root, but copying those paths can push the cost to O (n 2 ) if you're not careful.



And once all the nodes are marked, you can create a minimal grand tour. Start at the root; when you visit a node, iterate over your invisible neighbors (i.e. all but the one you just came from), visiting each, and then return the one you came from. (I can put this with more mathematical rigor, or give an example if you like.)

+2


source







All Articles