epoc32/include/stdapis/boost/graph/small_world_generator.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:33:34 +0100
branchSymbian3
changeset 4 837f303aceeb
permissions -rw-r--r--
Current Symbian^3 public API header files (from PDK 3.0.h)
This is the epoc32/include tree with the "platform" subtrees removed, and
all but a selected few mbg and rsg files removed.
williamr@2
     1
// Copyright 2004 The Trustees of Indiana University.
williamr@2
     2
williamr@2
     3
// Distributed under the Boost Software License, Version 1.0.
williamr@2
     4
// (See accompanying file LICENSE_1_0.txt or copy at
williamr@2
     5
// http://www.boost.org/LICENSE_1_0.txt)
williamr@2
     6
williamr@2
     7
//  Authors: Douglas Gregor
williamr@2
     8
//           Andrew Lumsdaine
williamr@2
     9
#ifndef BOOST_GRAPH_SMALL_WORLD_GENERATOR_HPP
williamr@2
    10
#define BOOST_GRAPH_SMALL_WORLD_GENERATOR_HPP
williamr@2
    11
williamr@2
    12
#include <iterator>
williamr@2
    13
#include <utility>
williamr@2
    14
#include <boost/random/uniform_01.hpp>
williamr@2
    15
#include <boost/random/uniform_int.hpp>
williamr@2
    16
williamr@2
    17
namespace boost {
williamr@2
    18
williamr@2
    19
  // Assumes undirected
williamr@2
    20
  template<typename RandomGenerator, typename Graph>
williamr@2
    21
  class small_world_iterator
williamr@2
    22
  {
williamr@2
    23
    typedef typename graph_traits<Graph>::vertices_size_type 
williamr@2
    24
      vertices_size_type;
williamr@2
    25
williamr@2
    26
  public:
williamr@2
    27
    typedef std::input_iterator_tag iterator_category;
williamr@2
    28
    typedef std::pair<vertices_size_type, vertices_size_type> value_type;
williamr@2
    29
    typedef const value_type& reference;
williamr@2
    30
    typedef const value_type* pointer;
williamr@2
    31
    typedef void difference_type;
williamr@2
    32
williamr@2
    33
    small_world_iterator() : gen(0) {}
williamr@2
    34
    small_world_iterator(RandomGenerator& gen, vertices_size_type n, 
williamr@2
    35
                         vertices_size_type k, double prob = 0.0, 
williamr@2
    36
                         bool allow_self_loops = false) 
williamr@2
    37
      : gen(&gen), n(n), k(k), prob(prob), source(0), 
williamr@2
    38
        target(allow_self_loops? 0 : 1), 
williamr@2
    39
        allow_self_loops(allow_self_loops), 
williamr@2
    40
        current(0, allow_self_loops? 0 : 1)
williamr@2
    41
    { }
williamr@2
    42
williamr@2
    43
    reference operator*() const { return current; }
williamr@2
    44
    pointer operator->() const { return &current; }
williamr@2
    45
    
williamr@2
    46
    small_world_iterator& operator++()
williamr@2
    47
    { 
williamr@2
    48
      target = (target + 1) % n;
williamr@2
    49
      if (target == (source + k/2 + 1) % n) {
williamr@2
    50
        ++source;
williamr@2
    51
        if (allow_self_loops) target = source;
williamr@2
    52
        else target = (source + 1) % n;
williamr@2
    53
      }
williamr@2
    54
      current.first = source;
williamr@2
    55
williamr@2
    56
      uniform_01<RandomGenerator, double> rand01(*gen);
williamr@2
    57
      uniform_int<vertices_size_type> rand_vertex_gen(0, n-1);
williamr@2
    58
      double x = rand01();
williamr@2
    59
      *gen = rand01.base(); // GRRRR
williamr@2
    60
      if (x < prob) {
williamr@2
    61
        vertices_size_type lower = (source + n - k/2) % n;
williamr@2
    62
        vertices_size_type upper = (source + k/2) % n;
williamr@2
    63
        do {
williamr@2
    64
          current.second = rand_vertex_gen(*gen);
williamr@2
    65
        } while (current.second >= lower && current.second <= upper
williamr@2
    66
                 || (upper < lower 
williamr@2
    67
                     && (current.second >= lower || current.second <= upper)));
williamr@2
    68
      } else {
williamr@2
    69
        current.second = target;
williamr@2
    70
      }
williamr@2
    71
      return *this;
williamr@2
    72
    }
williamr@2
    73
williamr@2
    74
    small_world_iterator operator++(int)
williamr@2
    75
    {
williamr@2
    76
      small_world_iterator temp(*this);
williamr@2
    77
      ++(*this);
williamr@2
    78
      return temp;
williamr@2
    79
    }
williamr@2
    80
williamr@2
    81
    bool operator==(const small_world_iterator& other) const
williamr@2
    82
    {
williamr@2
    83
      if (!gen && other.gen) return other == *this;
williamr@2
    84
      else if (gen && !other.gen) return source == n;
williamr@2
    85
      else if (!gen && !other.gen) return true;
williamr@2
    86
      return source == other.source && target == other.target;
williamr@2
    87
    }
williamr@2
    88
williamr@2
    89
    bool operator!=(const small_world_iterator& other) const
williamr@2
    90
    { return !(*this == other); }
williamr@2
    91
williamr@2
    92
  private:
williamr@2
    93
    void next()
williamr@2
    94
    {
williamr@2
    95
      uniform_int<vertices_size_type> rand_vertex(0, n-1);
williamr@2
    96
      current.first = rand_vertex(*gen);
williamr@2
    97
      do {
williamr@2
    98
        current.second = rand_vertex(*gen);
williamr@2
    99
      } while (current.first == current.second && !allow_self_loops);
williamr@2
   100
    }
williamr@2
   101
williamr@2
   102
    RandomGenerator* gen;
williamr@2
   103
    vertices_size_type n;
williamr@2
   104
    vertices_size_type k;
williamr@2
   105
    double prob;
williamr@2
   106
    vertices_size_type source;
williamr@2
   107
    vertices_size_type target;
williamr@2
   108
    bool allow_self_loops;
williamr@2
   109
    value_type current;
williamr@2
   110
  };
williamr@2
   111
williamr@2
   112
} // end namespace boost
williamr@2
   113
williamr@2
   114
#endif // BOOST_GRAPH_SMALL_WORLD_GENERATOR_HPP