【问题标题】:Random access of Vertices using Boost::graph使用 Boost::graph 随机访问顶点
【发布时间】:2015-05-09 03:01:12
【问题描述】:

我正在尝试使用 OpenMP 并行迭代提升图的顶点。这似乎需要一个支持随机访问元素的迭代器(例如,itr[i] 获取ith 元素)。但是,vertices(g) 返回的迭代器(vertex_iterator)似乎不支持这一点。有没有一种高效、干净的方法来实现这一点?理想情况下,我只想要一个标准的循环,例如:

for (int i = 0; i < num_vertices; i++) {
  vertex v = itr[i];
  // Compute on vertex
}

它将与 OpenMP 合作。谢谢!

【问题讨论】:

    标签: c++ boost boost-graph


    【解决方案1】:

    使用adjacency_list&lt;..., vecS, ...&gt;adjacency_matrix 将通过具有整数类型的顶点描述符来实现这一点。

    稍微开箱即用,看看Parallel Boost Graph Library(Parallel BGL)。它很可能会做你想要的(以及更多)但更好?

    小演示

    Live On Coliru

    示例输出(在我的系统上):

    Generated 50000000 vertices in 1879ms
    Using 8 threads.
    Sum of volumes for 50000000 vertices in 94ms: 2.5603e+10
    

    完整列表:

    #include <boost/graph/adjacency_list.hpp>
    #include <boost/graph/random.hpp>
    #include <chrono>
    #include <iostream>
    #include <omp.h>
    #include <random>
    
    static std::mt19937 prng { std::random_device{}() };
    
    struct MyVertex {
        uintmax_t volume = [] { static std::uniform_int_distribution<int> pick(0, 1024); return pick(prng); }();
    };
    
    using namespace boost;
    using G = adjacency_list<vecS, vecS, directedS, MyVertex>;
    
    G generate() {
        using namespace std::chrono;
        auto start = high_resolution_clock::now();
    
        G g;
        generate_random_graph(g, 50000000, 0, prng);
    
        auto end = high_resolution_clock::now();
        std::cerr << "Generated " << num_vertices(g) << " vertices " << "in " << duration_cast<milliseconds>(end-start).count() << "ms\n";
    
        return g;
    }
    
    int main() {
    
        auto const g = generate();
    
        using namespace std::chrono;
        auto start = high_resolution_clock::now();
        double sum = 0;
    #pragma omp parallel
        {
    #pragma omp single
            std::cerr << "Using " << omp_get_num_threads() << " threads.\n";
    
    #pragma omp for reduction(+:sum)
            for (G::vertex_descriptor u = 0; u < num_vertices(g); ++u) {
                sum += g[vertex(u, g)].volume;
            }
        }
    
        auto end = high_resolution_clock::now();
        std::cerr << "Sum of volumes for " << num_vertices(g)                                << " vertices "
                  << "in "                 << duration_cast<milliseconds>(end-start).count() << "ms: " << sum << "\n";
    }
    

    【讨论】:

    • 一如既往的好答案。据我了解,并行 bgl 是一组分布式多节点工具,而 openMP 用于单节点上的多线程。
    • @pbible 这是真的。然而,也许可以利用分布式模型并将每个核心视为一个节点,以便从现有的分布式算法中受益
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    • 2018-08-07
    • 1970-01-01
    • 2010-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多