我有一个undirected_unweighted_graph graph;
,其定义如下:
typedef typename boost::adjacency_list<boost::vecS,boost::vecS,boost::undirectedS,boost::no_property,boost::no_property> undirected_unweighted_graph;
它具有多个顶点,这些顶点通过无向边相互连接。
在执行算法期间,我正在搜索graph
的连接子图,该子图仅包含某些具有某些属性的顶点。
我正在使用线性优化软件包,该软件包为我的问题提供了可能的最佳解决方案。一个解决方案由一组具有固定大小n的顶点组成,并且可能不可行(即,这些顶点在graph
的相应子图中未连接)。我目前正在使用解决方案的顶点生成一个新图,并添加在graph
中也存在的边。我正在使用boost::connected_components()
为其计算连接的组件。
现在我要问我的问题:
对我而言,下一步是通过施加约束来提高生成解决方案的性能。具体来说,我将“增长”一个解决方案,从单个节点开始,以n
个节点的子图结束。在每个阶段,部分解决方案将通过添加其邻居之一来扩展。 (想法是,如果部分解决方案可以发展成为完整解决方案,那么至少一个邻居会出现在完整解决方案中。)如何识别这些邻居?
我的方法如下:
我要遍历每个组件,然后遍历boost::out_edges(v, g)
。然后,我必须检查邻居是否是我的组件的一部分。如果它不是组件的一部分,则将其添加到组件邻居组。我想知道是否有任何方法可以使boost::out_edges(V, g)
的顶点列表遍历V
。
编辑
更具体地说:给定一个图,我可以像这样迭代给定顶点的邻居:
for (auto edge: boost::make_iterator_range(boost::out_edges(v, graph))) {
//do stuff
}
如果我有一个连通的分量,说一个顶点向量std::vector<size_t> component
,该怎么办?我想要的是组件的输出边缘,这意味着顶点的所有输出边缘,不包括component
两个顶点之间的那些顶点。是否有一种优雅的方法可以有效地获得这些优势?
答案 0 :(得分:1)
我不会遍历多个顶点。相反,我将维护两组顶点-一组包含当前局部解决方案中的顶点,另一组包含与局部解决方案相邻(而不在其中)的顶点。当线性优化程序包将一个顶点添加到部分解中时,该顶点也应从邻接关系集移到解决方案中的顶点集。接下来,需要迭代来自新顶点的边缘,但是仅需要迭代来自新顶点的边缘。对于与新顶点相邻的每个顶点,如果不在局部解中,则将其添加到相邻顶点集中。
我也将尝试使用一组仅包含部分解决方案中的顶点和与部分解决方案相邻的顶点的集合进行类似的操作。更少的开销。根据周围代码的期望,此集合可能与仅包含相邻顶点的集合一样工作。
此方法的优点是可以消除重复的工作。如果您已经查看了顶点A的所有邻居,为什么只需要将顶点B添加到集合中就再次 查看它们?
此方法的缺点是,如果您有时需要回溯,则可能需要大量的内存开销(请考虑深度优先搜索并维护这些集合的堆栈)。这有多糟糕取决于n
的大小,以及平均来说,每个顶点连接多少个边。即使在最坏的情况下,巧妙地消除冗余也可能会挽救这种方法,但我将其留待以后使用。