Итерация случайного порядка по вершинам BGL

Вот пример кода для создания графа с помощью bgl и перебора вершин. Я хотел бы сделать эту итерацию в случайном порядке - другими словами: цикл должен манипулировать каждой вершиной, но порядок вершин должен быть случайным для каждого вызова основной функции. Как я могу этого добиться?

Я безуспешно экспериментировал с std::random_shuffle. Я думаю, что существуют разные концепции итераторов, но я пока не понимаю различий.

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

Изменить: вот решение, которое я нашел благодаря ответу @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;
  }

person nevrome    schedule 26.03.2017    source источник
comment
что не удалось использовать std::random_shuffle?   -  person Jay    schedule 26.03.2017
comment
@Jay Я пытался добавить std::random_shuffle(vp.first, vp.second);, но компиляция не удалась. Ошибка очень подробная, и я не уверен, что является важной частью, но я предполагаю, что функция подкачки, которая внутренне вызывается random_shuffle, ожидает ввода другого типа.   -  person nevrome    schedule 26.03.2017


Ответы (2)



Чтобы создать случайное число в заданном диапазоне, используйте приведенный ниже код. #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

Каждый раз, когда вам нужно новое число, измените значения диапазона (1, 100) и снова вызовите функцию.

person Felipe Lopez    schedule 26.03.2017
comment
Моя проблема не столько в том, чтобы создать генератор случайных чисел. Я не понимаю, как совместить это с концепцией итератора. Не могли бы вы уточнить, где вызывать вашу функцию для достижения случайного порядка вершин в моем примере кода? Может быть, я просто не вижу очевидного. - person nevrome; 26.03.2017