使用给定路径(C ++)查找MST

时间:2018-11-15 18:24:39

标签: c++ graph-theory minimum-spanning-tree

我有一个用于查找MST的代码,其中包括给MST的给定路径,这给了我正确的MST权重(我知道输出应该是什么)。我试图重写代码的一部分以使用std::map而不是std::vector来进行更有效的查找(从下面的代码中可以清楚地看到),但是现在它给出了错误的答案,并且尽管调查了几个小时,我无法理解我在哪里犯了错误。定位错误的任何帮助将不胜感激。

使用vector<Edge>的旧版本。遍历所有边的向量(m_all_edges)。如果边evector<Edge> path中,则将其添加到MST(m_mst)中。否则,将其添加到MST(m_edges)的候选边缘。

void MSTPath::m_add_shortest_path_old(vector<Edge> path){
    for (auto e : path){
        m_graph->union_vu(e.get_node(),e.get_opposite_node(-1));
    }
    for (auto e : m_all_edges){
        if (tempfunc(e,path)) m_mst.push_back(e);
        else m_edges.push_back(e);
    }
}

bool MSTPath::tempfunc(Edge e, vector<Edge> path){
    for (auto edge : path){
        if((edge.get_node()==e.get_node())&&(edge.get_opposite_node(-1)==e.get_opposite_node(-1))) return true;
    }
    return false;
}

带有std::map的版本。

void MSTPath::m_add_shortest_path(map<Edge,int> path_map){
    for (auto const& x : path_map){
        Edge e = x.first;
        m_graph->union_vu(e.get_node(),e.get_opposite_node(-1));
    }
    for (auto const& x : m_all_edges_map){
        if ((path_map.count(x.first)>0)||(path_map.count(x.first.reversed())>0)) m_mst.push_back(x.first);
        else m_edges.push_back(x.first);
    }
}

查找MST的函数(在调用m_add_shortest_path / m_add_shortest_path_old之后调用)。

int MSTPath::m_compute_mst(){
    sort(m_edges.begin(),m_edges.end(),[](Edge e1, Edge e2) { return e1.weight < e2.weight; });
    int i = 0;
    int mst_size = m_mst.size();

    int mst_weight = 0;
    int v,u;
    for (Edge e : m_mst) mst_weight += e.weight;

    while (mst_size<m_N-1){
        Edge edge = m_edges[i++];
        v = m_graph->find(edge.get_node());
        u = m_graph->find(edge.get_opposite_node(-1));
        if (u!=v){
            mst_size++;
            mst_weight += edge.weight;
            if (mst_weight>=min_mst_weight) return numeric_limits<int>::max();
            m_mst.push_back(edge);
            m_graph->union_vu(v,u);
        }
    }
    return mst_weight;
}

从我看到的结果来看,两个函数都获得完全相同的m_mst(并以mst_weight开头)和相同的m_edges(但顺序不同)。但是排序对于算法来说应该不是问题(除了按重量排序,但这是m_compute_mst中的句柄),对吧?

Edge类:

class Edge{
public:
    Edge(int v_e, int u_e, int w){
        v = v_e;
        u = u_e;
        weight = w;
    }

    int get_node() const { return v; }
    int get_opposite_node(int k) const {
        if ((k==v) || (k==-1)) return u;
        else return v;
    }

    Edge reversed() const {
        return Edge(u,v,weight);
    }

    bool operator<(const Edge& e) const {
        if (this->get_node()<e.get_node()) return true;
        else if (this->get_node()==e.get_node()) return this->get_opposite_node(-1)<e.get_opposite_node(-1);
        else return false;
    }

    int v, u, weight;
};

是的,我知道按值传递会产生更多副本。这是一个临时版本。

0 个答案:

没有答案