【问题标题】:Dijkstra's Algorithm with Adjacency Lists and Priority Queue具有邻接列表和优先级队列的 Dijkstra 算法
【发布时间】:2014-05-01 03:44:58
【问题描述】:
#include <iostream>
#include <fstream>
#include <functional>
#include <climits>
#include <vector>
#include <queue>
#include <list>


using namespace std;

struct Vertices {
    int vertex;
    int weight;
    Vertices(int v, int w) : vertex(v), weight(w) { };
    Vertices() { }
};

class CompareGreater {
    public:
        bool const operator()(Vertices &nodeX, Vertices &nodeY) {
            return (nodeX.weight > nodeY.weight) ;
        }
};

vector< list<Vertices> > adj;
vector<int> weights;
priority_queue<Vertices, vector<Vertices>, CompareGreater> Q;

int nrVertices, nrEdges;

void readData();
void Dijkstra(Vertices);
void writeData();

void writeData() {
    ifstream out;
    out.open("graph.txt");

    weights.resize(1);
    for (vector<int>::iterator it = weights.begin()+1; it != weights.end(); ++it) {
        cout << (*it) << " ";
    }

    out.close();
}

void readData() {
    ifstream myFile;
    myFile.open("graph.txt");

    int nodeX, nodeY, weight;

    myFile >> nrVertices >> nrEdges;

    adj.resize(nrVertices+1);
    weights.resize(1);

    for (int i = 1; i <= nrVertices; ++i) {
        weights.push_back(INT_MAX);
    }

    for (int i = 1; i <= nrEdges; ++i) {
        myFile >> nodeX >> nodeY >> weight;
        adj[nodeX].push_back(Vertices(nodeY, weight));
    }

    myFile.close();
}

void Dijkstra(Vertices startNode) {
    Vertices currVertex;

    weights[startNode.vertex] = 0;
    Q.push(startNode);

    while (!Q.empty()) {
        currVertex = Q.top();
        Q.pop();

        if (currVertex.weight <= weights[currVertex.vertex]) {
            for (list<Vertices>::iterator it = adj[currVertex.vertex].begin(); it != adj[currVertex.vertex].end(); ++it) {
                if (weights[it->vertex] > weights[currVertex.vertex] + it->weight) {
                    weights[it->vertex] = weights[currVertex.vertex] + it->weight;
                    Q.push(Vertices((it->vertex), weights[it->vertex]));
                }
            }
        }
    }
}

int main() {

    readData();
    Dijkstra(Vertices(1, 0));
    writeData();

    return 0;
}

所以这就是我到目前为止为了实现具有邻接列表的 Dijkstra 算法。但是,我的代码不会打印任何内容。有什么帮助吗?

Graph.txt 如下所示:

7
2
2  2
4  1
2
4  3
5  10
2
1  4
6  5
4
3  2
5  2
6  8
7  4
1
7  6
0
1
6  1

这意味着从顶点 1 到 7 依次存在 7 个顶点。 顶点 1 有 2 条边,一条连接到顶点 2,权重为 2,第二条连接到顶点 4,权重为 1。 顶点 2 有 2 条边,第一个到顶点 4,权重为 3,第二个到顶点 5,权重为 10。 顶点 3 有 2 条边,第一个到顶点 1,权重为 4,第二个到顶点 6​​,权重为 5。 等等。

【问题讨论】:

    标签: c++ algorithm list queue priority-queue


    【解决方案1】:

    这段代码:

    weights.resize(1);
    for (vector<int>::iterator it = weights.begin()+1; it != weights.end(); ++it) {
    

    会将weights 向量的大小调整为1,然后尝试打印出向量的第二个元素。由于不再有第二个元素,它不会打印任何内容。

    【讨论】:

    • 所以我应该将其设置为 weights.resize(nrVertices+1);
    • 为什么需要调整它的大小?您已经在readData 函数中填写了weights 向量。
    【解决方案2】:
    #include <iostream>
    #include <fstream>
    #include <functional>
    #include <climits>
    #include <vector>
    #include <queue>
    #include <list>
    
    using namespace std;
    
    struct Vertices {
        int vertex;
        int weight;
        Vertices(int v, int w) : vertex(v), weight(w) { };
        Vertices() { }
    };
    
    class CompareGreater {
        public:
            bool const operator()(Vertices &nodeX, Vertices &nodeY) {
                return (nodeX.weight > nodeY.weight) ;
            }
    };
    
    vector< list<Vertices> > adj;
    vector<int> weights;
    priority_queue<Vertices, vector<Vertices>, CompareGreater> Q;
    
    int nrVertices, nrEdges;
    
    void readData();
    void Dijkstra(Vertices);
    
    
    void readData() {
        ifstream myFile;
        myFile.open("graph.txt");
    
        int nodeX, nodeY, weight;
    
        myFile >> nrVertices >> nrEdges;
    
        adj.resize(nrVertices+1);
        //weights.resize(1);
    
        for (int i = 1; i <= nrVertices; ++i) {
            weights.push_back(INT_MAX);
        }
    
        for (int i = 1; i <= nrEdges; ++i) {
            myFile >> nodeX >> nodeY >> weight;
            adj[nodeX].push_back(Vertices(nodeY, weight));
        }
    
        //weights.resize(1);
        for (vector<int>::iterator itr = weights.begin()+1; itr != weights.end(); ++itr) {
            cout << (*itr) << " "<<endl;
        }
    
    
        myFile.close();
    }
    
    void Dijkstra(Vertices startNode) {
        Vertices currVertex;
    
        weights[startNode.vertex] = 0;
        Q.push(startNode);
    
        while (!Q.empty()) {
            currVertex = Q.top();
            Q.pop();
    
            //cout<<"Removed "<<&currVertex<<"from heap"<<endl;
    
            if (currVertex.weight <= weights[currVertex.vertex]) {
                for (list<Vertices>::iterator it = adj[currVertex.vertex].begin(); it != adj[currVertex.vertex].end(); ++it) {
                    if (weights[it->vertex] > weights[currVertex.vertex] + it->weight) {
                        weights[it->vertex] = weights[currVertex.vertex] + it->weight;
                        Q.push(Vertices((it->vertex), weights[it->vertex]));
                    }
                }
            }
        }
    }
    
    int main() {
    
        readData();
        Dijkstra(Vertices(1, 0));
    
        return 0;
    }
    

    所以这是我修改后的答案。但它只是打印出来:

    2147483647 
    2147483647 
    2147483647 
    2147483647 
    2147483647 
    2147483647 
    

    当我需要它打印出这样的东西时:

    V1: V2, 2; V4, 1
    V2: v4, 3; V5, 10
    V3: V1, 4; V6, 5
    V4: V3, 2; V5, 2; V6, 8; V7, 4
    V5: V7, 6
    V6:
    V7: V6, 1
    Removed minimum 1 from heap
    Print heap: V2, d=inf V4., d=inf v3, d= inf v7, d=inf v5......
    

    【讨论】:

    • 这是第一次回答后的修改。 @TheDark
    猜你喜欢
    • 2013-12-23
    • 1970-01-01
    • 2013-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多