Skip to content

Stoer–Wagner algorithm for minimum cut#606

Open
gbagan wants to merge 3 commits intopetgraph:masterfrom
gbagan:master
Open

Stoer–Wagner algorithm for minimum cut#606
gbagan wants to merge 3 commits intopetgraph:masterfrom
gbagan:master

Conversation

@gbagan
Copy link
Contributor

@gbagan gbagan commented Jan 7, 2024

Hi,

I propose an implementation of Stoer–Wagner algorithm to solve the (global) minimum cut problem.
https://en.wikipedia.org/wiki/Stoer%E2%80%93Wagner_algorithm

The implementation runs in O(|V| |E| + |V|²*log(|V|).

I'm fairly new to Rust and Petgraph. So I would be happy to have some advice.

The algorithm requires modifying the graph (vertex merging). So, I works on a mutable copy of the graph with the type Graph.
There may be a more elegant way to do this.

Since I need a max version of MinScored, I created the struct MaxScored.

I have added tests, quickcheck tests and benchmarks.

@aalekhpatel07
Copy link
Contributor

aalekhpatel07 commented Jan 15, 2024

Thanks for this! Works like a charm. This definitely helped me with an Advent of Code problem, haha. Wondering if you'd be willing to make this PR to my fork?

Copy link
Member

@RaoulLuque RaoulLuque left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A rebase to the current version of Petgraph is probably necessary. In particular, to comply with no-std, HashMap from the standard library should/could be replaced with the one from HashBrown and similarly with BinaryHeap.

I would also like if the private helper functions had some brief docstrings like for example in https://github.com/petgraph/petgraph/blob/master/src/algo/ford_fulkerson.rs

/// non-negative.
/// Returns a tuple composed of a vector of `EdgeId` that represents the cut and the cut weight.
///
/// Computes in **O(|V| |E| + |V|²*log(|V|)))** time
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Computes in **O(|V| |E| + |V|²*log(|V|)))** time
/// Computes in **O(|V|³)** time

The running time should probably be O(|V| |E| + |V|³) = O(|V|³), since we don't use Fibonacci heaps, but a binary heap.

G::NodeId: Eq + Hash,
K: Measure + Copy,
{
let mut node_to_node = HashMap::new();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::HashMap should be replaced by the hashbrown equivalent to be no-std compliant.

K: Measure + Copy,
EdgeId: Copy,
{
let mut queue = BinaryHeap::new();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::BinaryHeap should be replaced by the alloc::collections::BinaryHeap equivalent.

@RaoulLuque
Copy link
Member

Hey, I wanted to check-in on whether you'd be willing to continue working on this PR, or whether I or someone else could possibly pick it up in the future :) ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-new-algorithm Category: A feature request for a new graph algorithm

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants