Total Complexity | 13 |
Total Lines | 59 |
Duplicated Lines | 0 % |
Changes | 2 | ||
Bugs | 0 | Features | 0 |
1 | from pyalgs.data_structures.commons.queue import Queue |
||
4 | class FordFulkersonMaxFlow(object): |
||
5 | edgeTo = None |
||
6 | marked = None |
||
7 | s = None |
||
8 | t = None |
||
9 | value = 0.0 |
||
10 | network = None |
||
11 | |||
12 | def __init__(self, network, s, t): |
||
13 | self.s = s |
||
14 | self.t = t |
||
15 | self.network = network |
||
16 | self.value = 0.0 |
||
17 | while self.has_augmenting_path(): |
||
18 | x = self.t |
||
19 | bottle = float('inf') |
||
20 | while x != self.s: |
||
21 | bottle = min(bottle, self.edgeTo[x].residual_capacity_to(x)) |
||
22 | x = self.edgeTo[x].other(x) |
||
23 | |||
24 | x = self.t |
||
25 | while x != self.s: |
||
26 | self.edgeTo[x].add_residual_flow_to(x, bottle) |
||
27 | x = self.edgeTo[x].other(x) |
||
28 | |||
29 | self.value += bottle |
||
30 | |||
31 | def has_augmenting_path(self): |
||
32 | vertex_count = self.network.vertex_count() |
||
33 | self.edgeTo = [None] * vertex_count |
||
34 | self.marked = [False] * vertex_count |
||
35 | |||
36 | queue = Queue.create() |
||
37 | |||
38 | queue.enqueue(self.s) |
||
39 | self.marked[self.s] = True |
||
40 | |||
41 | while not queue.is_empty(): |
||
42 | x = queue.dequeue() |
||
43 | for e in self.network.adj(x): |
||
44 | w = e.other(x) |
||
45 | if e.residual_capacity_to(w) > 0: |
||
46 | if not self.marked[w]: |
||
47 | self.marked[w] = True |
||
48 | self.edgeTo[w] = e |
||
49 | queue.enqueue(w) |
||
50 | |||
51 | return self.marked[self.t] |
||
52 | |||
53 | def max_flow_value(self): |
||
54 | return self.value |
||
55 | |||
56 | def min_cut(self): |
||
57 | queue = Queue.create() |
||
58 | for edge in self.network.edges(): |
||
59 | if edge.residual_capacity_to(edge.end()) == 0: |
||
60 | queue.enqueue(edge) |
||
61 | |||
62 | return queue.iterate() |
||
63 | |||
64 |