File indexing completed on 2025-01-18 09:37:37
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_GRAPH_SSCA_GENERATOR_HPP
0010 #define BOOST_GRAPH_SSCA_GENERATOR_HPP
0011
0012 #include <iterator>
0013 #include <utility>
0014 #include <vector>
0015 #include <queue>
0016 #include <boost/config.hpp>
0017 #include <boost/random/uniform_int.hpp>
0018 #include <boost/graph/graph_traits.hpp>
0019 #include <boost/type_traits/is_base_and_derived.hpp>
0020 #include <boost/type_traits/is_same.hpp>
0021
0022 enum Direction
0023 {
0024 FORWARD = 1,
0025 BACKWARD = 2,
0026 BOTH = FORWARD | BACKWARD
0027 };
0028
0029 namespace boost
0030 {
0031
0032
0033
0034
0035 template < typename RandomGenerator, typename Graph > class ssca_iterator
0036 {
0037 typedef typename graph_traits< Graph >::directed_category directed_category;
0038 typedef
0039 typename graph_traits< Graph >::vertices_size_type vertices_size_type;
0040
0041 public:
0042 typedef std::input_iterator_tag iterator_category;
0043 typedef std::pair< vertices_size_type, vertices_size_type > value_type;
0044 typedef const value_type& reference;
0045 typedef const value_type* pointer;
0046 typedef void difference_type;
0047
0048
0049 ssca_iterator() : gen(), verticesRemaining(0) {}
0050
0051
0052 ssca_iterator(RandomGenerator& gen, vertices_size_type totVertices,
0053 vertices_size_type maxCliqueSize, double probUnidirectional,
0054 int maxParallelEdges, double probIntercliqueEdges)
0055 : gen(&gen)
0056 , totVertices(totVertices)
0057 , maxCliqueSize(maxCliqueSize)
0058 , probUnidirectional(probUnidirectional)
0059 , maxParallelEdges(maxParallelEdges)
0060 , probIntercliqueEdges(probIntercliqueEdges)
0061 , currentClique(0)
0062 , verticesRemaining(totVertices)
0063 {
0064 cliqueNum = std::vector< int >(totVertices, -1);
0065 current = std::make_pair(0, 0);
0066 }
0067
0068 reference operator*() const { return current; }
0069 pointer operator->() const { return ¤t; }
0070
0071 ssca_iterator& operator++()
0072 {
0073 BOOST_USING_STD_MIN();
0074 while (values.empty() && verticesRemaining > 0)
0075 {
0076 uniform_int< vertices_size_type > clique_size(1, maxCliqueSize);
0077 uniform_int< vertices_size_type > rand_vertex(0, totVertices - 1);
0078 uniform_int< int > num_parallel_edges(1, maxParallelEdges);
0079 uniform_int< short > direction(0, 1);
0080 uniform_01< RandomGenerator > prob(*gen);
0081 std::vector< vertices_size_type > cliqueVertices;
0082
0083 cliqueVertices.clear();
0084 vertices_size_type size = min BOOST_PREVENT_MACRO_SUBSTITUTION(
0085 clique_size(*gen), verticesRemaining);
0086 while (cliqueVertices.size() < size)
0087 {
0088 vertices_size_type v = rand_vertex(*gen);
0089 if (cliqueNum[v] == -1)
0090 {
0091 cliqueNum[v] = currentClique;
0092 cliqueVertices.push_back(v);
0093 verticesRemaining--;
0094 }
0095 }
0096
0097
0098
0099 typename std::vector< vertices_size_type >::iterator first, second;
0100 for (first = cliqueVertices.begin(); first != cliqueVertices.end();
0101 ++first)
0102 for (second = first + 1; second != cliqueVertices.end();
0103 ++second)
0104 {
0105 Direction d;
0106 int edges;
0107
0108 d = prob() < probUnidirectional
0109 ? (direction(*gen) == 0 ? FORWARD : BACKWARD)
0110 : BOTH;
0111
0112 if (d & FORWARD)
0113 {
0114 edges = num_parallel_edges(*gen);
0115 for (int i = 0; i < edges; ++i)
0116 values.push(std::make_pair(*first, *second));
0117 }
0118
0119 if (d & BACKWARD)
0120 {
0121 edges = num_parallel_edges(*gen);
0122 for (int i = 0; i < edges; ++i)
0123 values.push(std::make_pair(*second, *first));
0124 }
0125 }
0126
0127 if (verticesRemaining == 0)
0128 {
0129
0130 for (vertices_size_type i = 0; i < totVertices; ++i)
0131 {
0132 double p = probIntercliqueEdges;
0133 for (vertices_size_type d = 2; d < totVertices / 2;
0134 d *= 2, p /= 2)
0135 {
0136 vertices_size_type j = (i + d) % totVertices;
0137 if (cliqueNum[j] != cliqueNum[i] && prob() < p)
0138 {
0139 int edges = num_parallel_edges(*gen);
0140 for (int i = 0; i < edges; ++i)
0141 values.push(std::make_pair(i, j));
0142 }
0143 }
0144 }
0145 }
0146
0147 currentClique++;
0148 }
0149
0150 if (!values.empty())
0151 {
0152 current = values.front();
0153 values.pop();
0154 }
0155
0156 return *this;
0157 }
0158
0159 ssca_iterator operator++(int)
0160 {
0161 ssca_iterator temp(*this);
0162 ++(*this);
0163 return temp;
0164 }
0165
0166 bool operator==(const ssca_iterator& other) const
0167 {
0168 return verticesRemaining == other.verticesRemaining && values.empty()
0169 && other.values.empty();
0170 }
0171
0172 bool operator!=(const ssca_iterator& other) const
0173 {
0174 return !(*this == other);
0175 }
0176
0177 private:
0178
0179 RandomGenerator* gen;
0180 vertices_size_type totVertices;
0181 vertices_size_type maxCliqueSize;
0182 double probUnidirectional;
0183 int maxParallelEdges;
0184 double probIntercliqueEdges;
0185
0186
0187 std::vector< int > cliqueNum;
0188 std::queue< value_type > values;
0189 int currentClique;
0190 vertices_size_type verticesRemaining;
0191 value_type current;
0192 };
0193
0194 }
0195
0196 #endif