提升包含/排除某些边缘的最小生成树

时间:2015-06-22 14:05:49

标签: boost graph boost-graph minimum-spanning-tree kruskals-algorithm

我试图按照成本增加的顺序实现图表的所有可能生成树的列表。我使用Sorensen and Janssens (2005)的算法。该图初始化如下:

typedef property<edge_weight_t, int> EdgeWeightProperty;
typedef adjacency_list<vecS, vecS, undirectedS, no_property, EdgeWeightProperty> Graph;
typedef Graph::edge_descriptor Edge;
typedef Graph::vertex_descriptor Vertex;
typedef boost::graph_traits<Graph>::edge_iterator EdgeIterator;
typedef std::pair<EdgeIterator, EdgeIterator> EdgePair;
Graph g;

add_edge(1, 2, 3, g);
add_edge(1, 3, 1, g);
add_edge(1, 4, 2, g);
add_edge(2, 3, 3, g);
add_edge(2, 4, 1, g);

在此之后,有必要找到具有一些限制的图的最小生成树,例如Edge(2) - (4)不应该在MST和Edge(1) - (2) )应该在那里。

对于边缘排除,可以使用remove_edge_if(..)从图形中删除边缘。

template<typename WMap>
class Remover
{
public:
    Remover(const WMap& weights, int threshold)
        : m_weights(weights), m_threshold(threshold) {}

    template<typename ED>
    bool operator()(ED w) const { return m_weights[w] <= m_threshold; }

private:
    const WMap& m_weights;
    int         m_threshold;
};

....
// remove edges of weight < 1
Remover< property_map<Graph, edge_weight_t>::type> r(get(edge_weight, g), 1);
remove_edge_if(r, g);
....
std::list < Edge > spanning_treeT;
kruskal_minimum_spanning_tree(g, std::back_inserter(spanning_treeT));

但是我应该如何确保其中一条边总是在生成树中呢?我只是想把一些Edge添加到Kruskal函数的输出中,但它显然没有工作。它产生图形的MST +添加边缘:

std::list < Edge > spanning_tree_g2;
Vertex u, v;
EdgePair ep = edges(g2);
u = source(*ep.first, g2);
v = target(*ep.first, g2);
Edge ed = edge(u, v, g2).first;
spanning_tree_g2.push_front(ed);
kruskal_minimum_spanning_tree(g2, std::back_inserter(spanning_tree_g2));

是否有可能以Kruskal算法知道包含哪些内容以及不包含哪些内容的方式标记边缘?

1 个答案:

答案 0 :(得分:0)

我似乎可以通过拆分这条边并在中间插入两个“人造”顶点来强制包含某个边缘。

已经需要MST算法来生成覆盖所有顶点的边缘树

因为你有意添加了人工顶点,所以很容易确保使用任何其他边缘都无法访问它。

在:

   ------------------[e:w1+w2]------------------

后:

   ----[e1:w1]---(v1)---[em:0]---(v2)---[e2:w2]----

(其中v1v2是插入的顶点。)

事实上,您将(e1,em,e2)(e2,em,e1)的任何序列“折叠”为(e)

您最终可能会遇到一个到达v1和v2的树,但从​​未遍历em。在这种情况下,您只需删除e1e2中的一个,并无条件地将其替换为e