26 #include <boost/graph/adjacency_list.hpp>
27 #include <boost/graph/johnson_all_pairs_shortest.hpp>
28 #include <boost/numeric/conversion/cast.hpp>
37 #include "../exceptions.h"
40 namespace pagmo {
namespace topology {
88 return typeid(*this).name();
102 std::ostringstream s;
103 s <<
"Topology type: " <<
get_name() <<
'\n';
120 std::ostringstream s;
122 s <<
"Connections:\n\n";
123 std::pair<v_iterator,v_iterator> vertices =
get_vertices();
124 std::pair<a_iterator,a_iterator> adj_vertices;
125 for (; vertices.first != vertices.second; ++vertices.first) {
127 s << (*vertices.first);
128 if (adj_vertices.first != adj_vertices.second) {
130 while (adj_vertices.first != adj_vertices.second) {
131 s << (*adj_vertices.first);
132 ++adj_vertices.first;
133 if (adj_vertices.first != adj_vertices.second) {
153 return std::string();
164 boost::add_vertex(m_graph);
168 void base::check_vertex_index(
const vertices_size_type &idx)
const
170 if (idx >= num_vertices(m_graph)) {
171 pagmo_throw(value_error,
"invalid vertex index");
185 check_vertex_index(idx);
186 return boost::adjacent_vertices(boost::vertex(idx,m_graph),m_graph);
200 return std::vector<base::vertices_size_type>(tmp.first,tmp.second);
214 check_vertex_index(n);
215 check_vertex_index(m);
217 const std::pair<a_iterator,a_iterator> a_vertices = boost::adjacent_vertices(boost::vertex(n,m_graph),m_graph);
218 return std::find(a_vertices.first,a_vertices.second,boost::vertex(m,m_graph)) != a_vertices.second;
232 return boost::numeric_cast<
edges_size_type>(std::distance(v.first,v.second));
246 check_vertex_index(n);
247 check_vertex_index(m);
249 const std::pair<ia_iterator,ia_iterator> ia_vertices = boost::inv_adjacent_vertices(boost::vertex(n,m_graph),m_graph);
250 return std::find(ia_vertices.first,ia_vertices.second,boost::vertex(m,m_graph)) != ia_vertices.second;
263 check_vertex_index(idx);
264 return boost::inv_adjacent_vertices(boost::vertex(idx,m_graph),m_graph);
278 return std::vector<base::vertices_size_type>(tmp.first,tmp.second);
288 return boost::numeric_cast<
edges_size_type>(std::distance(v.first,v.second));
301 pagmo_throw(value_error,
"cannot add edge, vertices are already connected");
303 const std::pair<e_descriptor,bool> result = boost::add_edge(boost::vertex(n,m_graph),boost::vertex(m,m_graph),m_graph);
304 pagmo_assert(result.second);
316 if (w < 0.0 || w > 1.0) {
317 pagmo_throw(value_error,
"invalid migration probability");
319 m_graph[e].migr_probability = w;
330 return m_graph[e].migr_probability;
340 std::pair<e_iterator, e_iterator> es = boost::edges(m_graph);
341 for(; es.first != es.second; ++es.first) {
354 std::pair<a_iterator,a_iterator> adj_vertices = boost::adjacent_vertices(boost::vertex(n, m_graph), m_graph);
355 for(; adj_vertices.first != adj_vertices.second; ++adj_vertices.first) {
356 const std::pair<e_descriptor, bool> e = boost::edge(boost::vertex(n, m_graph), *adj_vertices.first, m_graph);
372 pagmo_throw(value_error,
"cannot set edge weight, vertices are not connected");
374 const std::pair<e_descriptor, bool> e = boost::edge(n, m, m_graph);
389 pagmo_throw(value_error,
"cannot get edge weight, vertices are not connected");
391 const std::pair<e_descriptor, bool> e = boost::edge(n, m, m_graph);
405 pagmo_throw(value_error,
"cannot remove edge, vertices are not connected");
407 boost::remove_edge(boost::vertex(n,m_graph),boost::vertex(m,m_graph),m_graph);
416 for (std::pair<v_iterator,v_iterator> vertices =
get_vertices(); vertices.first != vertices.second; ++vertices.first) {
417 boost::clear_vertex(*vertices.first,m_graph);
429 return boost::vertices(m_graph);
438 return boost::num_vertices(m_graph);
447 return boost::num_edges(m_graph);
464 std::map<e_descriptor, int> map;
465 boost::associative_property_map<std::map<e_descriptor, int> > map2(map);
466 std::pair<e_iterator, e_iterator> es = boost::edges(m_graph);
467 for(; es.first != es.second; ++es.first) {
468 map2[(*es.first)] = 1;
472 std::vector<std::vector<int> > D(boost::numeric_cast<std::vector<std::vector<int> >::size_type>(
get_number_of_vertices()),
474 boost::johnson_all_pairs_shortest_paths(m_graph, D, weight_map(map2));
476 for (std::vector<std::vector<int> >::size_type i = 0; i < D.size(); ++i) {
477 for (std::vector<int>::size_type j = 0; j < D[i].size(); ++j) {
494 std::pair<v_iterator, v_iterator> vertices;
495 std::vector<base::vertices_size_type> adj_vertices;
498 for(; vertices.first != vertices.second; vertices.first++) {
500 if(adj_vertices.size() > 1) {
502 for(
unsigned int i = 0; i < adj_vertices.size()-1; i++) {
503 for(
unsigned int j = i; j < adj_vertices.size(); j++) {
504 if(i != j &&
are_adjacent(adj_vertices[i],adj_vertices[j])) {
505 cc += 2.0/(adj_vertices.size() * (adj_vertices.size() - 1));
529 std::pair<v_iterator, v_iterator> vertices;
534 for(; vertices.first != vertices.second; vertices.first++) {
537 std::vector<double> deg_dist(mx+1);
538 for(
int i = 0; i < mx; i++) deg_dist[i] = 0;
541 for(; vertices.first != vertices.second; vertices.first++) {
bool are_inv_adjacent(const vertices_size_type &, const vertices_size_type &) const
Return true if two vertices are inversely adjacent.
void add_vertex()
Add a vertex.
virtual ~base()
Trivial destructor.
std::vector< vertices_size_type > get_v_adjacent_vertices(const vertices_size_type &) const
Return vector of adjacent vertices.
graph_type::edges_size_type edges_size_type
Edges size type.
double get_clustering_coefficient() const
Calculate clustering coefficient.
double get_average_shortest_path_length() const
Calculate average path length.
void remove_edge(const vertices_size_type &, const vertices_size_type &)
Remove an edge.
edges_size_type get_num_inv_adjacent_vertices(const vertices_size_type &) const
Return the number of inversely adjacent vertices.
std::string human_readable() const
Return complete human readable representation.
std::string human_readable_terse() const
Return terse human readable representation.
vertices_size_type get_number_of_vertices() const
Get number of vertices.
std::vector< vertices_size_type > get_v_inv_adjacent_vertices(const vertices_size_type &) const
Return vector of inversely adjacent vertices.
graph_type::vertices_size_type vertices_size_type
Vertices size type.
edges_size_type get_num_adjacent_vertices(const vertices_size_type &) const
Return the number of adjacent vertices.
base & operator=(const base &)
Assignment operator.
boost::graph_traits< graph_type >::edge_descriptor e_descriptor
Edge descriptor.
std::vector< double > get_degree_distribution() const
Constructs the Degree Distribution.
virtual std::string human_readable_extra() const
Return extra information for human readable representation.
double get_weight(const vertices_size_type &, const vertices_size_type &) const
Get the migration probability.
void remove_all_edges()
Remove all edges.
base()
Default constructor.
std::pair< ia_iterator, ia_iterator > get_inv_adjacent_vertices(const vertices_size_type &) const
Return iterator range to inversely adjacent vertices.
std::ostream & operator<<(std::ostream &s, const base &t)
Overload stream insertion operator for topology::base.
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.
virtual void connect(const vertices_size_type &idx)=0
Establish connections between islands during a push_back() operation.
void push_back()
Push back vertex.
void set_weight(double)
Sets the migration probability.
std::pair< a_iterator, a_iterator > get_adjacent_vertices(const vertices_size_type &) const
Return iterator range to adjacent vertices.
virtual std::string get_name() const
Get name of the topology.
std::pair< v_iterator, v_iterator > get_vertices() const
Return iterator range to vertices.
bool are_adjacent(const vertices_size_type &, const vertices_size_type &) const
Return true if two vertices are adjacent.