在 width_first_search 期间设置顶点的颜色
Posted
技术标签:
【中文标题】在 width_first_search 期间设置顶点的颜色【英文标题】:Setting the color of a vertex during breadth_first_search 【发布时间】:2016-11-09 14:59:23 【问题描述】:我想在 BGL 图上进行区域增长。区域增长的想法是访问顶点,从指定的根顶点开始,并收集并返回与其父级相比通过了某些标准函数的顶点的子图或顶点列表。例如,假设我们有一个如下所示的简单图表:
A-B-C-D
边权重为:
AB = 4, BC = 10, CD = 3
现在我们想从 A 开始扩大区域。我们想做以下事情:
发现 A 并将其添加到连接区域 发现 B,并确定 B 是否与 A“足够相似”。对于这个例子,假设标准是边缘权重的阈值:如果边缘权重 > 5,那么我们不应该继续遍历到 B . 所以在这里,AB = 4
所以我们应该成长为 B,但由于 BC=10
,我们永远不应该到达 C。
如果是,则将 B 添加到连接区域并继续发现 C 并检查 C 是否与 B 足够相似,等等。
如果不是,则停止并返回当前连接的区域
我可以在访问者的tree_edge
函数中检查这个标准函数。如果 A 和 B 太不相似,我试图通过将传递给 tree_edge
的边的目标顶点设置为黑色来“阻止”BFS 继续(将 B 添加到队列中,然后稍后处理它等)。但是,这似乎并没有停止遍历:
#include <iostream>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/graph/breadth_first_search.hpp>
using EdgeWeightProperty = boost::property<boost::edge_weight_t, float>;
using ColorPropertyType = boost::property<boost::vertex_color_t, boost::default_color_type>;
using GraphType = boost::adjacency_list<boost::setS, // out edge container
boost::vecS, // vertex container
boost::undirectedS, // directed or undirected
ColorPropertyType, // vertex properites
EdgeWeightProperty> // edge properties
;
template <typename TGraph>
void printColors(const TGraph& g)
const auto& colorMapGraph = get(boost::vertex_color_t(), g);
std::cout << "colors: ";
for(unsigned int i = 0; i < num_vertices(g); ++i)
std::cout << get(colorMapGraph, vertex(i, g)) << " ";
std::cout << std::endl;
class BreadthFirstSearchVisitor : public boost::default_bfs_visitor
public:
// We must provide a mutable version of the graph to the visitor since we want to change properties
BreadthFirstSearchVisitor(GraphType& graph) : mGraph(graph)
template < typename TEdge, typename TGraph>
void tree_edge(TEdge e, const TGraph& g) const
std::cout << std::endl << "tree_edge: " << e << std::endl;
printColors(g);
const auto& colors = get(boost::vertex_color_t(), mGraph); // Though this is const&, you can still call put()
const auto& edgeWeights = get(boost::edge_weight_t(), mGraph);
boost::graph_traits<GraphType>::vertex_descriptor targetVertex = boost::target(e, g);
std::cout << "targetVertex: " << targetVertex << std::endl;
float edgeWeight = get(edgeWeights, e);
std::cout << "edgeWeight: " << edgeWeight << std::endl;
if(edgeWeight > 5.f)
std::cout << "Next vertex does not belong to the region!" << std::endl;
put(colors, vertex(targetVertex, mGraph), boost::color_traits<GraphType>::black());
printColors(g);
// A very strange pattern, but this is (officially) recommended here: http://***.com/a/2608616/284529
GraphType& mGraph;
;
int main(int,char*[])
// Create a graph object
GraphType g(4);
EdgeWeightProperty e0 = 4.f;
add_edge(0, 1, e0, g);
EdgeWeightProperty e1 = 10.f;
add_edge(1, 2, e1, g);
EdgeWeightProperty e2 = 3.f;
add_edge(2, 3, e2, g);
BreadthFirstSearchVisitor breadthFirstSearchVisitor(g);
unsigned int startVertex = 0;
// named argument signature
breadth_first_search(g, vertex(startVertex, g), visitor(breadthFirstSearchVisitor).color_map(get(boost::vertex_color_t(), g)));
return 0;
输出是:
tree_edge: (0,1)
colors: 1 0 0 0
targetVertex: 1
edgeWeight: 4
tree_edge: (1,2)
colors: 4 1 0 0
targetVertex: 2
edgeWeight: 10
Next vertex does not belong to the region!
colors: 4 1 4 0
tree_edge: (2,3)
colors: 4 4 1 0
targetVertex: 3
edgeWeight: 3
但我希望它永远不会用边 (2,3)
调用 tree_edge
,因为我们将顶点 2
标记为黑色。
谁能解释为什么这不能像我预期的那样工作?
【问题讨论】:
【参考方案1】:答案似乎只是将访问者中的tree_edge
改为examine_edge
。我猜一旦调用tree_edge
,目标顶点就已经添加到队列中,所以颜色不再重要(因为颜色用于确定是否应将顶点添加到队列中)。
【讨论】:
以上是关于在 width_first_search 期间设置顶点的颜色的主要内容,如果未能解决你的问题,请参考以下文章