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.
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
(ie 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)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.