Transitive Reduction

Computes the minimal equivalent graph: removes all edges that can be inferred from other paths. If there is an edge u→v and also a longer path u→…​→v, the direct edge is redundant and is removed.

Complexity: O(V * (V + E))
Defined in: <boost/graph/transitive_reduction.hpp>

Example

#include <iostream>
#include <vector>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/transitive_reduction.hpp>

int main() {
    using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS>;
    using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
    Graph g(4);
    boost::add_edge(0, 1, g);
    boost::add_edge(1, 2, g);
    boost::add_edge(0, 2, g); // redundant: 0->1->2
    boost::add_edge(2, 3, g);
    boost::add_edge(0, 3, g); // redundant: 0->1->2->3

    std::cout << "Before (" << num_edges(g) << " edges):";
    for (auto ep = edges(g); ep.first != ep.second; ++ep.first)
        std::cout << " " << source(*ep.first, g) << "->" << target(*ep.first, g);
    std::cout << "\n";

    Graph tr;
    std::vector<Vertex> g_to_tr(num_vertices(g));
    boost::transitive_reduction(g, tr,
        boost::make_iterator_property_map(g_to_tr.begin(), get(boost::vertex_index, g)),
        get(boost::vertex_index, g));

    std::cout << "After  (" << num_edges(tr) << " edges):";
    for (auto ep = edges(tr); ep.first != ep.second; ++ep.first)
        std::cout << " " << source(*ep.first, tr) << "->" << target(*ep.first, tr);
    std::cout << "\n";
}
Before (5 edges): 0->1 0->2 0->3 1->2 2->3
After  (3 edges): 0->1 1->2 2->3

Synopsis

template <typename Graph, typename GraphTR,
          typename VertexMap, typename VertexIndexMap>
void transitive_reduction(const Graph& g, GraphTR& tr,
                          VertexMap g_to_tr_map,
                          VertexIndexMap index_map);
Direction Parameter Description

IN

const Graph& g

The input DAG. Must model VertexListGraph and IncidenceGraph.

OUT

GraphTR& tr

The output graph (transitive reduction). Must model MutableGraph.

OUT

VertexMap g_to_tr_map

Maps vertices of g to corresponding vertices in tr.

IN

VertexIndexMap index_map

Vertex index map for g.

The input graph must be a DAG. Behavior is undefined on graphs with cycles.