/** * Will return a formatted string containing: * - the output of get_name(), * - the number of vertices, * - the output of human_readable_extra(). * * @return string containing terse human readable representation of the topology. */ std::string base::human_readable_terse() const { std::ostringstream s; s << "Topology type: " << get_name() << '\n'; s << "\tNumber of vertices: " << get_number_of_vertices() << '\n'; s << "\tNumber of edges: " << get_number_of_edges() << '\n'; s << human_readable_extra() << '\n'; return s.str(); }
void clustered_ba::connect(const vertices_size_type &idx) { pagmo_assert(get_number_of_vertices() > 0); const vertices_size_type prev_size = get_number_of_vertices() - 1; if (prev_size < m_m0) { // If we had not built the initial m0 nodes, do it. // We want to connect the newcomer island with high probability, and make sure that // at least one connection exists (otherwise the island stays isolated). // NOTE: is it worth to make it a user-tunable parameter? const double prob = 0.0; // Flag indicating if at least 1 connection was added. bool connection_added = false; // Main loop. for (std::pair<v_iterator,v_iterator> vertices = get_vertices(); vertices.first != vertices.second; ++vertices.first) { // Do not consider the new vertex itself. if (*vertices.first != idx) { if (m_drng() < prob) { connection_added = true; // Add the connections add_edge(*vertices.first,idx); add_edge(idx,*vertices.first); } } } // If no connections were established and this is not the first island being inserted, // establish at least one connection with a random island other than n. if ((!connection_added) && (prev_size != 0)) { // Get a random vertex index between 0 and n_vertices - 1. Keep on repeating the procedure if by // chance we end up on idx again. boost::uniform_int<vertices_size_type> uni_int(0,get_number_of_vertices() - 1); vertices_size_type rnd; do { rnd = uni_int(m_urng); } while (rnd == idx); // Add connections to the random vertex. add_edge(rnd,idx); add_edge(idx,rnd); } } else { // Now we need to add j edges, choosing the nodes with a probability // proportional to their number of connections. We keep track of the // connection established in order to avoid connecting twice to the same // node. // j is a random integer in the range 1 to m. boost::uniform_int<edges_size_type> uni_int2(1,m_m); std::size_t i = 0; std::size_t j = uni_int2(m_urng); std::pair<v_iterator,v_iterator> vertices; std::pair<a_iterator,a_iterator> adj_vertices; while (i < j) { // Let's find the current total number of edges. const edges_size_type n_edges = get_number_of_edges(); pagmo_assert(n_edges > 0); boost::uniform_int<edges_size_type> uni_int(0,n_edges - 1 - i); // Here we choose a random number between 0 and n_edges - 1 - i. const edges_size_type rn = uni_int(m_urng); edges_size_type n = 0; // Iterate over all vertices and accumulate the number of edges for each of them. Stop when the accumulated number of edges is greater // than rn. This is equivalent to giving a chance of connection to vertex v directly proportional to the number of edges departing from v. // You can think of this process as selecting a random edge among all the existing edges and connecting to the vertex from which the // selected edge departs. vertices = get_vertices(); for (; vertices.first != vertices.second; ++vertices.first) { // Do not consider it_n. if (*vertices.first != idx) { adj_vertices = get_adjacent_vertices(*vertices.first); n += boost::numeric_cast<edges_size_type>(std::distance(adj_vertices.first,adj_vertices.second)); if (n > rn) { break; } } } pagmo_assert(vertices.first != vertices.second); // If the candidate was not already connected, then add it. if (!are_adjacent(idx,*vertices.first)) { // Connect to nodes that are already adjacent to idx with probability p. // This step increases clustering in the network. adj_vertices = get_adjacent_vertices(idx); for(;adj_vertices.first != adj_vertices.second; ++adj_vertices.first) { if(m_drng() < m_p && *adj_vertices.first != *vertices.first && !are_adjacent(*adj_vertices.first,*vertices.first)) { add_edge(*adj_vertices.first, *vertices.first); add_edge(*vertices.first, *adj_vertices.first); } } // Connect to idx add_edge(*vertices.first,idx); add_edge(idx,*vertices.first); ++i; } } } }