| Total Complexity | 13 |
| Total Lines | 59 |
| Duplicated Lines | 0 % |
| Changes | 1 | ||
| 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(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() == 0: |
||
| 60 | queue.enqueue(edge) |
||
| 61 | |||
| 62 | return queue.iterate() |
||
| 63 |