Пример #1
0
        private static void BuildGraph()
        {
            // For each cube from the cuboid we assign two nodes in the graph
            int graphNodesCount = 2 * (width * height * depth) + 2;
            graph = new Graph(graphNodesCount);

            // Add edges from the startNode to the top side of the cuboid
            startNode = graphNodesCount - 2;
            for (int w = 0; w < width; w++)
            {
                for (int h = 0; h < height; h++)
                {
                    int topSideNode = CalcNodeNumber(w, h, 0, 0);
                    int capacity = cuboid[w, h, 0];
                    graph.AddEdge(startNode, topSideNode, capacity);
                }
            }

            // Add edges between each cube and its 5 neighbors
            for (int d = 0; d < depth; d++)
            {
                for (int w = 0; w < width; w++)
                {
                    for (int h = 0; h < height; h++)
                    {
                        AddEdgeIfPossible(w, h, d, w + 1, h, d);
                        AddEdgeIfPossible(w, h, d, w - 1, h, d);
                        AddEdgeIfPossible(w, h, d, w, h + 1, d);
                        AddEdgeIfPossible(w, h, d, w, h - 1, d);
                        AddEdgeIfPossible(w, h, d, w, h, d + 1);
                        AddEdgeBetweenDoubledNode(w, h, d);
                    }
                }
            }

            // Add edges from the bottom side of the cuboid the the endNode
            endNode = graphNodesCount - 1;
            for (int w = 0; w < width; w++)
            {
                for (int h = 0; h < height; h++)
                {
                    int bottomSideNode = CalcNodeNumber(w, h, depth - 1, 1);
                    int capacity = cuboid[w, h, depth - 1];
                    graph.AddEdge(bottomSideNode, endNode, capacity);
                }
            }
        }
Пример #2
0
        private static int GetPathCapacity(Graph g, List<int> path)
        {
            int pathCapacity = int.MaxValue;
            for (int i = 0; i < path.Count - 1; i++)
            {
                int fromNode = path[i];
                int toNode = path[i + 1];
                int edgeCapacity = g.Capacities[fromNode, toNode];
                if (edgeCapacity < pathCapacity)
                {
                    pathCapacity = edgeCapacity;
                }
            }

            return pathCapacity;
        }
Пример #3
0
 private static void AugmentPath(Graph g, List<int> path, int minCapacity)
 {
     for (int i = 0; i < path.Count - 1; i++)
     {
         int fromNode = path[i];
         int toNode = path[i + 1];
         g.Capacities[fromNode, toNode] -= minCapacity;
         g.Capacities[toNode, fromNode] += minCapacity;
     }
 }
Пример #4
0
        private static List<int> FindAugumentingPathBFS(Graph g, int startNode, int endNode)
        {
            int?[] prevNode = new int?[g.NodesCount];
            Queue<int> queue = new Queue<int>();
            bool[] visited = new bool[g.NodesCount];
            visited[startNode] = true;
            queue.Enqueue(startNode);

            while (queue.Count > 0)
            {
                int currentNode = queue.Dequeue();

                if (currentNode == endNode)
                {
                    // Build the path by using prevNode[]
                    List<int> path = new List<int>();
                    int? node = endNode;
                    while (node != null)
                    {
                        path.Add(node.Value);
                        node = prevNode[node.Value];
                    }
                    path.Reverse();
                    return path;
                }

                // Append all possible child nodes to the queue
                foreach (var childNode in g.ChildNodes[currentNode])
                {
                    var capacity = g.Capacities[currentNode, childNode];
                    if (capacity > 0 && !visited[childNode])
                    {
                        prevNode[childNode] = currentNode;
                        visited[childNode] = true;
                        queue.Enqueue(childNode);
                    }
                }
            }

            return null;
        }
Пример #5
0
        public static int MaxFlow(Graph g, int sourceNode, int terminalNode)
        {
            int maxFlow = 0;

            while (true)
            {
                List<int> augumentingPath = FindAugumentingPathBFS(g, sourceNode, terminalNode);
                if (augumentingPath == null)
                {
                    // No more augumenting paths --> max flow is found
                    break;
                }
                int pathCapacity = GetPathCapacity(g, augumentingPath);
                AugmentPath(g, augumentingPath, pathCapacity);
                maxFlow += pathCapacity;
            }

            return maxFlow;
        }