如何使用Boost遍历图并提取边权,实现顶点属性的按需修改
嘿,刚好我对Boost Graph Library(BGL)还算熟悉,你的需求其实有两种简单的解决方式,完全不用自己从零写DFS逻辑,咱们一步步说:
情况1:A和B是直接相连的(就像你给出的示例图)
这种情况最省事,根本不需要遍历整个图——BGL提供了直接查找两个顶点间边的函数boost::edge,直接定位到B和A之间的边,拿到权重后修改A的name就行:
// 假设你已经通过顶点描述符拿到了vB(对应顶点B)和vA(对应顶点A) auto edge_result = boost::edge(vB, vA, g); if (edge_result.second) { // 确认这条边存在 double ba_weight = get(boost::edge_weight, g, edge_result.first); g[vA].name = newString(ba_weight); // 调用你自己的newString函数 }
这个方法效率最高,因为直接定位目标边,没有多余的遍历操作。
情况2:复杂图中需要从B出发遍历找到A(A不是直接邻居)
如果你的实际场景里A和B不是直接相连的,需要走路径才能到达,那可以用BGL自带的DFS/BFS框架,自定义一个**访问者(Visitor)**来处理「到达A顶点」这个事件,不用自己写整个DFS的循环逻辑。
比如用DFS的话,自定义一个访问者类,重写tree_edge方法——当DFS走到连接到A的边时,就触发我们的修改逻辑:
#include <boost/graph/depth_first_search.hpp> // 先定义你的图类型,假设是typedef过的Graph struct UpdateNameVisitor : public boost::default_dfs_visitor { using Edge = typename boost::graph_traits<Graph>::edge_descriptor; using Vertex = typename boost::graph_traits<Graph>::vertex_descriptor; Vertex target_vertex; // 我们要找的顶点A Graph& graph; UpdateNameVisitor(Vertex target, Graph& g) : target_vertex(target), graph(g) {} // 当DFS遍历到一条树边时触发 void tree_edge(Edge e, const Graph&) const { Vertex src = boost::source(e, graph); Vertex dest = boost::target(e, graph); // 如果这条边的终点是A,就用边权修改A的name if (dest == target_vertex) { double weight = get(boost::edge_weight, graph, e); graph[dest].name = newString(weight); } // 因为是无向图,也要考虑边的反向情况(比如从A指向B的边被遍历到) if (src == target_vertex) { double weight = get(boost::edge_weight, graph, e); graph[src].name = newString(weight); } } }; // 调用方式: UpdateNameVisitor visitor(vA, g); // 从顶点B开始DFS,传入我们自定义的访问者 boost::depth_first_search(g, boost::visitor(visitor).root(vB));
BGL的DFS框架会帮你处理所有遍历的细节,你只需要在访问者里关注「到达目标顶点」这个关键事件就行,完全不用自己写循环、维护访问标记这些繁琐的代码。
另外,如果更倾向于BFS,逻辑是一样的——把depth_first_search换成breadth_first_search,访问者类的写法基本一致。
内容的提问来源于stack exchange,提问作者Sailanarmo
相关产品推荐
相关产品推荐

