Ejemplo n.º 1
0
    small_world_iterator& operator++()
    {
      target = (target + 1) % n;
      if (target == (source + k/2 + 1) % n) {
        ++source;
        if (allow_self_loops) target = source;
        else target = (source + 1) % n;
      }
      current.first = source;

      uniform_01<RandomGenerator, double> rand01(*gen);
      uniform_int<vertices_size_type> rand_vertex_gen(0, n-1);
      double x = rand01();
      *gen = rand01.base(); // GRRRR
      if (x < prob) {
        vertices_size_type lower = (source + n - k/2) % n;
        vertices_size_type upper = (source + k/2) % n;
        do {
          current.second = rand_vertex_gen(*gen);
        } while ((current.second >= lower && current.second <= upper)
                 || (upper < lower
                     && (current.second >= lower || current.second <= upper)));
      } else {
        current.second = target;
      }
      return *this;
    }
    small_world_iterator(RandomGenerator& gen, vertices_size_type n, 
                         vertices_size_type k, double prob = 0.0, 
                         bool allow_self_loops = false, bool allow_multiple_edges = true) 
      : gen(&gen), n(n), k(k+k%2), prob(prob), source(0), 
        target(allow_self_loops? 0 : 1), 
        allow_self_loops(allow_self_loops),
        allow_multiple_edges(allow_multiple_edges), 
        current(0, allow_self_loops? 0 : 1),
#if !defined BOOST_NO_HASH
	edges(allow_multiple_edges? 0 : (k + k%2)*n/2)
#else
	edges()
#endif 
    {}

    reference operator*() const { return current; }
    pointer operator->() const { return &current; }
    
    small_world_iterator& operator++()
    { 
      current.first = source;

      uniform_01<RandomGenerator, double> rand01(*gen);
      uniform_int<vertices_size_type> rand_vertex_gen(0, n-1);
      double x = rand01();
      *gen = rand01.base(); // GRRRR
      vertices_size_type larger_v = 0;
      vertices_size_type smaller_v = 0;
      if (x < prob) {
        do {
          current.second = rand_vertex_gen(*gen);
	  if (!allow_multiple_edges) {
	    larger_v = current.first;
	    smaller_v = current.second;
	    if (current.first < current.second) {
	      smaller_v = current.first;
	      larger_v = current.second;
	    }
	  }
	  // std::cout << "swg " << current.first << " " << current.second << " " << smaller_v*n + larger_v << std::endl;
        } while ((!allow_self_loops && current.first == current.second)
		 ||
		 (!allow_multiple_edges && (current.first < k/2 && current.second >= n - k/2 + current.first))
		 ||
		 (!allow_multiple_edges && (edges.find(smaller_v*n + larger_v) != edges.end())));
      } else {
        current.second = target;
	if (!allow_multiple_edges) {
	  larger_v = current.first;
	  smaller_v = current.second;
	  if (current.first < current.second) {
	    smaller_v = current.first;
	    larger_v = current.second;
	  }
	}
      }

      if (!allow_multiple_edges) {
	edges.insert(smaller_v*n + larger_v);
	// std::cout << "added " << current.first << " " << current.second << " " << smaller_v*n + larger_v << std::endl;
      }

      target = (target + 1) % n;
      if (target == (source + k/2 + 1) % n) {
        ++source;
        if (allow_self_loops) target = source;
        else target = (source + 1) % n;
      }

      return *this;
    }

    small_world_iterator operator++(int)
    {
      small_world_iterator temp(*this);
      ++(*this);
      return temp;
    }