Exemple #1
0
        // Craete a network from a network file.
        public static Network LoadNetwork(string filename)
        {
            // Make a new network.
            Network network = new Network();

            // Read the data.
            string[] allLines = File.ReadAllLines(filename);

            // Get the number of nodes.
            int numNodes = int.Parse(allLines[0]);

            // Create the nodes.
            for (int i = 0; i < numNodes; i++)
            {
                network.AllNodes.Add(new NetworkNode());
                network.AllNodes[i].Index = i;
            }

            // Read the nodes.
            char[] separators = { ',' };
            for (int i = 1; i < allLines.Length; i++)
            {
                NetworkNode node       = network.AllNodes[i - 1];
                string[]    nodeFields = allLines[i].Split(separators);

                // Get the node's text and coordinates.
                node.Name     = nodeFields[0];
                node.Location = new PointF(
                    int.Parse(nodeFields[1]),
                    int.Parse(nodeFields[2])
                    );

                // Get the node's links.
                for (int j = 3; j < nodeFields.Length; j += 3)
                {
                    // Get the next link.
                    NetworkLink link = new NetworkLink();
                    link.Nodes[0] = node;
                    int index = int.Parse(nodeFields[j]);
                    link.Nodes[1] = network.AllNodes[index];
                    link.Cost     = int.Parse(nodeFields[j + 1]);
                    link.Capacity = int.Parse(nodeFields[j + 2]);
                    node.Links.Add(link);
                }
            }

            return(network);
        }
Exemple #2
0
        // Find a shortest path tree rooted at fromNode
        // by using a label correcting algorithm.
        // Return the tree's total cost.
        public int FindLabelCorrectingPathTree(NetworkNode fromNode)
        {
            // Reset the network.
            ResetNetwork();

            // Set all nodes' distances to infinity and their labels to 0.
            foreach (NetworkNode node in AllNodes)
            {
                node.Distance = int.MaxValue;
                node.Text     = "0";
            }

            // Add the start node to the shortest path tree.
            fromNode.Visited  = true;
            fromNode.Distance = 0;

            // Make the candidate list.
            Queue <NetworkLink> candidateLinks = new Queue <NetworkLink>();

            // Add the start node's links to the candidate list.
            foreach (NetworkLink link in fromNode.Links)
            {
                candidateLinks.Enqueue(link);
            }

            // Make a shortest path tree.
            while (candidateLinks.Count > 0)
            {
                // Use the first link in the candidate list.
                NetworkLink link = candidateLinks.Dequeue();

                // See if link this improves its destination node's distance.
                int         newDistance = link.Nodes[0].Distance + link.Cost;
                NetworkNode toNode      = link.Nodes[1];
                if (newDistance < toNode.Distance)
                {
                    // This is an improvement.
                    // Update the node's distance.
                    toNode.Distance = newDistance;

                    // Update the node's FromNode and FromLink.
                    toNode.FromNode = link.Nodes[0];
                    toNode.FromLink = link;

                    // Update the node's label.
                    int numUpdates = int.Parse(toNode.Text);
                    numUpdates++;
                    toNode.Text = numUpdates.ToString();

                    // Add the node's links to the candidate list.
                    foreach (NetworkLink newLink in toNode.Links)
                    {
                        candidateLinks.Enqueue(newLink);
                    }
                }
            }

            // Set the Visited properties for the visited nodes and links.
            int cost = 0;

            foreach (NetworkNode node in AllNodes)
            {
                node.Visited = true;
                if (node.FromLink != null)
                {
                    node.FromLink.Visited = true;
                    cost += node.FromLink.Cost;
                }
            }

            // Return the total cost.
            return(cost);
        }
Exemple #3
0
        // Follow a spanning tree's links to find a path from fromNode to toNode.
        public int FindSpanningTreePath(NetworkNode fromNode, NetworkNode toNode,
                                        out List <NetworkNode> pathNodes, out List <NetworkLink> pathLinks)
        {
            // Follow the tree's links back from toNode to fromNode.
            pathNodes = new List <NetworkNode>();
            pathLinks = new List <NetworkLink>();
            NetworkNode currentNode = toNode;

            while (currentNode != fromNode)
            {
                // Add this node to the path.
                pathNodes.Add(currentNode);

                // Find the previous node.
                NetworkNode prevNode = currentNode.FromNode;

                // Find the link that leads to currentNode.
                NetworkLink prevLink = null;
                foreach (NetworkLink link in prevNode.Links)
                {
                    if (link.Nodes[1] == currentNode)
                    {
                        prevLink = link;
                        break;
                    }
                }

                // Make sure we found the link.
                Debug.Assert(prevLink != null);

                // Add the link to the path.
                pathLinks.Add(prevLink);

                // Move to the next node.
                currentNode = prevNode;
            } // while (currentNode != fromNode)

            // Add the start node.
            pathNodes.Add(fromNode);

            // Reverse the order of the nodes and links.
            pathNodes.Reverse();
            pathLinks.Reverse();

            // Unmark all nodes and links.
            DeselectNodes();
            DeselectBranches();

            // Marks the path's nodes and links.
            foreach (NetworkNode node in pathNodes)
            {
                node.Visited = true;
            }
            foreach (NetworkLink link in pathLinks)
            {
                link.Visited = true;
            }

            // Calculate the cost of the path.
            int cost = 0;

            foreach (NetworkLink link in pathLinks)
            {
                cost += link.Cost;
            }

            // Return the cost.
            return(cost);
        }
Exemple #4
0
        // Find a shortest path tree rooted at fromNode
        // by using a label setting algorithm.
        // Return the tree's total cost.
        public int FindLabelSettingPathTree(NetworkNode fromNode)
        {
            // Reset the network.
            ResetNetwork();

            // Keep track of the number of nodes in the tree.
            int numDone = 0;

            // Add the start node to the shortest path tree.
            fromNode.Visited  = true;
            fromNode.Distance = 0;
            fromNode.Text     = numDone.ToString();
            numDone++;

            // Track the tree's total cost.
            int cost = 0;

            // Make the candidate list.
            List <NetworkLink> candidateLinks = new List <NetworkLink>();

            // Add the start node's links to the candidate list.
            foreach (NetworkLink link in fromNode.Links)
            {
                candidateLinks.Add(link);
            }

            // Make a shortest path tree.
            while (candidateLinks.Count > 0)
            {
                // Find the best link.
                NetworkLink bestLink = null;
                int         bestCost = int.MaxValue;

                for (int i = candidateLinks.Count - 1; i >= 0; i--)
                {
                    NetworkLink testLink = candidateLinks[i];

                    // See if the link leads outside the tree.
                    if (testLink.Nodes[1].Visited)
                    {
                        // Remove this link.
                        candidateLinks.RemoveAt(i);
                    }
                    else
                    {
                        // See if this link is an improvement.
                        int testCost = testLink.Nodes[0].Distance + testLink.Cost;
                        if (testCost < bestCost)
                        {
                            bestCost = testCost;
                            bestLink = testLink;
                        }
                    }
                }

                // If we found no link, then the candidate
                // list must be empty and we're done.
                if (bestLink == null)
                {
                    Debug.Assert(candidateLinks.Count == 0);
                    break;
                }

                // Use this link.
                // Remove it from the candidate list.
                candidateLinks.Remove(bestLink);

                // Add the node to the tree.
                NetworkNode bestNode = bestLink.Nodes[1];
                bestNode.Distance = bestLink.Nodes[0].Distance + bestLink.Cost;
                bestNode.Visited  = true;
                bestLink.Visited  = true;
                bestNode.FromNode = bestLink.Nodes[0];
                bestNode.Text     = numDone.ToString();
                numDone++;

                // Add the node's links to the tree.
                foreach (NetworkLink newLink in bestNode.Links)
                {
                    if (!newLink.Nodes[1].Visited)
                    {
                        candidateLinks.Add(newLink);
                    }
                }

                // Add the link's cost to the tree's total cost.
                cost += bestLink.Cost;
            }

            // Return the total cost.
            return(cost);
        }
Exemple #5
0
        // Build a minimal spanning tree. Return its total cost.
        // When it adds a node to the spanning tree, the algorithm
        // also adds its links that lead outside of the tree to a list.
        // Later it searches that list for a minimal link.
        public int MakeMinimalSpanningTree(NetworkNode root, out bool isConnected)
        {
            // Reset the network.
            ResetNetwork();

            // The total cost of the links in the spanning tree.
            int totalCost = 0;

            // Add the root node's links to the link candidate list.
            List <NetworkLink> candidateLinks = new List <NetworkLink>();

            foreach (NetworkLink link in root.Links)
            {
                candidateLinks.Add(link);
            }

            // Visit the root node.
            root.Visited = true;

            // Process the list until it's empty.
            while (candidateLinks.Count > 0)
            {
                // Find the link with the lowest cost.
                NetworkLink bestLink = candidateLinks[0];
                int         bestCost = bestLink.Cost;
                for (int i = 1; i < candidateLinks.Count; i++)
                {
                    if (candidateLinks[i].Cost < bestCost)
                    {
                        // Save this improvement.
                        bestLink = candidateLinks[i];
                        bestCost = bestLink.Cost;
                    }
                }

                // Remove the link from the list.
                candidateLinks.Remove(bestLink);

                // Get the node at the other end of the link.
                NetworkNode toNode = bestLink.Nodes[1];

                // See if the link's node is still unmarked.
                if (!toNode.Visited)
                {
                    // Use the link.
                    bestLink.Visited = true;
                    totalCost       += bestLink.Cost;
                    toNode.Visited   = true;

                    // Record the node that got us here.
                    toNode.FromNode = bestLink.Nodes[0];

                    // Process toNode's links.
                    foreach (NetworkLink newLink in toNode.Links)
                    {
                        // If the node hasn't been visited,
                        // add the link to the list.
                        if (!newLink.Nodes[1].Visited)
                        {
                            candidateLinks.Add(newLink);
                        }
                    }
                }
            }

            // See if the network is connected.
            isConnected = true;
            foreach (NetworkNode node in AllNodes)
            {
                if (!node.Visited)
                {
                    isConnected = false;
                    break;
                }
            }

            return(totalCost);
        }