25 #include <boost/numeric/conversion/cast.hpp>
26 #include <boost/random/uniform_int.hpp>
34 #include "../exceptions.h"
36 #include "clustered_ba.h"
39 namespace pagmo {
namespace topology {
53 m_m0(
boost::numeric_cast<
std::size_t>(m0)),m_m(
boost::numeric_cast<
std::size_t>(m)), m_p(double(p)),
56 if (m0 < 2 || m < 1 || m > m0) {
57 pagmo_throw(value_error,
"the value of m and m0 must be at least 1 and 2, and m must not be greater than m0");
60 pagmo_throw(value_error,
"the value of p must be between 0 and 1");
73 if (prev_size < m_m0) {
78 const double prob = 0.0;
80 bool connection_added =
false;
82 for (std::pair<v_iterator,v_iterator> vertices =
get_vertices(); vertices.first != vertices.second; ++vertices.first) {
84 if (*vertices.first != idx) {
85 if (m_drng() < prob) {
86 connection_added =
true;
95 if ((!connection_added) && (prev_size != 0)) {
101 rnd = uni_int(m_urng);
102 }
while (rnd == idx);
113 boost::uniform_int<edges_size_type> uni_int2(1,m_m);
115 std::size_t j = uni_int2(m_urng);
116 std::pair<v_iterator,v_iterator> vertices;
117 std::pair<a_iterator,a_iterator> adj_vertices;
121 pagmo_assert(n_edges > 0);
122 boost::uniform_int<edges_size_type> uni_int(0,n_edges - 1 - i);
131 for (; vertices.first != vertices.second; ++vertices.first) {
133 if (*vertices.first != idx) {
135 n += boost::numeric_cast<
edges_size_type>(std::distance(adj_vertices.first,adj_vertices.second));
141 pagmo_assert(vertices.first != vertices.second);
147 for(;adj_vertices.first != adj_vertices.second; ++adj_vertices.first) {
148 if(m_drng() < m_p && *adj_vertices.first != *vertices.first && !
are_adjacent(*adj_vertices.first,*vertices.first)) {
149 add_edge(*adj_vertices.first, *vertices.first);
150 add_edge(*vertices.first, *adj_vertices.first);
171 std::ostringstream oss;
172 oss <<
"\tm0 = " << m_m0 <<
'\n';
173 oss <<
"\tm = " << m_m <<
'\n';
174 oss <<
"\tp = " << m_p <<
'\n';
180 return "Clustered Barabasi-Albert";
Generic thread-safe generator of pseudo-random number generators.
std::string get_name() const
Get name of the topology.
boost::shared_ptr< base > base_ptr
Alias for shared pointer to base topology.
base_ptr clone() const
Clone method.
This rng returns an unsigned integer in the [0,2**32-1] range.
graph_type::edges_size_type edges_size_type
Edges size type.
clustered_ba(int m0=3, int m=2, double p=0.5)
Constructor from kernel size and number of edges.
vertices_size_type get_number_of_vertices() const
Get number of vertices.
std::string human_readable_extra() const
Topology-specific human readable info.
Barabási-Albert graph topology.
graph_type::vertices_size_type vertices_size_type
Vertices size type.
void add_edge(const vertices_size_type &, const vertices_size_type &)
Add an edge.
edges_size_type get_number_of_edges() const
Get number of edges.
std::pair< a_iterator, a_iterator > get_adjacent_vertices(const vertices_size_type &) const
Return iterator range to adjacent vertices.
This rng returns a double in the [0,1[ range.
std::pair< v_iterator, v_iterator > get_vertices() const
Return iterator range to vertices.
void connect(const vertices_size_type &)
Establish connections between islands during a push_back() operation.
bool are_adjacent(const vertices_size_type &, const vertices_size_type &) const
Return true if two vertices are adjacent.