pub fn contract_nodes_and_map<N, N2, E, E2, FN, FE, FC>(
    graph: &mut StableDiGraph<N, E>,
    nodes: &IxBitSet<NodeIndex>,
    mut node_map: FN,
    mut edge_map: FE,
    contract: FC,
) -> NodeIndex
where
    FN: FnMut(NodeIndex, N) -> N2,
    FE: FnMut(EdgeIndex, E) -> E2,
    FC: FnOnce(StableDiGraph<N2, E2>) -> N,
{
    debug_assert!(!nodes.is_empty());

    let mut preds = Vec::new();
    let mut succs = Vec::new();
    let mut internal_edges = Vec::new();

    // remove and store every edge incident to every node
    for n in nodes {
        {
            let mut neighbors = graph.neighbors_directed(n, Outgoing).detach();
            while let Some((edge, succ)) = neighbors.next(graph) {
                let weight = graph.remove_edge(edge).unwrap();
                if nodes.contains(succ) {
                    internal_edges.push((n, succ, edge_map(edge, weight)));
                } else {
                    succs.push((succ, weight));
                }
            }
        }
        {
            let mut neighbors = graph.neighbors_directed(n, Incoming).detach();
            while let Some((edge, pred)) = neighbors.next(graph) {
                let weight = graph.remove_edge(edge).unwrap();
                if nodes.contains(pred) {
                    internal_edges.push((pred, n, edge_map(edge, weight)));
                } else {
                    preds.push((pred, weight));
                }
            }
        }
    }

    let mut old_new_map = HashMap::with_capacity(nodes.len());
    let mut subgraph = StableDiGraph::with_capacity(nodes.len(), internal_edges.len());

    // move nodes
    for old_node in nodes {
        debug_assert!(graph.neighbors_undirected(old_node).next().is_none());
        let weight = graph.remove_node(old_node).unwrap();
        let new_node = subgraph.add_node(node_map(old_node, weight));
        old_new_map.insert(old_node, new_node);
    }

    // restore internal edges
    for (src, dst, weight) in internal_edges {
        subgraph.add_edge(old_new_map[&src], old_new_map[&dst], weight);
    }

    let contracted = graph.add_node(contract(subgraph));

    // restore external edges
    for (pred, weight) in preds {
        graph.add_edge(pred, contracted, weight);
    }
    for (succ, weight) in succs {
        graph.add_edge(contracted, succ, weight);
    }

    contracted
}
/// Contracts the nodes in `nodes` into a single node, maintaining all internal
/// and external edges. Node and edge weights can be changed by `node_map` and
/// `edge_map` before they are inserted into the graph given to `contract`.
Contracts the nodes in `nodes` into a single node, maintaining all internal
and external edges.
Contracts the nodes in ` nodes ` into a single node maintaining all internal and external edges .
pub fn contract_nodes_and_map<N, N2, E, E2, FN, FE, FC>(
    graph: &mut StableDiGraph<N, E>,
    nodes: &IxBitSet<NodeIndex>,
    mut node_map: FN,
    mut edge_map: FE,
    contract: FC,
) -> NodeIndex
where
    FN: FnMut(NodeIndex, N) -> N2,
    FE: FnMut(EdgeIndex, E) -> E2,
    FC: FnOnce(StableDiGraph<N2, E2>) -> N,
{
    debug_assert!(!nodes.is_empty());
    let mut preds = Vec::new();
    let mut succs = Vec::new();
    let mut internal_edges = Vec::new();
    // remove and store every edge incident to every node
    for n in nodes {
        {
            let mut neighbors = graph.neighbors_directed(n, Outgoing).detach();
            while let Some((edge, succ)) = neighbors.next(graph) {
                let weight = graph.remove_edge(edge).unwrap();
                if nodes.contains(succ) {
                    internal_edges.push((n, succ, edge_map(edge, weight)));
                } else {
                    succs.push((succ, weight));
                }
            }
        }
        {
            let mut neighbors = graph.neighbors_directed(n, Incoming).detach();
            while let Some((edge, pred)) = neighbors.next(graph) {
                let weight = graph.remove_edge(edge).unwrap();
                if nodes.contains(pred) {
                    internal_edges.push((pred, n, edge_map(edge, weight)));
                } else {
                    preds.push((pred, weight));
                }
            }
        }
    }
    let mut old_new_map = HashMap::with_capacity(nodes.len());
    let mut subgraph = StableDiGraph::with_capacity(nodes.len(), internal_edges.len());
    // move nodes
    for old_node in nodes {
        debug_assert!(graph.neighbors_undirected(old_node).next().is_none());
        let weight = graph.remove_node(old_node).unwrap();
        let new_node = subgraph.add_node(node_map(old_node, weight));
        old_new_map.insert(old_node, new_node);
    }
    // restore internal edges
    for (src, dst, weight) in internal_edges {
        subgraph.add_edge(old_new_map[&src], old_new_map[&dst], weight);
    }
    let contracted = graph.add_node(contract(subgraph));
    // restore external edges
    for (pred, weight) in preds {
        graph.add_edge(pred, contracted, weight);
    }
    for (succ, weight) in succs {
        graph.add_edge(contracted, succ, weight);
    }
    contracted
}
pub fn contract_nodes_and_map < N , N2 , E , E2 , FN , FE , FC > ( graph : & mut StableDiGraph < N , E > , nodes : & IxBitSet < NodeIndex > , mut node_map : FN , mut edge_map : FE , contract : FC , ) -> NodeIndex where FN : FnMut ( NodeIndex , N ) -> N2 , FE : FnMut ( EdgeIndex , E ) -> E2 , FC : FnOnce ( StableDiGraph < N2 , E2 > ) -> N , { debug_assert ! ( nodes is_empty ( ) ) ; let mut preds = Vec :: new ( ) ; let mut succs = Vec :: new ( ) ; let mut internal_edges = Vec :: new ( ) ; // remove and store every edge incident to every node for n in nodes { { let mut neighbors = graph . neighbors_directed ( n , Outgoing ) . detach ( ) ; while let Some ( ( edge , succ ) ) = neighbors . next ( graph ) { let weight = graph . remove_edge ( edge ) . unwrap ( ) ; if nodes . contains ( succ ) { internal_edges . push ( ( n , succ , edge_map ( edge , weight ) ) ) ; } else { succs . push ( ( succ , weight ) ) ; } } } { let mut neighbors = graph . neighbors_directed ( n , Incoming ) . detach ( ) ; while let Some ( ( edge , pred ) ) = neighbors . next ( graph ) { let weight = graph . remove_edge ( edge ) . unwrap ( ) ; if nodes . contains ( pred ) { internal_edges . push ( ( pred , n , edge_map ( edge , weight ) ) ) ; } else { preds . push ( ( pred , weight ) ) ; } } } } let mut old_new_map = HashMap :: with_capacity ( nodes . len ( ) ) ; let mut subgraph = StableDiGraph :: with_capacity ( nodes . len ( ) , internal_edges . len ( ) ) ; // move nodes for old_node in nodes { debug_assert ! ( graph neighbors_undirected ( old_node ) next ( ) is_none ( ) ) ; let weight = graph . remove_node ( old_node ) . unwrap ( ) ; let new_node = subgraph . add_node ( node_map ( old_node , weight ) ) ; old_new_map . insert ( old_node , new_node ) ; } // restore internal edges for ( src , dst , weight ) in internal_edges { subgraph . add_edge ( old_new_map [ & src ] , old_new_map [ & dst ] , weight ) ; } let contracted = graph . add_node ( contract ( subgraph ) ) ; // restore external edges for ( pred , weight ) in preds { graph . add_edge ( pred , contracted , weight ) ; } for ( succ , weight ) in succs { graph . add_edge ( contracted , succ , weight ) ; } contracted }
Contracts the nodes in `nodes` into a single node, maintaining all internal
and external edges.
Contracts the nodes in ` nodes ` into a single node maintaining all internal and external edges .
graph
&mut StableDiGraph<N, E>
nodes
&IxBitSet<NodeIndex>
node_map
FN
edge_map
FE
contract
FC
graph
&mut StableDiGraph<N, E>
nodes
&IxBitSet<NodeIndex>
node_map
FN
edge_map
FE
contract
FC