123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- #ifndef BOOST_GRAPH_TRANSITIVE_REDUCTION_HPP
- #define BOOST_GRAPH_TRANSITIVE_REDUCTION_HPP
- #include <vector>
- #include <algorithm> //std::find
- #include <boost/concept/requires.hpp>
- #include <boost/concept_check.hpp>
- #include <boost/graph/graph_traits.hpp>
- #include <boost/graph/topological_sort.hpp>
- namespace boost {
- template <
- typename Graph, typename GraphTR, typename G_to_TR_VertexMap,
- typename VertexIndexMap
- >
- BOOST_CONCEPT_REQUIRES(
- ((VertexListGraphConcept< Graph >))
- ((IncidenceGraphConcept< Graph >))
- ((MutableGraphConcept< GraphTR >))
- ((ReadablePropertyMapConcept< VertexIndexMap,
- typename graph_traits<Graph>::vertex_descriptor >))
- ((Integer< typename
- property_traits< VertexIndexMap >::value_type >))
- ((LvaluePropertyMapConcept< G_to_TR_VertexMap,
- typename graph_traits<Graph>::vertex_descriptor >)),
- (void))
- transitive_reduction(const Graph& g, GraphTR& tr,
- G_to_TR_VertexMap g_to_tr_map,
- VertexIndexMap g_index_map )
- {
- typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
- typedef typename graph_traits<Graph>::vertex_iterator VertexIterator;
- typedef typename std::vector<Vertex>::size_type size_type;
- std::vector<Vertex> topo_order;
- topological_sort(g, std::back_inserter(topo_order));
- std::vector<size_type> topo_number_storage(num_vertices(g));
- iterator_property_map<size_type*, VertexIndexMap,
- size_type, size_type&> topo_number( &topo_number_storage[0], g_index_map );
- {
- typename std::vector<Vertex>::reverse_iterator it = topo_order.rbegin();
- size_type n = 0;
- for(; it != topo_order.rend(); ++it,++n ) {
- topo_number[ *it ] = n;
- }
- }
- std::vector< std::vector< bool > > edge_in_closure(num_vertices(g),
- std::vector<bool>( num_vertices(g), false));
- {
- typename std::vector<Vertex>::reverse_iterator it = topo_order.rbegin();
- for( ; it != topo_order.rend(); ++it ) {
- g_to_tr_map[*it] = add_vertex(tr);
- }
- }
- typename std::vector<Vertex>::iterator
- it = topo_order.begin(),
- end = topo_order.end();
- for( ; it != end; ++it ) {
- size_type i = topo_number[ *it ];
- edge_in_closure[i][i] = true;
- std::vector<Vertex> neighbors;
-
-
-
- {
- typename Graph::out_edge_iterator oi,oi_end;
- for( boost::tie(oi, oi_end) = out_edges( *it, g ); oi != oi_end; ++oi ) {
- neighbors.push_back( target( *oi, g ) );
- }
- }
- {
-
- typename std::vector<Vertex>::reverse_iterator
- rit = topo_order.rbegin(),
- rend = topo_order.rend();
- for(; rit != rend; ++rit ) {
-
- if( std::find( neighbors.begin(), neighbors.end(), *rit) != neighbors.end() ) {
- size_type j = topo_number[ *rit ];
- if( not edge_in_closure[i][j] ) {
- for(size_type k = j; k < num_vertices(g); ++k) {
- if( not edge_in_closure[i][k] ) {
-
- edge_in_closure[i][k] = edge_in_closure[j][k];
- }
- }
-
-
- add_edge(g_to_tr_map[*it], g_to_tr_map[*rit], tr);
- }
- }
- }
- }
- }
- }
- }
- #endif
|