简体   繁体   English

BGL顶点上的随机顺序迭代

[英]Random order iteration over BGL vertices

Here's some example code to create a graph with bgl and iterate over the vertices. 这是一些示例代码,用于使用bgl创建图形并在顶点上进行迭代。 I would like to do this iteration in random order - in other words: the loop should manipulate every vertex, but the order of the vertices should be random for every call of the main function. 我想以随机顺序进行此迭代-换句话说:循环应该操纵每个顶点,但是对于主函数的每次调用,顶点的顺序应该是随机的。 How can I achieve this? 我该如何实现?

I experimented unsuccessfully with std::random_shuffle . 我尝试使用std :: random_shuffle失败。 I think there are different kinds of iterator concepts, but I don't understand the differences yet. 我认为有不同种类的迭代器概念,但是我还不了解它们之间的区别。

  #include <iostream>                  
  #include <boost/graph/graph_traits.hpp>
  #include <boost/graph/adjacency_list.hpp>

  using namespace boost;

  // vertex struct to store some properties in vertices
  struct Vertex {
    std::string name;
  };

  int main(int,char*[]) {
    // create a typedef for the graph type
    typedef adjacency_list<vecS, vecS, undirectedS, Vertex> Graph;

    // declare a graph object
    Graph g(3);

    // prepare iteration 
    typedef graph_traits<Graph>::vertex_iterator vertex_iter;
    std::pair<vertex_iter, vertex_iter> vp;

    // add some property data to the vertices
    vp = vertices(g);
    g[*vp.first].name = "A";
    g[*(++vp.first)].name = "B";
    g[*(++vp.first)].name = "C";

    // iterate over the vertices
    for (vp = vertices(g); vp.first != vp.second; ++vp.first)     
      std::cout << g[*vp.first].name <<  " ";
    std::cout << std::endl;

    return 0;
  }

Edit: Here's the solution I came up with thanks to the answer of @Jay. 编辑:这是我想出的解决方案,感谢@Jay的回答。

  #include <iostream>                  
  #include <boost/graph/graph_traits.hpp>
  #include <boost/graph/adjacency_list.hpp>
  #include <algorithm>    // std::random_shuffle
  #include <vector>       // std::vector
  #include <ctime>        // std::time
  #include <cstdlib>      // std::rand, std::srand

  using namespace boost;

  // vertex struct to store some properties in vertices
  struct Vertex {
    std::string name;
  };

  // random number generator function
  int myrandom (int i) { 
    return std::rand()%i;
  }

  int main(int,char*[]) {
    // create a typedef for the graph type
    typedef adjacency_list<vecS, vecS, undirectedS, Vertex> Graph;

    // declare a graph object
    Graph g(3);

    // prepare iteration 
    typedef graph_traits<Graph>::vertex_iterator vertex_iter;
    std::pair<vertex_iter, vertex_iter> vp;

    // add some property data to the vertices
    vp = vertices(g);
    g[*vp.first].name = "A";
    g[*(++vp.first)].name = "B";
    g[*(++vp.first)].name = "C";

    // initialize pseudo random number generator
    std::srand(unsigned (std::time(0)));

    // create offset vector
    std::vector<int> myvector;
    for (int i=0; i<3; ++i) {
      myvector.push_back(i);
    }

    // using myrandom to shuffle offset vector
    std::random_shuffle(myvector.begin(), myvector.end(), myrandom);

    // keep vp.first at the start 
    vp = vertices(g);

    // iterate over the vertices effectively shuffled by the offset
    vertex_iter dummy_iter;
    for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it) {
      dummy_iter = vp.first + *it;
      std::cout << g[*dummy_iter].name <<  " ";
    }
    std::cout << std::endl;

    return 0;
  }

I think the simplest thing to do is set up a random vector of indices, as outlined here . 我认为最简单的方法是建立一个随机的索引向量, 如此处所述 Then you can iterate the shuffled list and use it as an offset for your vertex iterator. 然后,您可以迭代改组后的列表,并将其用作顶点迭代器的偏移量。

For example 例如

vp = vertices(g); // Keep vp.first at the start 
vertex_iter dummy_iter;
// Looping on a shuffled vector, values should be 0..N-1
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
{
    dummy_iter = vp.first + *it;
    Vertex* v = *dummy_iter;
    ...

To create a random number within a given range use the code below. 要在给定范围内创建随机数,请使用以下代码。 #include ctime and #include stdlib.h #include ctime和#include stdlib.h

    int getNumberRange(int min, int max)
    {
        srand(static_cast<unsigned int>(time(0)));

        // always call rand(); after srand() on visual vasic;
        rand();

        static const double fraction = 1.0 / (static_cast<double>(RAND_MAX) + 1.0);
        return static_cast<int>(rand() * fraction * (max - min + 1) + min);
    }



    getNumberRange(1, 100); //picks number between 1 and 100

Every time you need a new number modify the range values (1, 100) and call the function again. 每次需要一个新数字时,请修改范围值(1、100)并再次调用该函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM