Random access of Vertices using Boost::graph

℡╲_俬逩灬. 提交于 2019-12-12 15:23:28

问题


I am trying to iterate over my boost graph's vertices in parallel using OpenMP. This seems to require having an iterator that supports random access of elements (e.g., itr[i] gets the ith element). However, the iterator that vertices(g) returns (a vertex_iterator) does not seem to support this. Is there an efficient, clean way to accomplish this? Ideally, I just want a standard for loop such as this:

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

which will cooperate with OpenMP. Thanks!


回答1:


Using a adjacency_list<..., vecS, ...> or adjacency_matrix would enable this by having integral-type vertex descriptors.

Thinking slightly out of the box, have a look at the Parallel Boost Graph Library (Parallel BGL). It's very likely that it does what you want (and more) but better?

Tiny Demo

Live On Coliru

Sample output (on my system):

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

Full listing:

#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";
}


来源:https://stackoverflow.com/questions/30135470/random-access-of-vertices-using-boostgraph

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!