1use std::sync::{Arc, atomic::AtomicI32};
2
3use crate::{
4 edge::{EdgeWithData, InputEdge},
5 graph::NodeID,
6};
7use bitvec::vec::BitVec;
8use log::debug;
9
10#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
11pub struct ResidualEdgeData {
12 pub capacity: i32,
13}
14
15impl ResidualEdgeData {
16 pub fn new(capacity: i32) -> ResidualEdgeData {
17 ResidualEdgeData { capacity }
18 }
19}
20
21pub trait MaxFlow {
22 fn run(&mut self);
23 fn run_with_upper_bound(&mut self, bound: Arc<AtomicI32>);
24 fn max_flow(&self) -> Result<i32, String>;
25 fn assignment(&self, source: NodeID) -> Result<BitVec, String>;
26 fn from_edge_list(
27 edges: Vec<InputEdge<ResidualEdgeData>>,
28 source: NodeID,
29 sink: NodeID,
30 ) -> Self;
31 fn from_generic_edge_list<E: EdgeWithData>(
32 input_edges: &[E],
33 source: NodeID,
34 target: NodeID,
35 function: impl Fn(&E) -> ResidualEdgeData,
36 ) -> Self
37 where
38 Self: Sized,
39 {
40 debug_assert!(!input_edges.is_empty());
41 debug!("instantiating max-flow solver");
42 let edge_list: Vec<InputEdge<ResidualEdgeData>> = input_edges
43 .iter()
44 .map(move |edge| InputEdge {
45 source: edge.source(),
46 target: edge.target(),
47 data: function(edge),
48 })
49 .collect();
50
51 debug!("created {} ff edges", edge_list.len());
52 Self::from_edge_list(edge_list, source, target)
53 }
54}