[][src]Module rs_graph::maxflow::pushrelabel

This module implements a push relabel algorithm for solving max flow problems.

This implementation uses the gap heuristic and the global relabelling heuristic.

Example

use rs_graph::traits::*;
use rs_graph::maxflow::pushrelabel;
use rs_graph::{EdgeVec, Net};
use rs_graph::string::{Data, from_ascii};

let Data { graph: g, weights: upper, nodes } = from_ascii::<Net>(r"
     a---2-->b
    @|\      ^\
   / | \     | 4
  5  |  \    |  \
 /   |   |   |   @
s    1   1   2    t
 \   |   |   |   @
  5  |    \  |  /
   \ |     \ | 5
    @v      @|/
     c---2-->d
    ").unwrap();

let s = nodes[&'s'];
let t = nodes[&'t'];
let v1 = nodes[&'a'];
let v2 = nodes[&'b'];
let v3 = nodes[&'c'];
let v4 = nodes[&'d'];

let (value, flow, mut mincut) = pushrelabel(&g, s, t, |e| upper[e.index()]);

assert_eq!(value, 5);
assert!(g.edges().all(|e| flow[e] >= 0 && flow[e] <= upper[e.index()]));
assert!(g.nodes().filter(|&u| u != s && u != t).all(|u| {
    g.outedges(u).map(|(e,_)| flow[e]).sum::<usize>() ==
    g.inedges(u).map(|(e,_)| flow[e]).sum::<usize>()
}));

mincut.sort_by_key(|u| u.index());
assert_eq!(mincut, vec![v1, s, v3]);
use rs_graph::traits::*;
use rs_graph::maxflow::pushrelabel;
use rs_graph::{EdgeVec, Net};
use rs_graph::string::{Data, from_ascii};

let Data { graph: g, weights: upper, nodes } = from_ascii::<Net>(r"
               ---8-->a---10---
              /       |        \
             /        1  --3--  |
            /         | /     \ |
           /          v@       \v
     ---->b-----9---->c----8--->d----
    /      \         @         @^    \
  18        ---6--  /         / |     33
  /               \/         /  |      \
 /                /\    -----   |       @
s           --5--- |   /        |        t
 \         /       |  /         |       @
  27      |  ----2-|--         /       /
   \      | /      |  /----8---       7
    \     |/       @  |              /
     ---->e----9-->f------6---->g----
           \          |    |   @
            \         |       /
             --5----->h---4---
    ").unwrap();

let s = nodes[&'s'];
let t = nodes[&'t'];

assert_eq!(g.num_edges(), 18);

let (value, flow, mut mincut) = pushrelabel(&g, s, t, |e| upper[e.index()]);
assert_eq!(value, 29);

let mincutval = g
    .edges()
    .filter(|&e| mincut.contains(&g.src(e)) && !mincut.contains(&g.snk(e)))
    .map(|e| upper[e.index()])
    .sum::<usize>();
assert_eq!(value, mincutval);

mincut.sort_by_key(|u| u.index());
assert_eq!(mincut, "bcsef".chars().map(|v| nodes[&v]).collect::<Vec<_>>());

assert!(g.edges().all(|e| flow[e] >= 0 && flow[e] <= upper[e.index()]));
assert!(g.nodes().filter(|&u| u != s && u != t).all(|u| {
    g.outedges(u).map(|(e,_)| flow[e]).sum::<usize>() ==
    g.inedges(u).map(|(e,_)| flow[e]).sum::<usize>()
}));

Structs

PushRelabel

The push-relabel algorithm.