// Copyright (C) 2007-2008 The Trustees of Indiana University. // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef BOOST_NO_EXCEPTIONS void boost::throw_exception(std::exception const& ex) { std::cout << ex.what() << std::endl; abort(); } #endif using namespace boost; using namespace std; using boost::graph::distributed::mpi_process_group; /// VertexProperties structure to be attached to each vertex struct VertexProperties { VertexProperties() { cash = 100; goods = 10; price = 0.1; } /* VertexProperties(double cash = 100, double goods = 10, double price = 0.1) : cash(cash), goods(goods), price(price) { }*/ template void serialize(Archiver& ar, const unsigned int /*version*/) { ar & cash & goods & price; } double cash; double goods; double price; }; struct EdgeProperties { EdgeProperties() { cash = 0; goods = 0; index = 0; } EdgeProperties(size_t i, double c, double g) : index(i), cash(c), goods(g) { } public: std::size_t index; double cash; double goods; friend class serialization::access; template void serialize(Archive & ar, const unsigned int version) { ar & index & cash & goods; } }; double lambda = 0.2; double mu = 0.3; double tau = 10; double eps = 0.01; typedef boost::adjacency_list, bidirectionalS, VertexProperties, EdgeProperties> Graph; typedef graph_traits::vertex_descriptor Vertex; typedef graph_traits::edge_descriptor Edge; struct remote_key_e { remote_key_e(int p = -1, Edge l = Edge()) : processor(p){local_key = &l; } int processor; Edge* local_key; template void serialize(Archiver& ar, const unsigned int /*version*/) { ar & processor & local_key; } }; namespace boost { template<> struct hash { std::size_t operator()(const remote_key_e& key) const { std::size_t hash = hash_value(key.processor); hash_combine(hash, key.local_key); return hash; } }; } inline bool operator==(const remote_key_e& x, const remote_key_e& y) { return x.processor == y.processor && (*(x.local_key)) == (*(y.local_key)); } struct remote_key_to_global_e { typedef readable_property_map_tag category; typedef remote_key_e key_type; typedef std::pair value_type; typedef value_type reference; }; inline std::pair get(remote_key_to_global_e, const remote_key_e& key) { return std::make_pair(key.processor, *(key.local_key)); } template class Remover { public: Remover(const double min, const GMap& egoods, const PMap& price, const Graph& graph) : m_min(min), m_egoods(egoods), m_price(price), m_graph(graph) {} template bool operator()(ED w) const { return m_price[target(w, m_graph)] > tau * m_min || m_egoods[w] < eps; } private: const Graph& m_graph; const GMap& m_egoods; const PMap& m_price; const double m_min; }; template class Remover_1 { public: Remover_1(const Graph& graph) : m_graph(graph) {} template bool operator()(ED w) const { return target(w, m_graph) == source(w, m_graph); } private: const Graph& m_graph; }; template struct rank_accumulate_reducer { static const bool non_default_resolver = false; // The default rank of an unknown node template T operator()(const K&) const {return T(0); } template T operator()(const K&, const T& x, const T& y) const { return x; } }; int test_main(int argc, char** argv) { boost::mpi::environment env(argc, argv); //Random scale-free typedef boost::unique_rmat_iterator RMATGen; boost::minstd_rand gen; Graph g(RMATGen(gen, 100, 1000, 0.57, 0.19, 0.19, 0.05), RMATGen(), 100); mpi_process_group pg = g.process_group(); synchronize(g); property_map::type index_map = get(vertex_index, g); typedef property_map::type egoods_map; typedef property_map::type ecash_map; typedef property_map::type price_map; //Vertex iterator distributed property maps typedef property_map::const_type VertexIndexMap; typedef iterator_property_map::iterator, VertexIndexMap> d_index_map; std::vector index_S(num_vertices(g), std::numeric_limits::max()); d_index_map d_index(index_S.begin(), get(vertex_index, g)); d_index.set_reduce(rank_accumulate_reducer()); synchronize(g); //Delete self-edges Remover_1 r(g); remove_edge_if(r, g); synchronize(g); boost::graph_traits::vertex_iterator vit, vit_end; boost::graph_traits::in_edge_iterator it, it_end; boost::graph_traits::out_edge_iterator oit, oit_end; for(boost::tie(vit,vit_end) = vertices(g); vit != vit_end; ++vit) { cout << index_map[*vit] << " --> "; for (boost::tie(oit,oit_end) = out_edges(*vit, g); oit != oit_end; ++oit) cout << index_map[target(*oit, g)] << " "; cout << endl; } for(boost::tie(vit,vit_end) = vertices(g); vit != vit_end; ++vit) { cout << index_map[*vit] << " <-- "; for (boost::tie(it,it_end) = in_edges(*vit, g); it != it_end; ++it) cout << index_map[source(*it, g)] << " "; cout << endl; } return 0; }