Ejemplo n.º 1
0
        static int[] FindMatching(bool[][] bipartiteGraph)
        {
            int numLeft  = bipartiteGraph.Length;
            int numRight = bipartiteGraph[0].Length;

            int[]     matching = new int[numLeft];
            FlowGraph graph    = ReadGraph(bipartiteGraph);

            MaxFlow(graph, 0, graph.Size() - 1);
            for (int i = 0; i < numLeft; i++)
            {
                foreach (int id in graph.GetIds(i + 1))
                {
                    Edge edge = graph.GetEdge(id);
                    if (edge.flow == 1)
                    {
                        matching[i] = edge.to - numLeft;
                        break;
                    }
                    matching[i] = -1;
                }
            }

            return(matching);
        }
Ejemplo n.º 2
0
 static void MaxFlow(FlowGraph graph, int from, int to)
 {
     while (true)
     {
         bool foundPath = false;
         var  queue     = new Queue <int>();
         var  parentIds = new int[graph.Size()];
         for (int i = 0; i < parentIds.Length; i++)
         {
             parentIds[i] = -1; //unvisited nodes are -1
         }
         queue.Enqueue(0);
         //Breadth-first search, finding shortest path
         while (queue.Count != 0 && !foundPath)
         {
             int node = queue.Dequeue();
             var ids  = graph.GetIds(node); // all the edges from current node
             foreach (int id in ids)
             {
                 var edge = graph.GetEdge(id);
                 if (edge.flow < edge.capacity && parentIds[edge.to] == -1) // if there's capacity left and "edge pointing" vertice isn't visited
                 {
                     if (edge.to == edge.from)
                     {
                         continue;
                     }
                     parentIds[edge.to] = id;
                     if (edge.to == graph.Size() - 1) // we found path
                     {
                         foundPath = true;
                         break;
                     }
                     queue.Enqueue(edge.to);
                 }
             }
         }
         if (!foundPath)
         {
             break;
         }
         //find the value of the flow
         to = graph.Size() - 1;
         var minCap = -1;
         //calculate min capacity
         while (to != 0)
         {
             var id   = parentIds[to];
             var edge = graph.GetEdge(id);
             if (minCap == -1 || (edge.capacity - edge.flow) < minCap)
             {
                 minCap = edge.capacity - edge.flow;
             }
             to = edge.from;
         }
         to = graph.Size() - 1;
         //adding flow to edges
         while (to != 0)
         {
             var id   = parentIds[to];
             var edge = graph.GetEdge(id);
             graph.AddFlow(id, minCap);
             to = edge.from;
         }
     }
 }
Ejemplo n.º 3
0
        static int MaxFlow(FlowGraph graph, int from, int to)
        {
            int flow = 0;

            while (true)
            {
                bool foundPath = false;
                var  queue     = new Queue <int>();
                var  parentIds = new int[graph.Size()];
                for (int i = 0; i < parentIds.Length; i++)
                {
                    parentIds[i] = -1; //unvisited nodes are -1
                }
                queue.Enqueue(0);
                //bfs
                while (queue.Count != 0 && !foundPath)
                {
                    int node = queue.Dequeue();
                    var ids  = graph.GetIds(node); // all the edges from current node
                    foreach (int id in ids)
                    {
                        var edge = graph.GetEdge(id);
                        if (edge.flow < edge.capacity && parentIds[edge.to] == -1)
                        {
                            if (edge.to == edge.from)
                            {
                                continue;
                            }
                            parentIds[edge.to] = id;
                            if (edge.to == graph.Size() - 1) // we found path
                            {
                                foundPath = true;
                                break;
                            }
                            queue.Enqueue(edge.to);
                        }
                    }
                }
                if (!foundPath)
                {
                    break;
                }
                //find the value of the flow
                to = graph.Size() - 1;
                var minCap = -1;
                //calculate min capacity
                while (to != 0)
                {
                    var id   = parentIds[to];
                    var edge = graph.GetEdge(id);
                    if (minCap == -1 || (edge.capacity - edge.flow) < minCap)
                    {
                        minCap = edge.capacity - edge.flow;
                    }
                    to = edge.from;
                }
                to = graph.Size() - 1;
                //adding flow to edges
                while (to != 0)
                {
                    var id   = parentIds[to];
                    var edge = graph.GetEdge(id);
                    graph.AddFlow(id, minCap);
                    to = edge.from;
                }
            }
            //calculate the flow
            // to do that we only sum the flows of the start node
            foreach (int id in graph.GetIds(0))
            {
                var edge = graph.GetEdge(id);
                flow += edge.flow;
            }
            return(flow);
        }