Example #1
0
        // compute residual path from source to sink using breadth first search
        // This way the Edmonds & Karp-Algorithm ensures that the shortest path
        // is chosen in each iteration and thus ensures polynomial complexity.
        public override List <int> ComputeResidualPath(FlowGraph network)
        {
            int V = network.Nodes();

            bool[] visited = new bool[V];               // marks already visited nodes.
            int[]  pred    = new int[V];                // marks the predecessor of the
            // current node for the output path
            // initialize
            for (int v = 0; v < V; v++)
            {
                visited[v] = false;
            }
            for (int v = 0; v < V; v++)
            {
                pred[v] = -1;
            }
            visited[network.Source] = true;
            Queue <int> nextNodes = new Queue <int>();

            nextNodes.Enqueue(network.Source);
            while (nextNodes.Count > 0)
            {
                int v = nextNodes.Dequeue();
                foreach (Edge edge in network.Edges(v))
                {
                    // we are only interested in paths with nonzero weights.
                    if ((edge.Weight() > 0) && !visited[edge.To()])
                    {
                        if (edge.To() != network.Target)
                        {
                            // If we have not yet reached the target, continue the
                            // search.
                            visited[edge.To()] = true;
                            pred[edge.To()]    = v;
                            nextNodes.Enqueue(edge.To());
                        }
                        else
                        {
                            // If we have reached the target, we extract the path.
                            List <int> path = new List <int>();
                            path.Add(network.Target);
                            while (v != network.Source)
                            {
                                path.Add(v);
                                v = pred[v];
                            }
                            path.Add(network.Source);
                            // ... and return it
                            path.Reverse();
                            return(path);
                        }
                    }
                }
            }
            // no path found, return null
            return(null);
        }
Example #2
0
        // Computes a bipartite matching in the given graph with the given partition of nodes.
        // The partition is given in form of a boolean array as returned by the Partition
        // function.
        public static List <Edge> Matching(UndirectedGraph.Graph graph, bool[] partition)
        {
            List <Edge> matching = new List <Edge>();

            //TODO: Implement

            DirectedWeightedGraph.Graph g = new DirectedWeightedGraph.Graph(graph.Nodes() + 2);

            int s = 0;
            int t = g.Nodes() - 1;

            for (int i = 0; i < graph.Nodes(); i++)
            {
                List <int> nodes = graph.AllNodes(i);
                for (int j = 0; j < nodes.Count; j++)
                {
                    g.AddEdge(i + 1, nodes[j], 1);

                    if (partition[i])
                    {
                        g.AddEdge(i + 1, t, 1);
                    }
                    else
                    {
                        g.AddEdge(s, i + 1, 1);
                    }
                }
            }


            FlowGraph     network   = new FlowGraph(g, s, t);
            FlowOptimizer optimizer = new EdmondsKarp.EdmondsKarp();

            //optimizer.InteractiveOptimumFlow(network);

            optimizer.OptimumFlow(network);
            network.ComputeFlow();

            for (int v = 1; v < network.Nodes() - 1; v++)
            {
                foreach (Edge edge in network.Edges(v))
                {
                    if (edge.To() != s && edge.From() != t && edge.Weight() > 0)
                    {
                        matching.Add(edge);
                        break;
                    }
                }
            }

            // Display the optimum flow
            //System.Console.WriteLine("Flow is " + network.ComputeFlow());

            return(matching);
        }