-- -- Created by IntelliJ IDEA. -- User: chen0 -- Date: 11/9/2017 -- Time: 8:35 AM -- To change this template use File | Settings | File Templates. -- local FordFulkerson = {} FordFulkerson.__index = FordFulkerson FordFulkerson.MAX_VALUE = 100000000000.0 function FordFulkerson.create() local s = {} setmetatable(s, FordFulkerson) s.value = 0 s.edgeTo = {} s.source = -1 s.target = -1 s.network = nil s.marked = {} return s end function FordFulkerson:run(network, s, t) self.value = 0 self.edgeTo = {} self.source = s self.target = t self.network = network self.marked = {} while self:hasPath() do local maxFlow = FordFulkerson.MAX_VALUE local x = self.target while x ~= self.source do local e = self.edgeTo[x] maxFlow = math.min(maxFlow, e:residualCapacityTo(x)) x = e:other(x) end local x = self.target while x ~= self.source do local e = self.edgeTo[x] e:addResidualFlowTo(x, maxFlow) x = e:other(x) end self.value = self.value + maxFlow end return self.value end function FordFulkerson:hasPath() self.edgeTo = {} self.marked = {} for i = 0,self.network:vertexCount()-1 do local v = self.network:vertexAt(i) self.marked[v] = false end local queue = require('luagraphs.data.queue').create() queue:enqueue(self.source) while queue:isEmpty() == false do local x = queue:dequeue() self.marked[x] = true if x == self.target then return true end local adj_x = self.network:adj(x) for i = 0,adj_x:size()-1 do local e = adj_x:get(i) local w = e:other(x) if self.marked[w] == false and e:residualCapacityTo(w) > 0 then self.edgeTo[w] = e queue:enqueue(w) end end end return false end function FordFulkerson:minCuts() local result = require('luagraphs.data.list').create() for i = 0,self.network:vertexCount()-1 do local v = self.network:vertexAt(i) local adj_v = self.network:adj(v) for i = 0,adj_v:size()-1 do local e = adj_v:get(i) if e.v == v and e:residualCapacityTo(e:other(v)) == 0 then result:add(e) end end end return result end return FordFulkerson