The following is the implementation of Dijkstra's algorithm, which I wrote from the pseudocode in the Wikipedia article. A graph with approximately 40,000 nodes and 80,000 edges requires 3 or 4 minutes. Is this something like the correct order? If not, what's wrong with my implementation?
struct DijkstraVertex { int index; vector<int> adj; vector<double> weights; double dist; int prev; bool opt; DijkstraVertex(int vertexIndex, vector<int> adjacentVertices, vector<double> edgeWeights) { index = vertexIndex; adj = adjacentVertices; weights = edgeWeights; dist = numeric_limits<double>::infinity(); prev = -1; // "undefined" node opt = false; // unoptimized node } }; void dijsktra(vector<DijkstraVertex*> graph, int source, vector<double> &dist, vector<int> &prev) { vector<DijkstraVertex*> Q(G); // set of unoptimized nodes G[source]->dist = 0; while (!Q.empty()) { sort(Q.begin(), Q.end(), dijkstraDistComp); // sort nodes in Q by dist from source DijkstraVertex* u = Q.front(); // u = node in Q with lowest dist u->opt = true; Q.erase(Q.begin()); if (u->dist == numeric_limits<double>::infinity()) { break; // all remaining vertices are inaccessible from the source } for (int i = 0; i < (signed)u->adj.size(); i++) { // for each neighbour of u not in Q DijkstraVertex* v = G[u->adj[i]]; if (!v->opt) { double alt = u->dist + u->weights[i]; if (alt < v->dist) { v->dist = alt; v->prev = u->index; } } } } for (int i = 0; i < (signed)G.size(); i++) { assert(G[i] != NULL); dist.push_back(G[i]->dist); // transfer data to dist for output prev.push_back(G[i]->prev); // transfer data to prev for output } }
source share