0

I am working on a dijkstra algorithm using priority queues. I have been doing a lot of research, and I thought my code was following the algorithm, but I cannot get into the conditional when comparing for the shortest paths

    void dijkstra( int startingID ) {

        priority_queue<Vertex*, vector<Vertex*>, PathWeightComparer> dijkstra_queue{};
        vector<Vertex*> vert;
        vert = _vertices;
        int n = vert.size();
        vector< double > dis(n);

        for (int i = 0; i < n; i++)
        {
            dis[i] = std::numeric_limits< double >::infinity();
        }
        vert[startingID]->setPathWeight(startingID);
        dis[startingID] = 0;
        Vertex* temp = vert[startingID];
        dijkstra_queue.push(temp);


        while (!dijkstra_queue.empty())
        {
            double dist = dijkstra_queue.top()->getPathWeight();
            double u = dijkstra_queue.top()->getId();
            dijkstra_queue.pop();

            for (auto i : vert)
            {
                double v = i->getId();
                double weight = i->getPathWeight();
                double distance_total = dist + weight;
                cout << "distance_total " << distance_total << " dis[v] " << dis[v] << endl;
                if (distance_total < dis[v]) //PROBLEM
                {
                    dis[v] = distance_total;
                    Vertex* temp2 = i;
                    temp2->setPathWeight(dis[v]);
                    dijkstra_queue.push(temp2);
                }
            }
        }
    }
};

Here is the graph class

class Graph
{
    vector<Vertex*> _vertices;      // All vertices in the graph (vertex id == index)
    int _last_startingID = -1;

And here is the vertex class

class Vertex
{
private:
    int _id;                    // ID (key) of given vertice
    bool _known = false;        // Dijkstra's algorithm "known" flag
    Vertex* _path = nullptr;    // Dijkstra's algorithm parent vertex pointer
        // Weight of path through graph - starts at a true infinity (inf)
    double _path_weight = std::numeric_limits<double>::infinity();

I tried to only include the code that was relavent to only the dijkstra function, but if anything is unclear I can add more.

  • Have you tried using a debugger? – Ed Heal Nov 26 '17 at 09:25
  • I am working on the linux terminal so I do my best to print out values, but I didn't put those in the question @EdHeal – TrashMachine139 Nov 26 '17 at 09:26
  • My understanding is that `gdb` works from the terminal – Ed Heal Nov 26 '17 at 09:27
  • I haven't mastered gdb with multiple files, and in my code in order to run it in the terminal you have to use the command "make test" (at the file location) (there is a Makefile) and I have no idea how to make those things work in gbd. @EdHeal – TrashMachine139 Nov 26 '17 at 09:30
  • You need to compile with the `-g` flag (if my memory serves me right). Then read up on gdb. It will be a couple of hours of your life and be a perfect tool to your ability to write code – Ed Heal Nov 26 '17 at 09:32
  • I don't need them to actually connect because the distances are stored. Here is the code I am trying to learn from. http://www.geeksforgeeks.org/dijkstras-shortest-path-algorithm-using-priority_queue-stl/ @molbdnilo – TrashMachine139 Nov 26 '17 at 10:29

1 Answers1

0

Your implementation of the algorithm is incorrect.

After you pop() vertex u from the queue (because it's distance from the source is the lowest) you should ONLY inspect vertices that are directly reachable from u (i.e. an edge exists from u to that vertex).

Your current implementation seems to be looping through ALL vertices regardless of whether they are directly reachable from u or not, and perhaps as a result, you are doing something strange with the distance calculation that makes no sense. More specifically, distance_total in your implementation seems nonsensical.

The key idea behind Dijkstra's algorithm is:

dis[u] = must be shortest path from source to u since u was popped.
dis[v] = current_known_distance_to_v

Then, for all v where edge exists from u to v:
IF dis[u] + weight(u, v) < dis[v]:
    // going via u is better than the current best known distance to v
    dis[v] = dis[u] + weight(u, v)
wookie919
  • 3,054
  • 24
  • 32