Exemple #1
0
        // Find a shortest path between the two nodes
        // by using a label correcting algorithm.
        // Return the path's total cost.
        public int FindLabelCorrectingPath(NetworkNode fromNode, NetworkNode toNode,
                                           out List <NetworkNode> pathNodes, out List <NetworkLink> pathLinks)
        {
            // Build a shortest path tree.
            FindLabelCorrectingPathTree(fromNode);

            // Follow the tree's links back from toNode to fromNode.
            return(FindSpanningTreePath(fromNode, toNode, out pathNodes, out pathLinks));
        }
Exemple #2
0
        // Find any path between the two nodes. Return the path's total cost.
        public int FindAnyPath(NetworkNode fromNode, NetworkNode toNode,
                               out List <NetworkNode> pathNodes, out List <NetworkLink> pathLinks)
        {
            // Make a spanning tree.
            bool isConnected;

            MakeSpanningTree(fromNode, out isConnected);

            // Follow the tree's links back from toNode to fromNode.
            return(FindSpanningTreePath(fromNode, toNode, out pathNodes, out pathLinks));
        }
 // Return true if a neighbor has the indicated color.
 public bool NeighborHasColor(Color color)
 {
     foreach (NetworkLink link in Links)
     {
         NetworkNode neighbor = link.Nodes[1];
         if (neighbor.IsColored && (neighbor.BackColor == color))
         {
             return(true);
         }
     }
     return(false);
 }
Exemple #4
0
        // Make a link between the two nodes.
        public NetworkLink(NetworkNode node0, NetworkNode node1)
        {
            Nodes[0] = node0;
            Nodes[1] = node1;

            float dx = node0.Location.X - node1.Location.X;
            float dy = node0.Location.Y - node1.Location.Y;

            Cost = (int)Math.Sqrt(dx * dx + dy * dy);

            Capacity = Rand.Next(1, 3) + Rand.Next(0, 3);

            node0.Links.Add(this);
        }
Exemple #5
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 #6
0
        private void allPairsToolStripButton_Click(object sender, EventArgs e)
        {
            // Find all pairs shortest paths.
            int[,] distance;
            int[,] via;
            TheNetwork.FindAllPairsPaths(out distance, out via);

            // Display the arrays.
            Console.WriteLine("Final arrays:");
            Console.WriteLine("distance:");
            Console.WriteLine(ArrayToString(distance, false));
            Console.WriteLine("via:");
            Console.WriteLine(ArrayToString(via, true));

            // Display all of the paths.
            int N = TheNetwork.AllNodes.Count;

            for (int i = 0; i < N; i++)
            {
                for (int j = 0; j < N; j++)
                {
                    List <NetworkNode> path =
                        TheNetwork.FindAllPairsPath(distance, via, i, j);
                    NetworkNode startNode = TheNetwork.AllNodes[i];
                    NetworkNode endNode   = TheNetwork.AllNodes[j];
                    Console.Write(startNode.Name + " --> " + endNode.Name +
                                  " [" + distance[i, j] + "] : ");
                    if (path == null)
                    {
                        Console.WriteLine("No path");
                    }
                    else
                    {
                        foreach (NetworkNode viaNode in path)
                        {
                            Console.Write(viaNode.Name + " ");
                        }
                        Console.WriteLine("");
                    }
                }
            }
            Console.WriteLine("");

            MessageBox.Show("See the Output Window for results.");
        }
 // Add a link to the indicated node.
 public void AddLinkTo(NetworkNode node)
 {
     new NetworkLink(this, node);
 }
Exemple #8
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 #9
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 #10
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 #11
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);
        }
Exemple #12
0
        // Build a spanning tree. Return its total cost.
        public int MakeSpanningTree(NetworkNode root, out bool isConnected)
        {
            // Reset the network.
            ResetNetwork();

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

            // Push the root node onto the stack.
            Stack <NetworkNode> stack = new Stack <NetworkNode>();

            stack.Push(root);

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

            // Process the stack until it's empty.
            while (stack.Count > 0)
            {
                // Get the next node from the stack.
                NetworkNode node = stack.Pop();

                // Process the node's links.
                foreach (NetworkLink link in node.Links)
                {
                    // Only use the link if the destination
                    // node hasn't been visited.
                    NetworkNode toNode = link.Nodes[1];
                    if (!toNode.Visited)
                    {
                        // Mark the node as visited.
                        toNode.Visited = true;

                        // Record the node that got us here.
                        toNode.FromNode = node;

                        // Mark the link as part of the tree.
                        link.Visited = true;

                        // Push the node onto the stack.
                        stack.Push(toNode);

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

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

            return(totalCost);
        }
Exemple #13
0
        // Return the network's connected components.
        public List <List <NetworkNode> > GetConnectedComponents()
        {
            // Reset the network.
            ResetNetwork();

            // Keep track of the number of nodes visited.
            int numVisited = 0;

            // Make the result list of lists.
            List <List <NetworkNode> > components = new List <List <NetworkNode> >();

            // Repeat until all nodes are in a connected component.
            while (numVisited < AllNodes.Count)
            {
                // Find a node that hasn't been visited.
                NetworkNode startNode = null;
                foreach (NetworkNode node in AllNodes)
                {
                    if (!node.Visited)
                    {
                        startNode = node;
                        break;
                    }
                }

                // Make sure we found one.
                Debug.Assert(startNode != null);

                // Add the start node to the stack.
                Stack <NetworkNode> stack = new Stack <NetworkNode>();
                stack.Push(startNode);
                startNode.Visited = true;
                numVisited++;

                // Add the node to a new connected component.
                List <NetworkNode> component = new List <NetworkNode>();
                components.Add(component);
                component.Add(startNode);

                // Process the stack until it's empty.
                while (stack.Count > 0)
                {
                    // Get the next node from the stack.
                    NetworkNode node = stack.Pop();

                    // Process the node's links.
                    foreach (NetworkLink link in node.Links)
                    {
                        // Only use the link if the destination
                        // node hasn't been visited.
                        NetworkNode toNode = link.Nodes[1];
                        if (!toNode.Visited)
                        {
                            // Mark the node as visited.
                            toNode.Visited = true;

                            // Mark the link as part of the tree.
                            link.Visited = true;
                            numVisited++;

                            // Add the node to the current connected component.
                            component.Add(toNode);

                            // Push the node onto the stack.
                            stack.Push(toNode);
                        }
                    }
                }
            }

            // Return the components.
            return(components);
        }
Exemple #14
0
        // Traverse the network in breadth-first order.
        public List <NetworkNode> BreadthFirstTraverse(NetworkNode startNode, out bool isConnected)
        {
            // Reset the network.
            ResetNetwork();

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

            // Add the start node to the queue.
            Queue <NetworkNode> queue = new Queue <NetworkNode>();

            queue.Enqueue(startNode);

            // Visit the start node.
            List <NetworkNode> traversal = new List <NetworkNode>();

            traversal.Add(startNode);
            startNode.Visited = true;
            startNode.Text    = numDone.ToString();
            numDone++;

            // Process the queue until it's empty.
            while (queue.Count > 0)
            {
                // Get the next node from the queue.
                NetworkNode node = queue.Dequeue();

                // Process the node's links.
                foreach (NetworkLink link in node.Links)
                {
                    NetworkNode toNode = link.Nodes[1];

                    // Only use the link if the destination
                    // node hasn't been visited.
                    if (!toNode.Visited)
                    {
                        // Mark the node as visited.
                        toNode.Visited = true;
                        toNode.Text    = numDone.ToString();
                        numDone++;

                        // Add the node to the traversal.
                        traversal.Add(toNode);

                        // Add the link to the traversal.
                        link.Visited = true;

                        // Add the node onto the queue.
                        queue.Enqueue(toNode);
                    }
                }
            }

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

            return(traversal);
        }
Exemple #15
0
 // Make links from node0 to node1 and node1 to node0.
 public void MakeLinks(NetworkNode node0, NetworkNode node1)
 {
     new NetworkLink(node0, node1);
     new NetworkLink(node1, node0);
 }
Exemple #16
0
        // Add a node or link if appropriate.
        private void networkPictureBox_MouseClick(object sender, MouseEventArgs e)
        {
            if (Mode == Modes.AddNode)
            {
                // Add a node.
                NetworkNode node = new NetworkNode();
                node.Location = e.Location;
                node.Index    = TheNetwork.AllNodes.Count;
                node.Name     = NumberToLetters(node.Index);
                TheNetwork.AllNodes.Add(node);
                networkPictureBox.Refresh();
            }
            else if (
                (Mode == Modes.AddLink1) ||
                (Mode == Modes.AddLink2))
            {
                // Add a link.
                // See if there is a node here.
                NetworkNode node = TheNetwork.FindNode(e.Location);
                if (node == null)
                {
                    SystemSounds.Beep.Play();
                }
                else
                {
                    if (e.Button == MouseButtons.Left)
                    {
                        Node0 = node;
                    }
                    else
                    {
                        Node1 = node;
                    }

                    // See if we have both nodes.
                    if ((Node0 != null) && (Node1 != null))
                    {
                        // Make the link.
                        if (Mode == Modes.AddLink1)
                        {
                            TheNetwork.MakeLink(Node0, Node1);
                        }
                        else
                        {
                            TheNetwork.MakeLinks(Node0, Node1);
                        }

                        // We're done with this link.
                        Node0 = null;
                        Node1 = null;

                        // Redraw.
                        networkPictureBox.Refresh();
                    }
                }
            }
            else if (Mode == Modes.DFTraversal)
            {
                // See if there is a node here.
                NetworkNode node = TheNetwork.FindNode(e.Location);
                if (node == null)
                {
                    SystemSounds.Beep.Play();
                }
                else
                {
                    // Traverse the network.
                    bool isConnected;
                    List <NetworkNode> traversal =
                        TheNetwork.DepthFirstTraverse(node, out isConnected);

                    // Display the traversal.
                    string txt = "";
                    foreach (NetworkNode traversalNode in traversal)
                    {
                        txt += " " + traversalNode.ToString();
                    }
                    toolStripStatusLabel1.Text = "Traversal: " + txt;
                    if (isConnected)
                    {
                        txt += " Connected.";
                    }
                    else
                    {
                        txt += " Not connected.";
                    }
                    toolStripStatusLabel1.Text = txt;
                    Console.WriteLine(txt);

                    // Redraw the network.
                    networkPictureBox.Refresh();
                }
            }
            else if (Mode == Modes.BFTraversal)
            {
                // See if there is a node here.
                NetworkNode node = TheNetwork.FindNode(e.Location);
                if (node == null)
                {
                    SystemSounds.Beep.Play();
                }
                else
                {
                    // Traverse the network.
                    bool isConnected;
                    List <NetworkNode> traversal =
                        TheNetwork.BreadthFirstTraverse(node, out isConnected);

                    // Display the traversal.
                    string txt = "";
                    foreach (NetworkNode traversalNode in traversal)
                    {
                        txt += " " + traversalNode.ToString();
                    }
                    toolStripStatusLabel1.Text = "Traversal: " + txt;
                    if (isConnected)
                    {
                        txt += " Connected.";
                    }
                    else
                    {
                        txt += " Not connected.";
                    }
                    toolStripStatusLabel1.Text = txt;
                    Console.WriteLine(txt);

                    // Redraw the network.
                    networkPictureBox.Refresh();
                }
            }
            else if (Mode == Modes.SpanningTree)
            {
                // See if there is a node here.
                NetworkNode node = TheNetwork.FindNode(e.Location);
                if (node == null)
                {
                    SystemSounds.Beep.Play();
                }
                else
                {
                    // Build a spanning tree.
                    bool  isConnected;
                    float cost = TheNetwork.MakeSpanningTree(node, out isConnected);
                    toolStripStatusLabel1.Text = "Total cost: " + cost.ToString();
                    string txt;
                    if (isConnected)
                    {
                        txt = "Connected. ";
                    }
                    else
                    {
                        txt = "Not connected. ";
                    }
                    txt += "Total cost: " + cost.ToString();
                    toolStripStatusLabel1.Text = txt;
                    Console.WriteLine(txt);

                    // Redraw the network.
                    networkPictureBox.Refresh();
                }
            }
            else if (Mode == Modes.MinimalSpanningTree)
            {
                // See if there is a node here.
                NetworkNode node = TheNetwork.FindNode(e.Location);
                if (node == null)
                {
                    SystemSounds.Beep.Play();
                }
                else
                {
                    // Build a spanning tree.
                    bool   isConnected;
                    float  cost = TheNetwork.MakeMinimalSpanningTree(node, out isConnected);
                    string txt;
                    if (isConnected)
                    {
                        txt = "Connected. ";
                    }
                    else
                    {
                        txt = "Not connected. ";
                    }
                    txt += "Total cost: " + cost.ToString();
                    toolStripStatusLabel1.Text = txt;
                    Console.WriteLine(txt);

                    // Redraw the network.
                    networkPictureBox.Refresh();
                }
            }
            else if (Mode == Modes.AnyPath)
            {
                // See if there is a node here.
                NetworkNode node = TheNetwork.FindNode(e.Location);
                if (node == null)
                {
                    SystemSounds.Beep.Play();
                }
                else
                {
                    if (e.Button == MouseButtons.Left)
                    {
                        Node0 = node;
                    }
                    else
                    {
                        Node1 = node;
                    }

                    // See if we have both nodes.
                    if ((Node0 != null) && (Node1 != null))
                    {
                        // Find a path between the nodes.
                        List <NetworkNode> pathNodes;
                        List <NetworkLink> pathLinks;
                        int cost = TheNetwork.FindAnyPath(Node0, Node1,
                                                          out pathNodes, out pathLinks);

                        string txt = "Path: ";
                        foreach (NetworkNode pathNode in pathNodes)
                        {
                            txt += pathNode.Name + " ";
                        }
                        txt += "Total cost: " + cost.ToString();
                        toolStripStatusLabel1.Text = txt;
                        Console.WriteLine(txt);

                        // Redraw the network.
                        networkPictureBox.Refresh();
                    }
                }
            }
            else if (Mode == Modes.LabelSettingTree)
            {
                // See if there is a node here.
                NetworkNode node = TheNetwork.FindNode(e.Location);
                if (node == null)
                {
                    SystemSounds.Beep.Play();
                }
                else
                {
                    // Build a label setting shortest path tree.
                    float  cost = TheNetwork.FindLabelSettingPathTree(node);
                    string txt  = "Total cost: " + cost.ToString();
                    toolStripStatusLabel1.Text = txt;
                    Console.WriteLine(txt);

                    // Redraw the network.
                    networkPictureBox.Refresh();
                }
            }
            else if (Mode == Modes.LabelSettingPath)
            {
                // See if there is a node here.
                NetworkNode node = TheNetwork.FindNode(e.Location);
                if (node == null)
                {
                    SystemSounds.Beep.Play();
                }
                else
                {
                    if (e.Button == MouseButtons.Left)
                    {
                        Node0 = node;
                    }
                    else
                    {
                        Node1 = node;
                    }

                    // See if we have both nodes.
                    if ((Node0 != null) && (Node1 != null))
                    {
                        // Find a path between the nodes.
                        List <NetworkNode> pathNodes;
                        List <NetworkLink> pathLinks;
                        int cost = TheNetwork.FindLabelSettingPath(Node0, Node1,
                                                                   out pathNodes, out pathLinks);

                        string txt = "Path: ";
                        foreach (NetworkNode pathNode in pathNodes)
                        {
                            txt += pathNode.Name + " ";
                        }
                        txt += "Total cost: " + cost.ToString();
                        toolStripStatusLabel1.Text = txt;
                        Console.WriteLine(txt);

                        // Redraw the network.
                        networkPictureBox.Refresh();
                    }
                }
            }
            else if (Mode == Modes.LabelCorrectingTree)
            {
                // See if there is a node here.
                NetworkNode node = TheNetwork.FindNode(e.Location);
                if (node == null)
                {
                    SystemSounds.Beep.Play();
                }
                else
                {
                    // Build a label setting shortest path tree.
                    float  cost = TheNetwork.FindLabelCorrectingPathTree(node);
                    string txt  = "Total cost: " + cost.ToString();
                    toolStripStatusLabel1.Text = txt;
                    Console.WriteLine(txt);

                    // Redraw the network.
                    networkPictureBox.Refresh();
                }
            }
            else if (Mode == Modes.LabelCorrectingPath)
            {
                // See if there is a node here.
                NetworkNode node = TheNetwork.FindNode(e.Location);
                if (node == null)
                {
                    SystemSounds.Beep.Play();
                }
                else
                {
                    if (e.Button == MouseButtons.Left)
                    {
                        Node0 = node;
                    }
                    else
                    {
                        Node1 = node;
                    }

                    // See if we have both nodes.
                    if ((Node0 != null) && (Node1 != null))
                    {
                        // Find a path between the nodes.
                        List <NetworkNode> pathNodes;
                        List <NetworkLink> pathLinks;
                        int cost = TheNetwork.FindLabelCorrectingPath(Node0, Node1,
                                                                      out pathNodes, out pathLinks);

                        string txt = "Path: ";
                        foreach (NetworkNode pathNode in pathNodes)
                        {
                            txt += pathNode.Name + " ";
                        }
                        txt += "Total cost: " + cost.ToString();
                        toolStripStatusLabel1.Text = txt;
                        Console.WriteLine(txt);

                        // Redraw the network.
                        networkPictureBox.Refresh();
                    }
                }
            }
            else if (Mode == Modes.MaximalFlow)
            {
                // See if there is a node here.
                NetworkNode node = TheNetwork.FindNode(e.Location);
                if (node == null)
                {
                    SystemSounds.Beep.Play();
                }
                else
                {
                    if (e.Button == MouseButtons.Left)
                    {
                        Node0 = node;
                    }
                    else
                    {
                        Node1 = node;
                    }

                    // See if we have both nodes.
                    if ((Node0 != null) && (Node1 != null))
                    {
                        // Calculate the maximal flow.
                        int flow = TheNetwork.MaximalFlow(Node0, Node1);

                        // Redraw.
                        networkPictureBox.Refresh();

                        // Display the result.
                        string txt = "Total flow " + Node0.ToString() +
                                     "-->" + Node1.ToString() + ": " + flow;
                        Console.WriteLine(txt);
                        MessageBox.Show(txt);

                        // We're done with these nodes.
                        Node0 = null;
                        Node1 = null;
                    }
                }
            }
            else if (Mode == Modes.MinFlowCut)
            {
                // See if there is a node here.
                NetworkNode node = TheNetwork.FindNode(e.Location);
                if (node == null)
                {
                    SystemSounds.Beep.Play();
                }
                else
                {
                    if (e.Button == MouseButtons.Left)
                    {
                        Node0 = node;
                    }
                    else
                    {
                        Node1 = node;
                    }

                    // See if we have both nodes.
                    if ((Node0 != null) && (Node1 != null))
                    {
                        // Find a minimal flow cut.
                        int flow = TheNetwork.MinimalFlowCut(Node0, Node1);

                        // Redraw.
                        networkPictureBox.Refresh();

                        // Display the result.
                        string txt = "Minimal flow cut " + Node0.ToString() +
                                     "-->" + Node1.ToString() + ": " + flow;
                        Console.WriteLine(txt);
                        MessageBox.Show(txt);

                        // We're done with these nodes.
                        Node0 = null;
                        Node1 = null;
                    }
                }
            }
        }