gpt4 book ai didi

c++ - 使用图权重 boost 深度优先访问者最小生成树

转载 作者:搜寻专家 更新时间:2023-10-31 00:53:14 24 4
gpt4 key购买 nike

我想从具有边权重的顶点创建一棵最小生成树,并按深度优先顺序遍历图形。我可以构建图形和最小生成树,但我无法编写自定义访问者。

#include <iostream>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/kruskal_min_spanning_tree.hpp>
#include <boost/graph/depth_first_search.hpp>
#include <boost/graph/graph_traits.hpp>

#include <vector>
#include <string>

typedef boost::property<boost::edge_weight_t, double> EdgeWeightProperty;
typedef boost::adjacency_list <
boost::listS,
boost::vecS,
boost::undirectedS,
boost::no_property,
EdgeWeightProperty> MyGraph;

typedef MyGraph::edge_descriptor Edge;

class MyVisitor : public boost::default_dfs_visitor
{
public:
void tree_edge(Edge e, const MyGraph& g) const {

}
};

void mst() {
MyGraph g;
boost::add_edge(0, 1, 0.7, g);
boost::add_edge(0, 2, 0.1, g);

boost::add_edge(1, 2, 0.3, g);
boost::add_edge(1, 0, 0.7, g);
boost::add_edge(1, 3, 0.8, g);
boost::add_edge(1, 4, 0.2, g);

boost::add_edge(2, 1, 0.3, g);
boost::add_edge(2, 0, 0.1, g);
boost::add_edge(2, 5, 0.1, g);
boost::add_edge(2, 4, 0.5, g);

boost::add_edge(3, 1, 0.8, g);

boost::add_edge(4, 1, 0.2, g);
boost::add_edge(4, 2, 0.5, g);

boost::add_edge(5, 2, 0.1, g);

std::list <Edge> spanning_tree;
boost::kruskal_minimum_spanning_tree(g, std::back_inserter(spanning_tree));

// the following two lines are failing
MyVisitor vis();
boost::depth_first_search(spanning_tree, visitor(vis));
}

int main(int argc, char** argv)
{
mst();
std::cin.get();
return (0);
}

我想访问自定义访问者中的顶点和边权重。这可能吗?我看到这个帖子:boost minimum spanning tree, how to do depth first?但我宁愿不构建单独的权重图。

此外,是否可以在不编写自定义访问者的情况下使用 boost 工具以深度优先顺序遍历树?

最佳答案

MyVisitor vis();

那是一个函数声明。参见 Most Vexing Parse

boost::depth_first_search(spanning_tree, visitor(vis));

std::list<Edge> 上调用图形算法. depth_first_search requires a graph that models the right graph concepts :

enter image description here

std::list 都不是模型。

建议

您可以构建一个仅包含 MST 集边的图。您链接到的问题的答案尝试了这一点。

但是,创建一个 filtered_graph<> 似乎更容易也更有效。同一图形的 View ,以便通过相同的机制可以简单地获得边缘属性。

首先,让我们更喜欢在 set<> 中获取 MST 边而不是 list<> :

struct InSpanning {
std::set<Edge> edges;
bool operator()(Edge e) const { return edges.count(e); }
} spanning;

boost::kruskal_minimum_spanning_tree(g, std::inserter(spanning.edges, spanning.edges.end()));

您会注意到有趣的事情是 InSpanning 也是一个函数对象,用作filtering_graph的过滤谓词:

boost::filtered_graph<MyGraph, InSpanning, boost::keep_all> mst(g, spanning, {});

现在你可以调用 de DFS:

boost::depth_first_search(mst, visitor(vis));

我稍微调整了访问者:

struct MyVisitor : boost::default_dfs_visitor {
template <typename Graph>
void tree_edge(Edge e, const Graph& g) {
std::cout << "Visiting: " << e << " with weight " << get(boost::edge_weight, g, e) << "\n";
}
};

注意:

  1. 它不会对 MyGraph 进行硬编码再键入(因为 filtered_graph 具有不同的类型)。
  2. 它打印你想看的信息。

现场演示

Live On Coliru

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/filtered_graph.hpp>
#include <boost/graph/depth_first_search.hpp>
#include <boost/graph/kruskal_min_spanning_tree.hpp>
#include <iostream>

#include <string>
#include <vector>

typedef boost::property<boost::edge_weight_t, double> EdgeWeightProperty;
typedef boost::adjacency_list<boost::listS, boost::vecS, boost::undirectedS, boost::no_property, EdgeWeightProperty>
MyGraph;

typedef MyGraph::edge_descriptor Edge;

struct MyVisitor : boost::default_dfs_visitor {
template <typename Graph>
void tree_edge(Edge e, const Graph& g) {
std::cout << "Visiting: " << e << " with weight " << get(boost::edge_weight, g, e) << "\n";
}
};

void run_mst_test() {
MyGraph g;
boost::add_edge(0, 1, 0.7, g);
boost::add_edge(0, 2, 0.1, g);

boost::add_edge(1, 2, 0.3, g);
boost::add_edge(1, 0, 0.7, g);
boost::add_edge(1, 3, 0.8, g);
boost::add_edge(1, 4, 0.2, g);

boost::add_edge(2, 1, 0.3, g);
boost::add_edge(2, 0, 0.1, g);
boost::add_edge(2, 5, 0.1, g);
boost::add_edge(2, 4, 0.5, g);

boost::add_edge(3, 1, 0.8, g);

boost::add_edge(4, 1, 0.2, g);
boost::add_edge(4, 2, 0.5, g);

boost::add_edge(5, 2, 0.1, g);

struct InSpanning {
std::set<Edge> edges;
bool operator()(Edge e) const { return edges.count(e); }
} spanning;

boost::kruskal_minimum_spanning_tree(g, std::inserter(spanning.edges, spanning.edges.end()));

MyVisitor vis;
boost::filtered_graph<MyGraph, InSpanning, boost::keep_all> mst(g, spanning, {});
boost::depth_first_search(mst, visitor(vis));
}

int main() {
run_mst_test();
}

打印

Visiting: (0,2) with weight 0.1
Visiting: (2,1) with weight 0.3
Visiting: (1,3) with weight 0.8
Visiting: (1,4) with weight 0.2
Visiting: (2,5) with weight 0.1

关于c++ - 使用图权重 boost 深度优先访问者最小生成树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49428082/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com