使用Boost :: Graph随机访问顶点

Random access of Vertices using Boost::graph

本文关键字:访问 顶点 随机 Graph Boost 使用      更新时间:2023-10-16

我正在尝试使用OpenMP并行迭代Boost Graph的顶点。这似乎需要具有支持元素随机访问的迭代器(例如,itr[i]获取i TH元素)。但是,vertices(g)返回(A vertex_iterator)的迭代器似乎并不支持这一点。是否有一种有效,干净的方法可以实现这一目标?理想情况下,我只想要这样的循环标准:

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

将与OpenMP合作。谢谢!

使用 adjacency_list<..., vecS, ...>adjacency_matrix可以通过具有积分型顶点描述符来实现这一目标。

稍微从开箱即用,请查看并行的增压图库(并行BGL)。它很有可能会做您想要的(以及更多),但更好?

微小的演示

活在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() << "msn";
    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";
}