簡體   English   中英

使用Kruskal算法查找最小生成樹的錯誤

[英]Bug in finding minimum spanning tree using Kruskal's algorithm

我編寫代碼,將頂點添加到圖形中並更新邊緣的權重,然后找到最小生成樹。 我認為我已經完成了但是它似乎有一些錯誤但是我找不到它。使用Valgrind的系統並在MST的調用中指出“無效寫入大小4”和“無效讀取大小4” ,但我認為它運作正常.Valgrind的整個錯誤是https://docs.google.com/document/d/1_AhOdDkyZGNTBVHspyGtnSQoU1tYkm0nVA5UABmKljI/edit?usp=sharing

以下代碼由like調用

CreateNewGraph();
AddEdge(1, 2, 10);
AddEdge(2, 4, 10);
AddEdge(1, 3, 100);
AddEdge(3, 4, 10);
GetMST(mst_edges);

結果將是(1,2)(2,4)(3,4)。

並打電話

UpdateEdge(1, 3, 0.1);
GetMST(mst_edges);

結果將是(1,2)(1,3)(2,4)。

它被發送到一個系統執行,它將被調用,如上所述,但在上面的很多時間周期。

#include <vector>
#include <utility>
#include <algorithm>

using namespace std;

namespace HOMEWORK{
    class Edge{
        public:
            Edge(unsigned int, unsigned int, double);
            unsigned int u;
            unsigned int v;
            double w;
        friend bool operator<(const Edge& a, const Edge& b){
         return a.w < b.w;
        }
    };
    Edge::Edge(unsigned int source = 0, unsigned int destination = 0, double weight = 0.0){
        u = source;
        v = destination;
        w = weight;
    }

    vector<Edge> graph(0);
    vector<int> parent(0);

    int findset(int x){
        if(x != parent[x])parent[x] = findset(parent[x]);
        return parent[x];
    }

    void CreateNewGraph(){
        graph.clear();
        parent.clear();
    }

    void AddEdge(unsigned int u, unsigned int v, double w){
        graph.push_back(Edge(u,v,w));
    }

    void UpdateEdge(unsigned int u, unsigned int v, double w){
        for(int i = 0; i < graph.size(); i ++){
            if(graph[i].u == u && graph[i].v == v)graph[i] = Edge(u,v,w);
        }
    }

    void GetMST(vector<pair<unsigned int, unsigned int> >& mst_edges){
        mst_edges.clear();
        parent.clear();
        int e = graph.size();
        for(int i = 0; i <= e + 1; i ++)parent.push_back(i);
        stable_sort(graph.begin(), graph.end());
        for(int i = 0; i < e; i ++){
            //cout << graph[i].u << ":" << graph[i].v << ":" << graph[i].w << ":" << parent[i + 1] << endl;
            int pu = findset(graph[i].u);
            int pv = findset(graph[i].v);
            if(pu != pv){
                parent[pu] = parent[pv];
                mst_edges.push_back(make_pair(graph[i].u, graph[i].v));
            }
        }
    }

    void Init(){
    }

    void Cleanup(){
    }
}

我認為問題是你如何設置父指針。 請注意,您已將parents設置為

for(int i = 0; i <= e + 1; i ++) parent.push_back(i);

這將在parent數組中為圖中的每個邊創建一個條目,另外還有一個額外的條目。 但是,每個節點都有一個父節點 ,而不是每個節點,並且圖形中的節點數可以大於邊數加一。 例如,假設您獲得了這組邊:

1  2
3  4
5  6

這個圖顯然有六個節點(編號為1 ... 6),但是你的代碼只能為parents 4個條目留出空間。

嘗試更改代碼,以便將parents設置為適當的大小,可能是通過在邊列表中查找最大和最小編號節點並適當調整數組大小。 或者,考慮使用std::unordered_map<int, int> ,如果頂點數不連續地從0開始,則更靈活。

希望這可以幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM