【问题标题】:Boost Strong components with listS使用 listS 提升强组件
【发布时间】:2020-05-08 05:33:37
【问题描述】:

在 listS 而不是 vecS 上做强连通分量的图的例子并不多。这是 vecS 的等效示例

#include <boost/config.hpp>
#include <vector>
#include <iostream>
#include <boost/graph/strong_components.hpp>
#include <boost/graph/adjacency_list.hpp>

int
main()
{
  using namespace boost;
  typedef adjacency_list < vecS, vecS, directedS > Graph;
  const int N = 6;
  Graph G(N);
  add_edge(0, 1, G);
  add_edge(1, 1, G);
  add_edge(1, 3, G);
  add_edge(1, 4, G);
  add_edge(3, 4, G);
  add_edge(3, 0, G);
  add_edge(4, 3, G);
  add_edge(5, 2, G);

  std::vector<int> c(N);

  int num = strong_components
    (G, make_iterator_property_map(c.begin(), get(vertex_index, G), c[0]));

    auto l=get(vertex_index, G);

  std::cout << "Total number of components: " << num << std::endl;
  std::vector < int >::iterator i;
  for (i = c.begin(); i != c.end(); ++i)
    std::cout << "Vertex " << i - c.begin()
      << " is in component " << *i << std::endl;
  return EXIT_SUCCESS;
}

但是当我从 vecS 更改为 listS 时,它会中断。我知道问题是由于顶点索引和输出向量索引中的某种类型的不匹配,但我无法完全想出解决它的方法。最接近的答案是Which VertexList types are valid for depth_first_search,但这是针对 DFS,不能外推到 SCC。

【问题讨论】:

    标签: boost boost-graph strongly-connected-graph


    【解决方案1】:

    关于在 listS 而不是 vecS 上做强连通分量的图的例子并不多。这是 vecS 的等效示例

    “没有太多关于在水下而不是在陆地上玩棋盘游戏的信息”

    原因是您提到的算法(连接的组件)没有什么特别的。您面临的问题是使用 listS 会丢失隐含的 vertex_index 属性。这会破坏所有需要它的东西。

    具体来说,您会注意到 add_edge 调用已经无法编译。

    您需要添加一个顶点索引。就像在水下进行任何活动都需要氧气管理解决方案。

    因此,请查找 e.g. here 的示例。

    事实上......我立即遇到了一个重复的问题,我在 2017 年回答过:

    Find connected components using Boost Graph library, with the vertex and edge type being boost::listS

    最简单的改变:

    对示例代码的最简单更改:

    Live On Coliru

    #include <boost/config.hpp>
    #include <boost/graph/adjacency_list.hpp>
    #include <boost/graph/strong_components.hpp>
    #include <iostream>
    #include <vector>
    using boost::make_iterator_range;
    
    int main() {
        typedef boost::adjacency_list<boost::vecS, boost::listS, boost::directedS,
                boost::property<boost::vertex_index_t, int>
            > Graph;
    
        Graph G(6);
        auto idmap = get(boost::vertex_index, G);
        {
            // initialize idmap
            int id = 0;
            for (auto& v : make_iterator_range(vertices(G)))
                idmap[v] = id++;
        }
    
        auto add_edge = [&](int i, int j) {
            return boost::add_edge(vertex(i, G), vertex(j, G), G);
        };
    
        add_edge(0, 1);
        add_edge(1, 1);
        add_edge(1, 3);
        add_edge(1, 4);
        add_edge(3, 4);
        add_edge(3, 0);
        add_edge(4, 3);
        add_edge(5, 2);
    
        std::vector<int> c(num_vertices(G));
    
        int num = strong_components(
            G, make_iterator_property_map(c.begin(), idmap, c[0]));
    
        //auto l = get(vertex_index, G);
    
        std::cout << "Total number of components: " << num << std::endl;
        std::vector<int>::iterator i;
        for (i = c.begin(); i != c.end(); ++i)
            std::cout << "Vertex " << i - c.begin() << " is in component " << *i
                      << std::endl;
    }
    

    打印

    Total number of components: 3
    Vertex 0 is in component 0
    Vertex 1 is in component 0
    Vertex 2 is in component 1
    Vertex 3 is in component 0
    Vertex 4 is in component 0
    Vertex 5 is in component 2
    

    【讨论】:

    • 添加了一个简单编辑的live demo 以使示例与listS 一起工作
    • 它就像一个魅力!非常感激。我正在考虑这个解决方案,但在创建正确的属性映射时遇到了困难。非常感谢。
    • 我注意到你提到这就像在水下玩棋盘游戏。你认为有更好的方法吗?我的最终目标是在不继续的节点 ID 上运行 SCC(它可能有间隙),所以我认为 listS 会更适合。
    • 我的意思是作为一个有趣的比较,只是因为在水下进行任何活动都需要基本上相同的准备,无论活动如何。这并不意味着这是错误的做法(有正当理由,例如在水下运动或焊接;也许棋盘游戏是一个不好的例子:))
    • 关于非连续 ID 的主题,我会说 orthogonal 选择数据结构。虽然使用默认的vertex_index 通常很方便,但当然没有“法律”规定您必须:coliru.stacked-crooked.com/a/9458e75d2e6ce1b3
    猜你喜欢
    • 1970-01-01
    • 2013-11-30
    • 2010-09-12
    • 1970-01-01
    • 2020-08-31
    • 2013-07-05
    • 1970-01-01
    • 1970-01-01
    • 2011-10-07
    相关资源
    最近更新 更多