Пример #1
0
        public void TestBigGraph()
        {
            IWeightedGraph <int, double> graph = LoadGraphFromFile("./graphs/weighted/G_1_2.txt");
            IVertex <int> source = graph.GetFirstMatchingVertex(v => v.Value == 0);
            IVertex <int> target = graph.GetFirstMatchingVertex(v => v.Value == 7);
            IWeightedGraph <int, double> maxFlow = EdmondsKarp.FindMaxFlow(graph, source, target, CombineFlowValues, SubstractFlowValues, 0.0);
            double maxFlowValue = GetMaxFlowValue(maxFlow, source.Value);

            AssertDoublesNearlyEqual(0.735802, maxFlowValue, 0.000001);
        }
Пример #2
0
        public void TestSmallGraph()
        {
            IWeightedGraph <int, double> graph = LoadGraphFromFile("./graphs/max_flow/Fluss2.txt");
            IVertex <int> source = graph.GetFirstMatchingVertex(v => v.Value == 0);
            IVertex <int> target = graph.GetFirstMatchingVertex(v => v.Value == 7);
            IWeightedGraph <int, double> maxFlow = EdmondsKarp.FindMaxFlow(graph, source, target, CombineFlowValues, SubstractFlowValues, 0.0);
            double maxFlowValue = GetMaxFlowValue(maxFlow, source.Value);

            Assert.AreEqual(5, maxFlowValue);
        }
        static void Main(string[] args)
        {
            Console.Write("Enter the number of test cases to run: ");
            int test = int.Parse(Console.ReadLine());

            Console.WriteLine("* * * * * * * * * * * * Dinic * * * * * * * * * * * *");
            TestDinic.Test(test);
            Console.WriteLine("* * * * * * * * * * Edmonds Karp * * * * * * * * * *");
            EdmondsKarp.Test(test);
            Console.WriteLine("* * * * * * * * *  Ford Fulkerson  * * * * * * * * *");
            FordFloukerson.Test(test);
        }
    public void FindMaxFlow_WithCrossGraph()
    {
        var graph = new int[][]
        {
            new int[] { 0, 1000, 1000, 0 },
            new int[] { 0, 0, 1, 1000 },
            new int[] { 0, 0, 0, 1000 },
            new int[] { 0, 0, 0, 0 },
        };
        var expected = 2000;
        var maxFlow  = EdmondsKarp.FindMaxFlow(graph);

        Assert.AreEqual(expected, maxFlow, $"Expected {expected}, but was {maxFlow}.");
    }
    static void Main(string[] args)
    {
        var graph = new int[][]
        {
            new int[] { 0, 10, 10, 0, 0, 0 },
            new int[] { 0, 0, 2, 4, 8, 0 },
            new int[] { 0, 0, 0, 0, 9, 0 },
            new int[] { 0, 0, 0, 0, 0, 10 },
            new int[] { 0, 0, 0, 6, 0, 10 },
            new int[] { 0, 0, 0, 0, 0, 0 },
        };

        var maxFlow = EdmondsKarp.FindMaxFlow(graph);

        Console.WriteLine($"Max flow = {maxFlow}");
    }
    public void FindMaxFlow_WithSmallGraph()
    {
        var graph = new int[][]
        {
            new int[] { 0, 10, 10, 0, 0, 0 },
            new int[] { 0, 0, 2, 4, 8, 0 },
            new int[] { 0, 0, 0, 0, 9, 0 },
            new int[] { 0, 0, 0, 0, 0, 10 },
            new int[] { 0, 0, 0, 6, 0, 10 },
            new int[] { 0, 0, 0, 0, 0, 0 },
        };

        var expected = 19;
        var maxFlow  = EdmondsKarp.FindMaxFlow(graph);

        Assert.AreEqual(expected, maxFlow, $"Expected {expected}, but was {maxFlow}.");
    }
Пример #7
0
        public void ComputeMaximalMatching(WeightedDiAdjacencyMatrix graph)
        {
            List <int> redVerticles  = null;
            List <int> blueVerticles = null;

            if (!IsGraphBipartite(graph, out redVerticles, out blueVerticles))
            {
                Console.WriteLine("Graph is not Bipartite!");
                return;
            }

            WeightedDiAdjacencyMatrix diGraph = new WeightedDiAdjacencyMatrix(graph.Order + 2);

            int S = 1;
            int T = graph.Order + 2;

            for (int i = 1; i <= graph.Order; i++)
            {
                var neighbours = graph.Neighbours(i);
                foreach (var item in neighbours)
                {
                    if (blueVerticles.Contains(i))
                    {
                        diGraph.AddEdge(i + 1, item + 1, 1f);
                    }
                }
            }

            blueVerticles.ForEach(blue => diGraph.AddEdge(S, blue + 1, 1f));
            redVerticles.ForEach(red => diGraph.AddEdge(red + 1, T, 1f));

            Console.WriteLine("Residual network S=0; T=" + (T - 1));
            for (int i = 0; i < diGraph.Order; i++)
            {
                Console.Write("Neighbours[" + (i) + "]\t");
                diGraph.Neighbours(i + 1).ForEach(_ => Console.Write((_ - 1) + " "));
                Console.WriteLine();
            }

            Console.WriteLine("To read result remove S-> and ->T. Then substract 1 from each middle N->N:");
            var edmondsKarp = new EdmondsKarp();

            edmondsKarp.MaximumFlow(diGraph, S - 1, T - 1);
        }
Пример #8
0
        static void Main(string[] args)
        {
            CapacityGraph g = new CapacityGraph(new int[, ]
            {
                { 0, 7, 1 },
                { 7, 0, 3 },
                { 1, 3, 0 }
            });

            g.setSourceNode(0);
            g.setSinkNode(2);

            int maxFlow = EdmondsKarp.FindMaxFlow(g.getCapacityMatrix(), g.getNeighbors(), g.getSourceNode(), g.getSinkNode());

            Console.WriteLine($"Max flow = {maxFlow}");

            Console.WriteLine("\n\nPress any key to continue...\n\n");
            Console.ReadKey();
        }
    public void FindMaxFlow_WithMediumGraphWithBackwardsEdges()
    {
        var graph = new int[][]
        {
            new int[] { 0, 0, 3, 5, 17, 0, 5, 0 },
            new int[] { 0, 0, 2, 13, 0, 0, 7, 0 },
            new int[] { 0, 6, 0, 9, 3, 13, 0, 0 },
            new int[] { 0, 0, 3, 0, 17, 10, 5, 0 },
            new int[] { 0, 15, 0, 8, 0, 6, 6, 9 },
            new int[] { 0, 0, 22, 0, 3, 0, 7, 10 },
            new int[] { 0, 5, 0, 9, 4, 13, 0, 5 },
            new int[] { 0, 0, 0, 0, 0, 0, 0, 0 },
        };

        var expected = 24;
        var maxFlow  = EdmondsKarp.FindMaxFlow(graph);

        Assert.AreEqual(expected, maxFlow, $"Expected {expected}, but was {maxFlow}.");
    }
    public void FindMaxFlow_WithMediumGraph()
    {
        var graph = new int[][]
        {
            new int[] { 0, 6, 15, 5, 0, 0, 0, 0 },
            new int[] { 0, 0, 7, 0, 8, 0, 0, 3 },
            new int[] { 0, 0, 0, 9, 9, 13, 0, 0 },
            new int[] { 0, 0, 0, 3, 17, 10, 5, 0 },
            new int[] { 0, 0, 0, 0, 0, 0, 11, 8 },
            new int[] { 0, 0, 0, 0, 0, 0, 7, 12 },
            new int[] { 0, 0, 0, 0, 0, 0, 0, 14 },
            new int[] { 0, 0, 0, 0, 0, 0, 0, 0 },
        };

        var expected = 26;
        var maxFlow  = EdmondsKarp.FindMaxFlow(graph);

        Assert.AreEqual(expected, maxFlow, $"Expected {expected}, but was {maxFlow}.");
    }
Пример #11
0
        public static IWeightedGraph <TV, TW> BuildResidualGraph <TV, TW>(IWeightedGraph <TV, TW> graph,
                                                                          Func <TW, TW, TW> substractValues,
                                                                          Func <TW, TW> negateValue,
                                                                          TW zeroValue)
            where TV : IEquatable <TV> where TW : IComparable
        {
            // Build residual graph as done in Edmonds-Karp
            IWeightedGraph <TV, TW> residualGraph = EdmondsKarp.BuildResidualGraph(graph, substractValues, zeroValue);

            // Add costs
            foreach (IWeightedEdge <TV, TW> edge in graph.GetAllEdges())
            {
                if (edge is IWeightedDirectedEdge <TV, TW> directedEdge)
                {
                    TW costs = edge.GetAttribute <TW>(Constants.COSTS);

                    // Add costs to forward edges
                    if (residualGraph.AreVertecesConnected(directedEdge.OriginVertex.Value, directedEdge.TargetVertex.Value))
                    {
                        residualGraph.GetEdgeBetweenVerteces(directedEdge.OriginVertex.Value, directedEdge.TargetVertex.Value)
                        .SetAttribute(Constants.COSTS, costs);
                    }

                    // Add negative costs to backward edges
                    if (residualGraph.AreVertecesConnected(directedEdge.TargetVertex.Value, directedEdge.OriginVertex.Value))
                    {
                        residualGraph.GetEdgeBetweenVerteces(directedEdge.TargetVertex.Value, directedEdge.OriginVertex.Value)
                        .SetAttribute(Constants.COSTS, negateValue(costs));
                    }
                }
                else
                {
                    throw new GraphNotDirectedException();
                }
            }

            // Done - return residual graph
            return(residualGraph);
        }
    public void FindMaxFlow_WithLargeGraph()
    {
        var graph = new int[][]
        {
            new int[] { 0, 0, 0, 0, 0, 0, 30, 0, 22, 0, 0, 0 },             // 0
            new int[] { 0, 0, 0, 0, 20, 0, 0, 26, 0, 25, 0, 6 },            // 1
            new int[] { 0, 0, 0, 0, 0, 0, 0, 15, 14, 0, 0, 9 },             // 2
            new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0 },               // 3
            new int[] { 0, 20, 0, 0, 0, 5, 17, 0, 0, 0, 0, 11 },            // 4
            new int[] { 0, 0, 0, 0, 5, 0, 6, 0, 3, 0, 0, 33 },              // 5
            new int[] { 30, 0, 0, 0, 17, 6, 0, 0, 0, 0, 0, 0 },             // 6
            new int[] { 0, 26, 15, 0, 0, 0, 0, 0, 0, 23, 0, 20 },           // 7
            new int[] { 22, 0, 14, 0, 0, 3, 0, 0, 0, 0, 0, 0 },             // 8
            new int[] { 0, 25, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0 },             // 9
            new int[] { 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0 },               // 10
            new int[] { 0, 6, 9, 0, 11, 33, 0, 20, 0, 0, 0, 0 },            // 11
        };

        var expected = 40;
        var maxFlow  = EdmondsKarp.FindMaxFlow(graph);

        Assert.AreEqual(expected, maxFlow, $"Expected {expected}, but was {maxFlow}.");
    }
    public void FindMaxFlow_WithLargeGraphWithBackwardsEdges()
    {
        var graph = new int[][]
        {
            new int[] { 0, 13, 55, 8, 0, 13, 0, 0, 15, 0, 5, 0, 0 },
            new int[] { 0, 0, 155, 13, 21, 0, 0, 0, 14, 0, 35, 0, 0 },
            new int[] { 0, 3, 0, 44, 0, 15, 0, 0, 47, 0, 56, 0, 14 },
            new int[] { 0, 77, 0, 0, 0, 71, 28, 90, 99, 5, 0, 76, 0 },
            new int[] { 0, 0, 15, 7, 0, 64, 3, 0, 15, 0, 65, 0, 43 },
            new int[] { 0, 23, 0, 5, 17, 0, 5, 0, 51, 3, 86, 0, 0 },
            new int[] { 0, 33, 33, 0, 0, 7, 0, 13, 0, 6, 17, 8, 34 },
            new int[] { 0, 0, 0, 0, 0, 0, 5, 0, 5, 5, 5, 5, 5 },
            new int[] { 0, 5, 0, 0, 27, 13, 34, 0, 21, 57, 42, 0, 71 },
            new int[] { 0, 287, 15, 31, 49, 0, 70, 0, 13, 0, 99, 13, 0 },
            new int[] { 0, 0, 44, 1, 17, 0, 5, 0, 15, 0, 0, 29, 0 },
            new int[] { 0, 44, 4, 13, 19, 14, 0, 0, 34, 0, 12, 0, 0 },
            new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        };

        var expected = 109;
        var maxFlow  = EdmondsKarp.FindMaxFlow(graph);

        Assert.AreEqual(expected, maxFlow, $"Expected {expected}, but was {maxFlow}.");
    }
Пример #14
0
        public static IEnumerable <IEdge <TV> > FindMaxMatching <TV>(IGraph <TV> graph,
                                                                     ISet <IVertex <TV> > set1,
                                                                     ISet <IVertex <TV> > set2,
                                                                     TV superSourceValue,
                                                                     TV superTargetValue) where TV : IEquatable <TV>
        {
            // Build directed graph with super nodes and capacity 1
            IWeightedGraph <TV, int> graphWithSuperNodes = BuildGraphWithSuperNodesAndCapacity(graph, superSourceValue, superTargetValue, set1, set2, 1);
            IVertex <TV>             sourceNode          = graphWithSuperNodes.GetFirstMatchingVertex(v => v.Value.Equals(superSourceValue));
            IVertex <TV>             targetNode          = graphWithSuperNodes.GetFirstMatchingVertex(v => v.Value.Equals(superTargetValue));

            // Compute max flow in graph with super nodes
            IWeightedGraph <TV, int> maxFlow = EdmondsKarp.FindMaxFlow(graphWithSuperNodes,
                                                                       sourceNode,
                                                                       targetNode,
                                                                       (x, y) => x + y,
                                                                       (x, y) => x - y,
                                                                       0);

            // Add edges with flow to matching
            List <IEdge <TV> > matchings = new List <IEdge <TV> >();

            foreach (IVertex <TV> vertex in set1)
            {
                foreach (IEdge <TV> edge in graph.GetEdgesOfVertex(vertex))
                {
                    if (maxFlow.GetEdgeBetweenVerteces(vertex.Value, edge.ConnectedVertex(vertex).Value).Weight == 1)
                    {
                        matchings.Add(edge);
                    }
                }
            }

            // Done - return matching!
            return(matchings);
        }
        public static void Main(string[] args)
        {
            Data data = DataProvider.Instance.ReadData("DateProblema.txt");

            Retea retea = new Retea();

            int nrNoduri = data.NrAsociatii + data.NrLocuitori + data.NrPartidePolitice + 2;

            Nod nodSursa = new Nod {
                Id           = 1,
                EsteNodSursa = true,
                EsteNodStoc  = false,
            };

            Nod nodStoc = new Nod {
                Id           = nrNoduri,
                EsteNodSursa = false,
                EsteNodStoc  = true,
            };

            retea.Noduri.Add(nodSursa);
            int idNodCurent = nodSursa.Id;

            data.Asociatii.ForEach(asociatie => {
                Nod nodAsociatie = retea.Noduri.FirstOrDefault(n => n.IdAsociatie == asociatie.Id);

                if (nodAsociatie == null)
                {
                    idNodCurent++;
                    nodAsociatie = new Nod {
                        Id = idNodCurent, IdAsociatie = asociatie.Id
                    };
                    retea.Noduri.Add(nodAsociatie);
                }

                Arc arc = new Arc(nodSursa, nodAsociatie, flux: 0, capacitate: 1);
                retea.Arce.Add(arc);
            });

            data.Locuitori.ForEach(locuitor => {
                Nod nodLocuitor = retea.Noduri.FirstOrDefault(n => n.IdLocuitor == locuitor.Id);

                if (nodLocuitor == null)
                {
                    idNodCurent++;
                    nodLocuitor = new Nod {
                        Id = idNodCurent, IdLocuitor = locuitor.Id
                    };
                    retea.Noduri.Add(nodLocuitor);
                }

                List <Asociatie> asociatii = data.Asociatii.Where(asociatie => asociatie.Membrii.Contains(locuitor)).ToList();

                asociatii.ForEach(asociatie => {
                    Nod nodAsociatie = retea.Noduri.FirstOrDefault(n => n.IdAsociatie == asociatie.Id);

                    if (nodAsociatie == null)
                    {
                        throw new InvalidOperationException($"Nu a fost creat nod pentru asociatia cu id-ul {asociatie.Id}.");
                    }

                    Arc arc = new Arc(nodAsociatie, nodLocuitor, 0, 1);
                    retea.Arce.Add(arc);
                });
            });

            List <Arc> arcePartide = new List <Arc>();

            data.PartidePolitice.ForEach(partid => {
                Nod nodPartid = retea.Noduri.FirstOrDefault(n => n.IdPartid == partid.Id);
                if (nodPartid == null)
                {
                    idNodCurent++;
                    nodPartid = new Nod {
                        Id = idNodCurent, IdPartid = partid.Id
                    };
                    retea.Noduri.Add(nodPartid);
                }

                partid.Membrii.ForEach(locuitor => {
                    Nod nodLocuitor = retea.Noduri.FirstOrDefault(n => n.IdLocuitor == locuitor.Id);

                    if (nodLocuitor == null)
                    {
                        throw new InvalidOperationException($"Nu a fost creat nod pentru locuitorul cu id-ul {locuitor.Id}.");
                    }

                    retea.Arce.Add(new Arc(nodLocuitor, nodPartid, 0, 1));
                });

                Arc arc = new Arc(nodPartid, nodStoc, flux: 0, capacitate: partid.NrReprezentantiInConsiliu);

                arcePartide.Add(arc);
            });

            retea.Arce.AddRange(arcePartide);

            data.Locuitori.ForEach(locuitor => {
                IEnumerable <PartidPolitic> partide = data.PartidePolitice.Where(p => p.Membrii.Contains(locuitor));

                if (partide?.Count() == 0)
                {
                    Nod nodLocuitor = retea.Noduri.FirstOrDefault(n => n.IdLocuitor == locuitor.Id);

                    if (nodLocuitor == null)
                    {
                        throw new InvalidOperationException($"Nu a fost creat nod pentru locuitorul cu id-ul {locuitor.Id}.");
                    }

                    retea.Arce.Add(new Arc(nodLocuitor, nodStoc, 0, 1));
                }
            });

            retea.Noduri.Add(nodStoc);

            EdmondsKarp edmondsKarp = new EdmondsKarp();
            AhujaOrlin  ahujaOrlin  = new AhujaOrlin();
            PrefluxFIFO prefluxFIFO = new PrefluxFIFO();

            double maxValue = -1;
            string option   = string.Empty;

            while (true)
            {
                Console.WriteLine("Selectati algoritmul: ");
                Console.WriteLine("1. Edmonds Karp");
                Console.WriteLine("2. Preflux FIFO");
                Console.WriteLine("3. Iesire program");

                string input = Console.ReadLine();

                switch (input.Trim())
                {
                case "1":
                    maxValue = edmondsKarp.GetValoareMaxima(new Retea(retea));
                    break;

                case "2":
                    maxValue = prefluxFIFO.GetValoareMaxima(new Retea(retea));
                    break;

                case "3":
                default:
                    return;
                }

                Console.WriteLine($"Valoarea maxima: {maxValue}");
                Console.WriteLine($"Consiliul orasului {((maxValue == data.NrAsociatii) ? "" : "NU ")}este echilibrat!");
                Console.ReadKey();
            }
        }
Пример #16
0
        public static IWeightedGraph <TV, TW> FindCostMinimalFlow <TV, TW>(IWeightedGraph <TV, TW> graph,
                                                                           TV superSourceValue,
                                                                           TV superTargetValue,
                                                                           Func <TW, TW, TW> combineValues,
                                                                           Func <TW, TW, TW> substractValues,
                                                                           Func <TW, TW> negateValue,
                                                                           TW zeroValue,
                                                                           TW maxValue)
            where TV : IEquatable <TV> where TW : IComparable
        {
            // Build graph with super nodes
            IWeightedGraph <TV, TW> graphWithSuperNodes = BuildGraphWithSuperNodes(graph, superSourceValue, superTargetValue, negateValue);

            // Get max flow in graph with super nodes
            IWeightedGraph <TV, TW> maxFlow = EdmondsKarp.FindMaxFlow(graphWithSuperNodes,
                                                                      graphWithSuperNodes.GetFirstMatchingVertex(v => v.Value.Equals(superSourceValue)),
                                                                      graphWithSuperNodes.GetFirstMatchingVertex(v => v.Value.Equals(superTargetValue)),
                                                                      combineValues,
                                                                      substractValues,
                                                                      zeroValue);
            TW maxFlowValue = FlowValue(maxFlow, superSourceValue, combineValues, zeroValue);

            // Check for existance of a b-flow
            IEnumerable <IVertex <TV> > sources = graph.GetAllMatchingVerteces(v => v.GetAttribute <double>(Constants.BALANCE) > 0);
            IEnumerable <IVertex <TV> > targets = graph.GetAllMatchingVerteces(v => v.GetAttribute <double>(Constants.BALANCE) < 0);
            TW sourcesBalance = zeroValue;
            TW targetsBalance = zeroValue;

            foreach (IVertex <TV> source in sources)
            {
                sourcesBalance = combineValues(sourcesBalance, source.GetAttribute <TW>(Constants.BALANCE));
            }
            foreach (IVertex <TV> target in targets)
            {
                targetsBalance = combineValues(targetsBalance, target.GetAttribute <TW>(Constants.BALANCE));
            }
            if (maxFlowValue.Equals(sourcesBalance) &&
                maxFlowValue.Equals(negateValue(targetsBalance)))
            {
                // Copy flow values from graph with super nodes to original graph
                foreach (IWeightedEdge <TV, TW> edge in graphWithSuperNodes.GetAllEdges())
                {
                    if (edge is IWeightedDirectedEdge <TV, TW> directedEdge)
                    {
                        if (!directedEdge.OriginVertex.Value.Equals(superSourceValue) &&
                            !directedEdge.TargetVertex.Value.Equals(superTargetValue))
                        {
                            graph.GetEdgeBetweenVerteces(directedEdge.OriginVertex.Value, directedEdge.TargetVertex.Value)
                            .SetAttribute(Constants.FLOW, edge.GetAttribute <TW>(Constants.FLOW));
                        }
                    }
                    else
                    {
                        throw new GraphNotDirectedException();
                    }
                }

                bool modifyingCycleLeft;
                do
                {
                    // Build residual graph
                    IWeightedGraph <TV, TW> residualGraph = BuildResidualGraph(graph, substractValues, negateValue, zeroValue);

                    // Prepare graph for BellmanFordMoore
                    IWeightedGraph <TV, TW> bfmGraph = BuildGraphForBellmanFordMoore(residualGraph, superSourceValue, zeroValue);

                    // Attempt to find modifying cycle
                    IVertex <TV> bfmSuperSource = bfmGraph.GetFirstMatchingVertex(v => v.Value.Equals(superSourceValue));
                    if (modifyingCycleLeft = BellmanFordMoore.TryFindNegativeCycle(bfmGraph,
                                                                                   bfmSuperSource,
                                                                                   zeroValue,
                                                                                   maxValue,
                                                                                   combineValues,
                                                                                   out IEnumerable <IWeightedDirectedEdge <TV, TW> > cycle))
                    {
                        // Get minimum capacity of the cycle in the residual graph
                        List <IWeightedDirectedEdge <TV, TW> > rgCycle = new List <IWeightedDirectedEdge <TV, TW> >();
                        foreach (IWeightedDirectedEdge <TV, TW> edge in cycle)
                        {
                            rgCycle.Add((IWeightedDirectedEdge <TV, TW>)residualGraph.GetEdgeBetweenVerteces(edge.OriginVertex.Value, edge.TargetVertex.Value));
                        }
                        TW minCycleCapacity = rgCycle.Min(e => e.Weight);

                        // Modify b-flow along cycle
                        foreach (IWeightedDirectedEdge <TV, TW> edge in rgCycle)
                        {
                            if (edge.GetAttribute <EdgeDirection>(Constants.DIRECTION) == EdgeDirection.Forward)
                            {
                                IWeightedDirectedEdge <TV, TW> graphEdge = (IWeightedDirectedEdge <TV, TW>)graph.GetEdgeBetweenVerteces(edge.OriginVertex.Value, edge.TargetVertex.Value);
                                graphEdge.SetAttribute(Constants.FLOW, combineValues(graphEdge.GetAttribute <TW>(Constants.FLOW), minCycleCapacity));
                            }
                            else
                            {
                                IWeightedDirectedEdge <TV, TW> graphEdge = (IWeightedDirectedEdge <TV, TW>)graph.GetEdgeBetweenVerteces(edge.TargetVertex.Value, edge.OriginVertex.Value);
                                graphEdge.SetAttribute(Constants.FLOW, substractValues(graphEdge.GetAttribute <TW>(Constants.FLOW), minCycleCapacity));
                            }
                        }
                    }
                }while (modifyingCycleLeft);

                // Return same graph
                return(graph);
            }
            else
            {
                throw new NoBFlowException();
            }
        }