You should probably implement this first with a dense graph. That way, you can assume there's an edge in each direction between every pair of distinct vertices. You can represent functions on the edges as |V| x |V| matrices. In particular, declarations for capacity and flow are quite simple:
int[][] cap = new int[numverts][numverts];
int[][] flow = new int[numverts][numverts];
One useful trick is to represent a flow of k
units along edge vw
as a flow of a
from v
to w
and a flow of -a
from w
to v
. This way, you don't have to worry about whether each edge of your augmenting path is pushing more flow forward or less flow backward. If you do this, you can compute the residual capacity along vw
by simply cap[v][w] - flow[v][w]
.
With this representation, finding an augmenting path becomes a breadth-first search in a dense graph where there is an edge from v
to w
exactly when cap[v][w] > flow[v][w]
. This is fairly straightforwardly implemented.
Since you're using java, you should be mindful of its per-object overhead. The Edge structure you described contains not just two ints (or pointers) and two doubles, but also stuff like GC information, a klass pointer, and a monitor. This is a few dozen extra bytes, easily doubling or tripling the size of your object.
A better representation for static sparse graphs, when you get to making your code work with sparse graphs, is as follows:
int[] from = new int[numverts+1];
int[] to = new int[numedges];
Sort the edges by "from" vertex. The i
th entry of the from
array is the index of the first edge whose "from" vertex is the i
th vertex or later. There's one extra entry at the end and you should set it to numedges
; it comes in handy when you want to loop over all edges leaving a given vertex.
Since you're doing flow, you'll want to store backward edges as well, so have an
int[] rev = new int[numedges];
to store the edge index of the reverse of each edge. Now you can represent arbitrary functions, say cap
and flow
, on the edges like this:
int[] cap = new int[numedges];
int[] flow = new int[numedges];
So whether to store these attributes in the Edge
structure is moot because the Edge
structure has gone away.