Python Forum

Full Version: Algorithm with graph
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Detect a bottleneck of a graph, i.e., Min-Cut, using the Max-flow algorithm. In other words, the algorithm should find a set of edges F ⊆ E such that there is minimum cut (S, T) such that the edges in F cross the cut. (In the direction S → T). The program takes as an input a network presented as a weighted graph G =(V, E, w) where w is interpreted as the capacities. The source s is the vertex that has the smallest number of any vertex that has outgoing edges. Usually this is 1, but it could be 0. The vertex with the largest number with incoming edges is considered t. I.e., the input doesn’t separately specify the source and the sink. Edges should be pairs of vertices (direction matters) given in a list or set but Order of vertices does not matter. implement a class FlowNetwork(G),whose constructor takes in the graph and which implements the method MinCut(),that returns the list of edges that is required.

How can i solve this using Python code? Is the code correct? What modification is needed?

My code:
from collections import defaultdict

class FlowNetwork:
    def __init__(self, graph):
        self.graph = graph
        self.residual_graph = defaultdict(dict)

        for u, neighbors in graph.items():
            for v, capacity in neighbors.items():
                self.residual_graph[u][v] = capacity
                self.residual_graph[v][u] = 0  # Add reverse edge with 0 capacity

    def find_min_cut(self, source, sink):
        visited = set()
        stack = [source]
        visited.add(source)

        # DFS to find reachable nodes from the source in the residual graph
        while stack:
            current_node = stack.pop()
            for neighbor, capacity in self.residual_graph[current_node].items():
                if neighbor not in visited and capacity > 0:
                    stack.append(neighbor)
                    visited.add(neighbor)

        min_cut_edges = []
        for u, neighbors in self.graph.items():
            for v, capacity in neighbors.items():
                if u in visited and v not in visited:
                    min_cut_edges.append((u, v))

        return min_cut_edges

    def ford_fulkerson(self, source, sink):
        max_flow = 0
        path = self.bfs(source, sink)

        while path:
            # Find the minimum capacity in the augmenting path
            min_capacity = float('inf')
            for u, v in path:
                min_capacity = min(min_capacity, self.residual_graph[u][v])

            # Update the residual graph
            for u, v in path:
                self.residual_graph[u][v] -= min_capacity
                self.residual_graph[v][u] += min_capacity

            max_flow += min_capacity
            path = self.bfs(source, sink)

        return max_flow

    def bfs(self, source, sink):
        queue = [(source, [source])]

        while queue:
            current_node, path = queue.pop(0)

            for neighbor, capacity in self.residual_graph[current_node].items():
                if capacity > 0 and neighbor not in path:
                    if neighbor == sink:
                        return list(zip(path, path[1:] + [neighbor]))
                    queue.append((neighbor, path + [neighbor]))

        return None

    def MinCut(self):
        source = min(self.graph, key=int)
        sink = max(self.graph, key=int)

        max_flow = self.ford_fulkerson(source, sink)

        # Find the minimum cut using the residual graph
        min_cut_edges = self.find_min_cut(source, sink)

        return min_cut_edges


# Example usage:
graph = {
    '0': {'1': 3, '2': 4},
    '1': {'2': 2, '3': 2},
    '2': {'3': 5},
    '3': {}
}

flow_network = FlowNetwork(graph)
min_cut_edges = flow_network.MinCut()

print("Minimum cut edges:", min_cut_edges)
Quote:How can i solve this using Python code? Is the code correct? What modification is needed?
Do you have a specific question? Are you getting an error? Does MinCut return an incorrect result?
(Jan-29-2024, 05:10 PM)deanhystad Wrote: [ -> ]
Quote:How can i solve this using Python code? Is the code correct? What modification is needed?
Do you have a specific question? Are you getting an error? Does MinCut return an incorrect result?

Yes, it is giving incorrect result. Also, the code needs to be efficient so I need a review if it answers the question and if its efficient/
What are the expected result given your example usage?
(Jan-29-2024, 07:50 PM)deanhystad Wrote: [ -> ]What are the expected result given your example usage?

Minimum cut edges: [('1', '2'), ('2', '3')]