diff --git a/src/algorithms/dinic.rs b/src/algorithms/dinic.rs index 8594c15..8643264 100644 --- a/src/algorithms/dinic.rs +++ b/src/algorithms/dinic.rs @@ -1,4 +1,3 @@ -// Dinic use std::cmp::min; use std::collections::VecDeque; diff --git a/src/algorithms/edmonds_karp.rs b/src/algorithms/edmonds_karp.rs index 59d8d8c..c75a49c 100644 --- a/src/algorithms/edmonds_karp.rs +++ b/src/algorithms/edmonds_karp.rs @@ -1,11 +1,10 @@ -// Edmonds-Karp (also Ford-Fulkerson mit BFS statt DFS), use std::cmp::min; use std::collections::VecDeque; use petgraph::{stable_graph::{NodeIndex, StableGraph, EdgeReference}, visit::{EdgeRef, VisitMap, Visitable}, Direction}; -fn available_capacity(edge: EdgeReference<'_, (u64, u64)>) -> u64 { - edge.weight().1 - edge.weight().0 +fn available_capacity(edge: (u64, u64)) -> u64 { + edge.1 - edge.0 } // Runs a depth Breadth First Search (BFS) and returns an augmenting path from source to destination if possible @@ -21,7 +20,7 @@ fn bfs(graph: &StableGraph<(f32, f32), (u64, u64)>, source: NodeIndex, destinati for edge in outgoing_edges { let neighbor = edge.target(); - if !visited.is_visited(&neighbor) && available_capacity(edge) > 0 { + if !visited.is_visited(&neighbor) && available_capacity(*edge.weight()) > 0 { visited.visit(neighbor); let mut new_path = path.clone(); new_path.push(neighbor); diff --git a/src/algorithms/ford_fulkerson.rs b/src/algorithms/ford_fulkerson.rs index 4ab8b88..966d8ac 100644 --- a/src/algorithms/ford_fulkerson.rs +++ b/src/algorithms/ford_fulkerson.rs @@ -1,20 +1,14 @@ -// Ford-Fulkerson mit DFS zur Berechnung des flusserhöhenden Pfades, -// Edmonds-Karp (also Ford-Fulkerson mit BFS statt DFS), -// Dinic -// Goldberg-Tarjan (auch Preflow-Push oder Push-Relabel genannt). use std::cmp::min; use std::collections::VecDeque; use petgraph::{stable_graph::{EdgeReference, NodeIndex, StableGraph}, visit::{EdgeRef, VisitMap, Visitable}, Direction}; -//use crate::random_generator::MaxflowProblem; -//mod random_generator; -fn available_capacity(edge: EdgeReference<'_, (u64, u64)>) -> u64 { - edge.weight().1 - edge.weight().0 +fn available_capacity(edge: (u64, u64)) -> u64 { + edge.1 - edge.0 } -// Runs a depth Depth First Search (DFS) and returns an augmenting path from source to destination if possible +// Runs a depth Depth First Search (DFS) which returns an augmenting path from source to destination if possible fn dfs(graph: &StableGraph<(f32, f32), (u64, u64)>, source: NodeIndex, destination: NodeIndex) -> Option> { let mut visited = graph.visit_map(); let mut stack = VecDeque::from([(source, vec![source])]); @@ -24,10 +18,10 @@ fn dfs(graph: &StableGraph<(f32, f32), (u64, u64)>, source: NodeIndex, destinati let outgoing_edges = graph.edges_directed(node, Direction::Outgoing); visited.visit(node); - // iterate over all outgoing edges + // iterate over all outgoing edges & add neighboring nodes to the stack for edge in outgoing_edges { let neighbor = edge.target(); - if !visited.is_visited(&neighbor) && available_capacity(edge) > 0 { + if !visited.is_visited(&neighbor) && available_capacity(*edge.weight()) > 0 { visited.visit(neighbor); let mut new_path = path.clone(); new_path.push(neighbor); @@ -67,52 +61,3 @@ pub fn ford_fulkerson(mut graph: StableGraph<(f32, f32), (u64, u64)>, source: No // return graph with augmented flows graph } - -//pub struct FordFulkerson { -// problem: MaxflowProblem, -// flows: Graph<(), u64, Directed, u32, DefaultNodeShape, DefaultEdgeShape>, - // alertnatively, use a map from EdgeIndex to flow value - //dfs: Dfs, -//} - -/* impl FordFulkerson { - fn new(problem: MaxflowProblem) -> S/elf { - Self { problem: problem, flows: Graph::new(StableGraph::default()) } - } - - fn graph(&mut self) -> &Graph { - &self.problem.g - } - - fn flows(&mut self) -> &Graph<(), u64> { - &self.flows - } - - fn dfs(&mut self, ni: NodeIndex) -> Vec>{ - // set own node to visited - self.problem.g.node_mut(ni).expect("node index not found").set_visited(true); - //self.graph().node_mut(ni).expect("node index not found").set_visited(true); - - let augmenting_paths: Vec> = Vec::new(); - let neighboring_edges = self.graph().edges_directed(ni, Direction::Outgoing); - - for edge in neighboring_edges { - //let neighbor = self.problem.g.node_mut(edge.target()).expect("node index not found"); - //if neighbor.visited() == false { - // println!("{:?}", edge.weight()); - //} - } - // iterate over all unvisited! neighbors. for each: - // - check if there is capacity left - // - if neighbor = target, return path - // - else, do dfs starting from neighbor - // - if neighbor returns augmenting path add it to own list & prepend own edge - // return list of augmenting paths - augmenting_paths - } - - fn step(&self) { - //self.dfs(self.problem.s); - } - -} */ diff --git a/src/graph.rs b/src/graph.rs index e314be9..9b3204e 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -1,5 +1,5 @@ use egui_graphs::{DefaultNodeShape, Graph, default_edge_transform, default_node_transform, to_graph_custom}; -use petgraph::{stable_graph::{StableGraph, NodeIndex}, Directed}; +use petgraph::{stable_graph::{NodeIndex, StableGraph}, visit::{VisitMap, Visitable}, Directed}; use egui::Pos2; use crate::layout::CustomEdgeShape; use egui::Color32; @@ -19,9 +19,10 @@ impl ResidualGraph for StableGraph<(f32, f32), (u64, u64)> { let (reverse_flow, reverse_capacity) = *res_graph.edge_weight(reverse_edge).expect("reverse edge not found"); // update the forward edge // TODO: this seems to overflow in certain cases - res_graph.update_edge(source, target, (flow, capacity + reverse_flow - flow)); + + res_graph.update_edge(source, target, (flow, capacity + reverse_flow)); // update the reverse edge - res_graph.update_edge(target, source, (reverse_flow, reverse_capacity + flow - reverse_flow)); + //res_graph.update_edge(target, source, (reverse_flow, reverse_capacity + flow)); } else { // add a residual edge with a flow of 0 if the reverse edge doesn't exist res_graph.add_edge(target, source, (0, 0));