2

I'd implement Edmond Karp algorithm, but seems it's not correct and I'm not getting correct flow, consider following graph and flow from 4 to 8:

enter image description here

enter image description here

Algorithm runs as follow:

First finds 4→1→8, Then finds 4→5→8 after that 4→1→6→8

And I think third path is wrong, because by using this path we can't use flow from 6→8 (because it used), and in fact we can't use flow from 4→5→6→8.

In fact if we choose 4→5→6→8, and then 4→1→3→7→8 and then 4→1→3→7→8 we can gain better flow(40).

I Implemented algorithm from wiki sample code. I think we can't use any valid path and in fact this greedy selection is wrong.

Am I wrong?

Code is as below (in c#, threshold is 0, and doesn't affect the algorithm):

   public decimal EdmondKarps(decimal[][] capacities/*Capacity matrix*/,
                    List<int>[] neighbors/*Neighbour lists*/,
                    int s /*source*/,
                    int t/*sink*/,
                    decimal threshold,
                    out decimal[][] flowMatrix
                    /*flowMatrix (A matrix giving a legal flowMatrix with the maximum value)*/
                    )
    {
        THRESHOLD = threshold;
        int n = capacities.Length;
        decimal flow = 0m; // (Initial flowMatrix is zero)
        flowMatrix = new decimal[n][]; //array(1..n, 1..n) (Residual capacity from u to v is capacities[u,v] - flowMatrix[u,v])
        for (int i = 0; i < n; i++)
        {
            flowMatrix[i] = new decimal[n];
        }

        while (true)
        {
            var path = new int[n];
            var pathCapacity = BreadthFirstSearch(capacities, neighbors, s, t, flowMatrix, out path);
            if (pathCapacity <= threshold)
                break;
            flow += pathCapacity;

            //(Backtrack search, and update flowMatrix)
            var v = t;
            while (v != s)
            {
                var u = path[v];
                flowMatrix[u][v] = flowMatrix[u][v] + pathCapacity;
                flowMatrix[v][u] = flowMatrix[v][u] - pathCapacity;
                v = u;
            }
        }
        return flow;
    }

    private decimal BreadthFirstSearch(decimal[][] capacities, List<int>[] neighbors, int s, int t, decimal[][] flowMatrix, out int[] path)
    {
        var n = capacities.Length;
        path = Enumerable.Range(0, n).Select(x => -1).ToArray();//array(1..n)
        path[s] = -2;
        var pathFlow = new decimal[n];
        pathFlow[s] = Decimal.MaxValue; // INFINT
        var Q = new Queue<int>(); // Q is exactly Queue :)
        Q.Enqueue(s);
        while (Q.Count > 0)
        {
            var u = Q.Dequeue();
            for (int i = 0; i < neighbors[u].Count; i++)
            {
                var v = neighbors[u][i];
                //(If there is available capacity, and v is not seen before in search)
                if (capacities[u][v] - flowMatrix[u][v] > THRESHOLD && path[v] == -1)
                {
                    // save path:
                    path[v] = u;
                    pathFlow[v] = Math.Min(pathFlow[u], capacities[u][v] - flowMatrix[u][v]);
                    if (v != t)
                        Q.Enqueue(v);
                    else
                        return pathFlow[t];
                }
            }
        }
        return 0;
    }
templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
Saeed Amiri
  • 22,252
  • 5
  • 45
  • 83
  • It's not important to be care about code, I think there is problem with algorithm, such that I can't understand it well and I missed something. – Saeed Amiri Feb 25 '12 at 16:00
  • So It's better to give a short pseudo-code of the algorithm you've implemented. – a-z Feb 25 '12 at 16:20

1 Answers1

2

The way to choose paths is not important.

You have to add edges of the path in reverse order with path capacity and reduce capacity of edges of the path by that value.

In fact this solution works:

while there is a path with positive capacity from source to sink{
    find any path with positive capacity from source to sink, named P with capacity C.
    add C to maximum_flow_value.
    reduce C from capacity of edges of P.
    add C to capacity of edges of reverse_P.
}

Finally the value of maximum-flow is sum of Cs in the loop.

If you want to see the flow in edges in the maximum-flow you made, you can retain the initial graph somewhere, the flow in edge e would be original_capacity_e - current_capacity_e.

a-z
  • 1,634
  • 4
  • 16
  • 35
  • Thank you very much, I implemented wiki article and I didn't attention that it's not updating residual network, Yes you are completely right, I was in wrong way, when I see it reduces/increases flow matrix, I didn't attention that it's not residual network. I think wiki sample code is wrong what do you think? – Saeed Amiri Feb 25 '12 at 17:45