예제 #1
0
        /// <summary>
        /// Compares this instance with a specified adjacency matrix.
        /// </summary>
        /// <param name="matrix">The specified adjacency matrix that this instantce is to be compared with.</param>
        /// <returns>
        /// Returns NULL if the two adjaceny matrices are identical.
        /// If the two adjacency matrices are different, return a List<int> containing the indexes of different vertices.
        /// </returns>
        public List <int> CompareTo(AdjacencyMatrix matrix)
        {
            bool isEqual = true;

            List <int> differentVertices = new List <int>();

            if (matrix == null)
            {
                isEqual = false;
                for (int v = 0; v < GetSize(); v++)
                {
                    if (this.IsVertexExisting(v))
                    {
                        if (!differentVertices.Contains(v))
                        {
                            differentVertices.Add(v);
                        }
                    }
                }
                differentVertices.Sort();
                return(differentVertices);
            }

            for (int v = 0; v < GetSize(); v++)
            {
                if (this.IsVertexExisting(v) != matrix.IsVertexExisting(v))
                {
                    isEqual = false;
                    if (!differentVertices.Contains(v))
                    {
                        differentVertices.Add(v);
                    }
                }
            }
            for (int row = 0; row < GetSize(); row++)
            {
                for (int col = 0; col < GetSize(); col++)
                {
                    if (!this.GetEdge(row, col).Equals(matrix.GetEdge(row, col)))
                    {
                        isEqual = false;
                        if (!differentVertices.Contains(row))
                        {
                            differentVertices.Add(row);
                        }
                    }
                }
            }
            if (isEqual)
            {
                return(null);
            }
            else
            {
                differentVertices.Sort();
                return(differentVertices);
            }
        }
예제 #2
0
        private void PanelGraph_Paint(object sender, PaintEventArgs e)
        {
            Dictionary <bool, Color> colorFocusEdge = new Dictionary <bool, Color>
            {
                { true, Color.Red },
                { false, Color.Black }
            };

            using (Graphics g = e.Graphics)
            {
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                foreach (DijkstraVertexLabel v1 in vertices)
                {
                    foreach (DijkstraVertexLabel v2 in vertices)
                    {
                        int vStart  = v1.GetNumberIndex();
                        int vFinish = v2.GetNumberIndex();
                        if (mapMatrix.ContainsEdge(vStart, vFinish))
                        {
                            int shiftX     = Convert.ToInt32(Math.Round(Math.Min(v2.Width / 2, Math.Abs(v2.Height / 2 * (v2.GetCentreLocation().X - v1.GetCentreLocation().X) / (v2.GetCentreLocation().Y - v1.GetCentreLocation().Y + 1e-10)))));
                            int shiftY     = Convert.ToInt32(Math.Round(Math.Min(v2.Height / 2, Math.Abs(v2.Width / 2 * (v2.GetCentreLocation().Y - v1.GetCentreLocation().Y) / (v2.GetCentreLocation().X - v1.GetCentreLocation().X + 1e-10)))));
                            int directionX = v2.GetCentreLocation().X > v1.GetCentreLocation().X ? 1 : -1;
                            int directionY = v2.GetCentreLocation().Y > v1.GetCentreLocation().Y ? 1 : -1;
                            if (!mapMatrix.ContainsEdge(vFinish, vStart))
                            {
                                g.DrawLine(new Pen(colorFocusEdge[edgeFocused[vStart, vFinish]], 5), v1.GetCentreLocation(), v2.GetCentreLocation());
                                Point point1 = new Point
                                               (
                                    v2.GetCentreLocation().X - directionX * shiftX,
                                    v2.GetCentreLocation().Y - directionY * shiftY
                                               );
                                Point pointBase = new Point
                                                  (
                                    Convert.ToInt32(Math.Round(point1.X - 40 * (v2.GetCentreLocation().X - v1.GetCentreLocation().X) / v1.GetDistance(v2))),
                                    Convert.ToInt32(Math.Round(point1.Y - 40 * (v2.GetCentreLocation().Y - v1.GetCentreLocation().Y) / v1.GetDistance(v2)))
                                                  );
                                Point point2 = new Point
                                               (
                                    Convert.ToInt32(Math.Round(pointBase.X + 7.5 * (v2.GetCentreLocation().Y - v1.GetCentreLocation().Y) / v1.GetDistance(v2))),
                                    Convert.ToInt32(Math.Round(pointBase.Y - 7.5 * (v2.GetCentreLocation().X - v1.GetCentreLocation().X) / v1.GetDistance(v2)))
                                               );
                                Point point3 = new Point
                                               (
                                    Convert.ToInt32(Math.Round(pointBase.X - 7.5 * (v2.GetCentreLocation().Y - v1.GetCentreLocation().Y) / v1.GetDistance(v2))),
                                    Convert.ToInt32(Math.Round(pointBase.Y + 7.5 * (v2.GetCentreLocation().X - v1.GetCentreLocation().X) / v1.GetDistance(v2)))
                                               );
                                Point[] arrow = { point1, point2, point3 };
                                g.FillPolygon(new SolidBrush(colorFocusEdge[edgeFocused[vStart, vFinish]]), arrow);
                            }
                            else if (mapMatrix.GetEdge(vStart, vFinish) != mapMatrix.GetEdge(vFinish, vStart))
                            {
                                if (vFinish > vStart)
                                {
                                    Point point1 = new Point
                                                   (
                                        v1.GetCentreLocation().X + directionX * shiftX,
                                        v1.GetCentreLocation().Y + directionY * shiftY
                                                   );
                                    Point point2 = new Point
                                                   (
                                        v2.GetCentreLocation().X - directionX * shiftX,
                                        v2.GetCentreLocation().Y - directionY * shiftY
                                                   );
                                    Point midPoint = new Point
                                                     (
                                        (v1.GetCentreLocation().X + v2.GetCentreLocation().X) / 2,
                                        (v1.GetCentreLocation().Y + v2.GetCentreLocation().Y) / 2
                                                     );
                                    Point point3 = new Point
                                                   (
                                        Convert.ToInt32(Math.Round(midPoint.X + 42 * (v2.GetCentreLocation().Y - v1.GetCentreLocation().Y) / v1.GetDistance(v2))),
                                        Convert.ToInt32(Math.Round(midPoint.Y - 42 * (v2.GetCentreLocation().X - v1.GetCentreLocation().X) / v1.GetDistance(v2)))
                                                   );
                                    Point point4 = new Point
                                                   (
                                        Convert.ToInt32(Math.Round(midPoint.X - 42 * (v2.GetCentreLocation().Y - v1.GetCentreLocation().Y) / v1.GetDistance(v2))),
                                        Convert.ToInt32(Math.Round(midPoint.Y + 42 * (v2.GetCentreLocation().X - v1.GetCentreLocation().X) / v1.GetDistance(v2)))
                                                   );
                                    Point point5 = new Point
                                                   (
                                        Convert.ToInt32(Math.Round(point2.X - 40 * (point2.X - point3.X) / Math.Sqrt((point2.X - point3.X) * (point2.X - point3.X) + (point2.Y - point3.Y) * (point2.Y - point3.Y)))),
                                        Convert.ToInt32(Math.Round(point2.Y - 40 * (point2.Y - point3.Y) / Math.Sqrt((point2.X - point3.X) * (point2.X - point3.X) + (point2.Y - point3.Y) * (point2.Y - point3.Y))))
                                                   );
                                    Point point6Reflect = new Point
                                                          (
                                        Convert.ToInt32(Math.Round(point2.X - 40 * (v2.GetCentreLocation().X - v1.GetCentreLocation().X) / v1.GetDistance(v2))),
                                        Convert.ToInt32(Math.Round(point2.Y - 40 * (v2.GetCentreLocation().Y - v1.GetCentreLocation().Y) / v1.GetDistance(v2)))
                                                          );
                                    Point point6 = new Point
                                                   (
                                        Convert.ToInt32(Math.Round(point5.X + 11 * (point5.X - point6Reflect.X) / Math.Sqrt((point5.X - point6Reflect.X) * (point5.X - point6Reflect.X) + (point5.Y - point6Reflect.Y) * (point5.Y - point6Reflect.Y)))),
                                        Convert.ToInt32(Math.Round(point5.Y + 11 * (point5.Y - point6Reflect.Y) / Math.Sqrt((point5.X - point6Reflect.X) * (point5.X - point6Reflect.X) + (point5.Y - point6Reflect.Y) * (point5.Y - point6Reflect.Y))))
                                                   );
                                    Point point7 = new Point
                                                   (
                                        Convert.ToInt32(Math.Round(point1.X - 40 * (point1.X - point4.X) / Math.Sqrt((point1.X - point4.X) * (point1.X - point4.X) + (point1.Y - point4.Y) * (point1.Y - point4.Y)))),
                                        Convert.ToInt32(Math.Round(point1.Y - 40 * (point1.Y - point4.Y) / Math.Sqrt((point1.X - point4.X) * (point1.X - point4.X) + (point1.Y - point4.Y) * (point1.Y - point4.Y))))
                                                   );
                                    Point point8Reflect = new Point
                                                          (
                                        Convert.ToInt32(Math.Round(point1.X + 40 * (v2.GetCentreLocation().X - v1.GetCentreLocation().X) / v1.GetDistance(v2))),
                                        Convert.ToInt32(Math.Round(point1.Y + 40 * (v2.GetCentreLocation().Y - v1.GetCentreLocation().Y) / v1.GetDistance(v2)))
                                                          );
                                    Point point8 = new Point
                                                   (
                                        Convert.ToInt32(Math.Round(point7.X + 11 * (point7.X - point8Reflect.X) / Math.Sqrt((point7.X - point8Reflect.X) * (point7.X - point8Reflect.X) + (point7.Y - point8Reflect.Y) * (point7.Y - point8Reflect.Y)))),
                                        Convert.ToInt32(Math.Round(point7.Y + 11 * (point7.Y - point8Reflect.Y) / Math.Sqrt((point7.X - point8Reflect.X) * (point7.X - point8Reflect.X) + (point7.Y - point8Reflect.Y) * (point7.Y - point8Reflect.Y))))
                                                   );
                                    Point[] curve1 = { point1, point3, point2 };
                                    Point[] curve2 = { point2, point4, point1 };
                                    g.DrawCurve(new Pen(colorFocusEdge[edgeFocused[vStart, vFinish]], 5), curve1);
                                    g.DrawCurve(new Pen(colorFocusEdge[edgeFocused[vFinish, vStart]], 5), curve2);
                                    Point[] arrow1 = { point2, point5, point6 };
                                    Point[] arrow2 = { point1, point7, point8 };
                                    g.FillPolygon(new SolidBrush(colorFocusEdge[edgeFocused[vStart, vFinish]]), arrow1);
                                    g.FillPolygon(new SolidBrush(colorFocusEdge[edgeFocused[vFinish, vStart]]), arrow2);
                                }
                            }
                            else
                            {
                                if (vFinish > vStart)
                                {
                                    g.DrawLine(new Pen(colorFocusEdge[edgeFocused[vStart, vFinish]], 5), v1.GetCentreLocation(), v2.GetCentreLocation());
                                }
                            }
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Show the tag window of the vertex, and all its adjacenct edge information.
 /// </summary>
 private void FormVertexTag_Load(object sender, EventArgs e)
 {
     for (int finishingVertex = 0; finishingVertex < mapMatrix.GetSize(); finishingVertex++)
     {
         int startingVertex = mapMatrix.GetVertexIndex((sender as FormVertexTag).Text.Trim("Vertex ".ToCharArray()));
         if (mapMatrix.IsVertexExisting(finishingVertex) && finishingVertex != startingVertex)
         {
             (sender as FormVertexTag).AddVertexTagControl(finishingVertex);
             if (mapMatrix.ContainsEdge(startingVertex, finishingVertex))
             {
                 (sender as FormVertexTag).edgeControls[(sender as FormVertexTag).edgeControls.Count - 1].GetCheckBoxContainsEdge().Checked = true;
                 (sender as FormVertexTag).edgeControls[(sender as FormVertexTag).edgeControls.Count - 1].GetTextBoxWeight().Text           = mapMatrix.GetEdge(startingVertex, finishingVertex).ToString();
             }
         }
     }
 }
예제 #4
0
        // Graph/Tree Traversal (Group A) is implemented here.
        private void ButtonNext_Click(object sender, EventArgs e)
        {
            if (buttonNext.Text == "Close")
            {
                this.Close();
            }
            else
            {
                // Step 1 operation
                if (currentStep == 1)
                {
                    // Highlight current step
                    label1.ForeColor     = Color.Red;
                    labelStep1.ForeColor = Color.Red;
                    label2.ForeColor     = SystemColors.ControlText;
                    labelStep2.ForeColor = SystemColors.ControlText;
                    label3.ForeColor     = SystemColors.ControlText;
                    labelStep3.ForeColor = SystemColors.ControlText;

                    // Show the headers of the list of all edges
                    labelList.Visible        = true;
                    labelEdgeLeft.Visible    = true;
                    labelWeightLeft.Visible  = true;
                    labelEdgeRight.Visible   = true;
                    labelWeightRight.Visible = true;

                    // Initialise and sort the list of all edges
                    int edgeCount = 0;
                    for (int v1 = 0; v1 < mapMatrix.GetSize() - 1; v1++)
                    {
                        for (int v2 = v1 + 1; v2 < mapMatrix.GetSize(); v2++)
                        {
                            if (mapMatrix.ContainsEdge(v1, v2))
                            {
                                edgeCount++;
                                edgeList.Add(new Edge
                                {
                                    vStart  = v1,
                                    vFinish = v2,
                                    weight  = mapMatrix.GetEdge(v1, v2)
                                });
                            }
                        }
                    }
                    edgeCount /= 2;
                    QuickSort(edgeList, 0, edgeList.Count - 1);

                    // Show the list of all edges
                    Point[] originalLocations = new Point[2];
                    originalLocations[0] = new Point(24, 332);
                    originalLocations[1] = new Point(originalLocations[0].X + 228, originalLocations[0].Y);
                    for (int i = 0; i < edgeList.Count; i++)
                    {
                        Point location = new Point(originalLocations[i / edgeCount].X, originalLocations[i / edgeCount].Y + 44 * (i % edgeCount));
                        labelEdges.Add(new Label()
                        {
                            AutoSize    = true,
                            Font        = new Font("Microsoft YaHei", 12F, FontStyle.Bold, GraphicsUnit.Point, ((byte)(134))),
                            Location    = location,
                            MinimumSize = new Size(100, 44),
                            Name        = "labelEdge" + i.ToString(),
                            Size        = new Size(100, 44),
                            Text        = Convert.ToChar(edgeList[i].vStart + 'A').ToString() + Convert.ToChar(edgeList[i].vFinish + 'A').ToString(),
                            TextAlign   = ContentAlignment.TopCenter
                        });
                        labelEdges[i].Click += new EventHandler(LabelEdge_Click);
                        labelWeights.Add(new Label()
                        {
                            AutoSize    = true,
                            Font        = new Font("Microsoft YaHei", 12F, FontStyle.Bold, GraphicsUnit.Point, ((byte)(134))),
                            Location    = new Point(location.X + 100, location.Y),
                            MinimumSize = new Size(100, 44),
                            Name        = "labelWeight" + i.ToString(),
                            Size        = new Size(100, 44),
                            Text        = edgeList[i].weight.ToString(),
                            TextAlign   = ContentAlignment.TopCenter
                        });
                        labelWeights[i].Click += new EventHandler(LabelEdge_Click);
                        labelEdgeUsed.Add(new Label()
                        {
                            AutoSize    = true,
                            Font        = new Font("Microsoft YaHei", 12F, FontStyle.Bold, GraphicsUnit.Point, ((byte)(134))),
                            Location    = new Point(location.X + 200, location.Y),
                            MinimumSize = new Size(0, 22),
                            Name        = "labelEdgeUsed" + i.ToString(),
                            Size        = new Size(22, 22),
                            Text        = "×",
                            TextAlign   = ContentAlignment.TopCenter,
                            Visible     = false
                        });
                        this.Controls.Add(labelEdges[i]);
                        this.Controls.Add(labelWeights[i]);
                        this.Controls.Add(labelEdgeUsed[i]);
                    }
                    currentEdgeIndex = 0;
                    currentWeight    = edgeList[0].weight;
                    currentStep      = 2;
                }

                // Step 2 operations
                else if (currentStep == 2)
                {
                    // Highlight current step
                    label1.ForeColor     = SystemColors.ControlText;
                    labelStep1.ForeColor = SystemColors.ControlText;
                    label2.ForeColor     = Color.Red;
                    labelStep2.ForeColor = Color.Red;
                    label3.ForeColor     = SystemColors.ControlText;
                    labelStep3.ForeColor = SystemColors.ControlText;
                    foreach (Label label in labelEdges)
                    {
                        label.ForeColor = SystemColors.ControlText;
                    }
                    foreach (Label label in labelWeights)
                    {
                        label.ForeColor = SystemColors.ControlText;
                    }
                    labelEdges[currentEdgeIndex].ForeColor   = Color.Red;
                    labelWeights[currentEdgeIndex].ForeColor = Color.Red;

                    // Initialise text explanation label
                    labelInformation.Text    = "";
                    labelInformation.Visible = true;

                    // Perform Kruskal's algorithm
                    if (Find(edgeList[currentEdgeIndex].vStart).GetLeader() == Find(edgeList[currentEdgeIndex].vFinish).GetLeader()) // Reject edges forming a cycle
                    {
                        labelInformation.Text = "Adding edge " + labelEdges[currentEdgeIndex].Text + " will form a cycle, therefore edge " + labelEdges[currentEdgeIndex].Text + " should not be chosen.";
                        labelEdgeUsed[currentEdgeIndex].Text      = "×";
                        labelEdgeUsed[currentEdgeIndex].ForeColor = Color.Red;
                        labelEdgeUsed[currentEdgeIndex].Visible   = true;
                        labelEdges[currentEdgeIndex].Font         = new Font("Microsoft YaHei", 12F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Strikeout))), System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                        labelWeights[currentEdgeIndex].Font       = new Font("Microsoft YaHei", 12F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Strikeout))), System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                        do
                        {
                            currentEdgeIndex++;
                        } while (labelEdgeUsed[currentEdgeIndex].Visible);
                        currentWeight = edgeList[currentEdgeIndex].weight;
                        currentStep   = 2;
                    }
                    else
                    {
                        int         i            = currentEdgeIndex + 1;
                        List <Edge> tempEdgeList = new List <Edge>
                        {
                            edgeList[currentEdgeIndex]
                        };
                        while (edgeList[i].weight == currentWeight && !labelEdgeUsed[i].Visible)
                        {
                            if (Find(edgeList[i].vStart).GetLeader() != Find(edgeList[i].vFinish).GetLeader()) // Highlight feasible candidate edges
                            {
                                labelEdges[i].ForeColor   = Color.Red;
                                labelWeights[i].ForeColor = Color.Red;
                                tempEdgeList.Add(edgeList[i]);
                            }
                            else // Reject edges forming a cycle
                            {
                                labelInformation.Text     += "Adding edge " + labelEdges[i].Text + " will form a cycle, therefore edge " + labelEdges[i].Text + " should not be chosen.\n";
                                labelEdgeUsed[i].Text      = "×";
                                labelEdgeUsed[i].ForeColor = Color.Red;
                                labelEdgeUsed[i].Visible   = true;
                                labelEdges[i].Font         = new Font("Microsoft YaHei", 12F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Strikeout))), System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                                labelWeights[i].Font       = new Font("Microsoft YaHei", 12F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Strikeout))), System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                            }
                            i++;
                        }
                        if (tempEdgeList.Count >= 2) // More than two candidate edges - user operation required
                        {
                            labelInformation.Text += "Edges ";
                            foreach (Edge edge in tempEdgeList)
                            {
                                labelInformation.Text += Convert.ToChar(edge.vStart + 'A').ToString() + Convert.ToChar(edge.vFinish + 'A').ToString() + ", ";
                            }
                            labelInformation.Text  = labelInformation.Text.TrimEnd(", ".ToCharArray());
                            labelInformation.Text += " have the same weight. Please pick one of your choice.\n"
                                                     + "Please click on the edge in the list (NOT on the graph).";
                            currentStep        = 2;
                            buttonNext.Enabled = false;
                        }
                        else // One candidate edge only
                        {
                            labelInformation.Text += "Edge " + labelEdges[currentEdgeIndex].Text + " has been added to the Minimum Spanning Tree.";
                            labelEdgeUsed[currentEdgeIndex].Text      = "√";
                            labelEdgeUsed[currentEdgeIndex].ForeColor = Color.Green;
                            labelEdgeUsed[currentEdgeIndex].Visible   = true;
                            EdgeFocusOn(edgeList[currentEdgeIndex].vStart, edgeList[currentEdgeIndex].vFinish);
                            exampleGraph.LabelFocusOn(edgeList[currentEdgeIndex].vStart, edgeList[currentEdgeIndex].vFinish);
                            treeEdgeCount++;
                            weightMST += currentWeight;
                            Union(Find(edgeList[currentEdgeIndex].vStart).GetLeader(), Find(edgeList[currentEdgeIndex].vFinish).GetLeader());
                            currentEdgeIndex = i;
                            while (labelEdgeUsed[currentEdgeIndex].Visible)
                            {
                                currentEdgeIndex++;
                            }
                            currentWeight = edgeList[currentEdgeIndex].weight;
                            currentStep   = 3;
                        }
                    }
                }

                // Step 3 operation
                else // if (currentStep == 3)
                {
                    // Highlight current step
                    label1.ForeColor     = SystemColors.ControlText;
                    labelStep1.ForeColor = SystemColors.ControlText;
                    label2.ForeColor     = SystemColors.ControlText;
                    labelStep2.ForeColor = SystemColors.ControlText;
                    label3.ForeColor     = Color.Red;
                    labelStep3.ForeColor = Color.Red;
                    foreach (Label label in labelEdges)
                    {
                        label.ForeColor = SystemColors.ControlText;
                    }
                    foreach (Label label in labelWeights)
                    {
                        label.ForeColor = SystemColors.ControlText;
                    }

                    // Initialise text explanation label
                    labelInformation.Text    = "";
                    labelInformation.Visible = true;

                    // Check if the algorithm is finished
                    if (treeEdgeCount < mapMatrix.Count() - 1)
                    {
                        labelInformation.Text = "We have not yet formed a Minimum Spanning Tree, so go back to STEP 2.";
                        currentStep           = 2;
                    }
                    else
                    {
                        labelInformation.Text = "Now we have picked " + (mapMatrix.Count() - 1).ToString() + " edges and has formed a Minimum Spanning Tree.\nTherefore Kruskal's algorithm has finished.";
                        for (int i = 0; i < edgeList.Count; i++)
                        {
                            if (labelEdgeUsed[i].Text == "√")
                            {
                                labelTotalWeight.Text += labelWeights[i].Text + " + ";
                            }
                        }
                        labelTotalWeight.Text    = labelTotalWeight.Text.TrimEnd(" + ".ToCharArray());
                        labelTotalWeight.Text   += " = " + weightMST.ToString();
                        labelTotalWeight.Visible = true;
                        buttonNext.Text          = "Close";
                    }
                }
            }
        }
예제 #5
0
        // Graph/Tree Traversal (Group A) is implemented here.
        private void ButtonNext_Click(object sender, EventArgs e)
        {
            if (buttonNext.Text == "Close")
            {
                this.Close();
            }
            else
            {
                labelInformation.Visible = true;

                // Step 1 operation
                if (currentStep == 1)
                {
                    // Highlight current step
                    label1.ForeColor     = Color.Red;
                    labelStep1.ForeColor = Color.Red;
                    label2.ForeColor     = SystemColors.ControlText;
                    labelStep2.ForeColor = SystemColors.ControlText;
                    label3.ForeColor     = SystemColors.ControlText;
                    labelStep3.ForeColor = SystemColors.ControlText;

                    // Initialise Prim's algorithm
                    for (int i = 0; i < mapMatrix.GetSize(); i++)
                    {
                        if (mapMatrix.IsVertexExisting(i))
                        {
                            remainingVertices.Add(i);
                        }
                    }
                    labelInformation.Text = "Please pick a vertex of your choice:\nPlease click on the vertex of the graph.";
                    buttonNext.Enabled    = false;
                }

                // Step 2 operation
                else if (currentStep == 2)
                {
                    // Highlight current step
                    label1.ForeColor     = SystemColors.ControlText;
                    labelStep1.ForeColor = SystemColors.ControlText;
                    label2.ForeColor     = Color.Red;
                    labelStep2.ForeColor = Color.Red;
                    label3.ForeColor     = SystemColors.ControlText;
                    labelStep3.ForeColor = SystemColors.ControlText;

                    // Find minimum value of edge weight and candidate edges
                    double       min            = Double.MaxValue;
                    List <int[]> candidateEdges = new List <int[]>();

                    foreach (int i in visitedVertices)
                    {
                        foreach (int j in remainingVertices)
                        {
                            if (mapMatrix.ContainsEdge(i, j) && mapMatrix.GetEdge(i, j) < min) // Find minimum value of edge weight
                            {
                                min = mapMatrix.GetEdge(i, j);
                            }
                        }
                    }

                    foreach (int i in visitedVertices)
                    {
                        foreach (int j in remainingVertices)
                        {
                            if (mapMatrix.ContainsEdge(i, j) && mapMatrix.GetEdge(i, j) == min) // Find candidate edges
                            {
                                candidateEdges.Add(new int[2] {
                                    i, j
                                });
                            }
                        }
                    }

                    // More than two candidate edges - User operation required
                    if (candidateEdges.Count >= 2)
                    {
                        // Show explanation
                        labelInformation.Text = "Edges ";
                        foreach (int[] edge in candidateEdges)
                        {
                            labelInformation.Text += Convert.ToChar(edge[0] + 'A').ToString() + Convert.ToChar(edge[1] + 'A').ToString() + ", ";
                        }
                        labelInformation.Text  = labelInformation.Text.TrimEnd(", ".ToCharArray());
                        labelInformation.Text += " have the same weight (" + min.ToString() + "). Please pick one of your choice:\n"
                                                 + "Please click on the vertex or the weight.";

                        // Highlight candidate edges
                        for (int i = 0; i < candidateEdges.Count; i++)
                        {
                            int    v1        = Math.Min(candidateEdges[i][0], candidateEdges[i][1]);
                            int    v2        = Math.Max(candidateEdges[i][0], candidateEdges[i][1]);
                            string labelName = "label" + Convert.ToChar(v1 + 'A').ToString() + Convert.ToChar(v2 + 'A').ToString();
                            foreach (Label label in exampleGraph.labelWeights)
                            {
                                if (label.Name == labelName)
                                {
                                    label.ForeColor = Color.Red;
                                    break;
                                }
                            }
                            foreach (Vertex vertex in vertices)
                            {
                                if (vertex.GetNumberIndex() == candidateEdges[i][1])
                                {
                                    vertex.labelName.ForeColor = Color.Red;
                                    break;
                                }
                            }
                        }

                        currentStep        = 2;
                        buttonNext.Enabled = false;
                    }

                    // Only one candidate edge avaliable - No user operation needed
                    else
                    {
                        // Show explanation
                        int[] newEdge = new int[2] {
                            candidateEdges[0][0], candidateEdges[0][1]
                        };
                        labelInformation.Text = "Edge " + Convert.ToChar(candidateEdges[0][0] + 'A').ToString() + Convert.ToChar(candidateEdges[0][1] + 'A').ToString()
                                                + " has the minimum weight joining a vertex already included to a vertex not already included (" + min.ToString() + "),"
                                                + " therefore it has been added to the Minimum Spanning Tree.";

                        // Update Prim's algorithm
                        foreach (Vertex vertex in vertices)
                        {
                            if (vertex.GetNumberIndex() == newEdge[1])
                            {
                                weightMST             += min;
                                labelTotalWeight.Text += min.ToString() + " + ";
                                visitedVertices.Add(newEdge[1]);
                                remainingVertices.Remove(newEdge[1]);
                                EdgeFocusOn(newEdge[0], newEdge[1]);
                                exampleGraph.LabelFocusOn(newEdge[0], newEdge[1]);
                                currentStep = 3;
                                break;
                            }
                        }
                    }
                }

                // Step 3 operation
                else // if (currentStep == 3)
                {
                    // Highlight current steps
                    label1.ForeColor     = SystemColors.ControlText;
                    labelStep1.ForeColor = SystemColors.ControlText;
                    label2.ForeColor     = SystemColors.ControlText;
                    labelStep2.ForeColor = SystemColors.ControlText;
                    label3.ForeColor     = Color.Red;
                    labelStep3.ForeColor = Color.Red;

                    // Check if Prim's algorithm has finished
                    if (remainingVertices.Any())
                    {
                        labelInformation.Text = "We have not yet formed a Minimum Spanning Tree, so go back to STEP 2.";
                        currentStep           = 2;
                    }
                    else
                    {
                        labelInformation.Text    = "Now we have picked " + (mapMatrix.Count() - 1).ToString() + " edges and has formed a Minimum Spanning Tree.\nTherefore Prim's algorithm has finished.";
                        labelTotalWeight.Text    = labelTotalWeight.Text.TrimEnd(" + ".ToCharArray());
                        labelTotalWeight.Text   += " = " + weightMST.ToString();
                        labelTotalWeight.Visible = true;
                        buttonNext.Text          = "Close";
                    }
                }
            }
        }
예제 #6
0
        public FormPrimOnMatrix(int accountID, string username, string accountName, string accountType, int example)
        {
            InitializeComponent();

            // Show account name on the account menu.
            this.accountMenu.accountID             = accountID;
            this.accountMenu.username              = username;
            this.accountMenu.labelAccountName.Text = accountName;
            this.accountMenu.accountType           = accountType;
            this.example = example;

            // Select the correct example graph to perform the demonstration.
            if (example == 1)
            {
                exampleGraph = new MinimumSpanningTreeExample1(this.panelGraph);
            }
            else
            {
                exampleGraph = new MinimumSpanningTreeExample2(this.panelGraph);
            }

            // Initialise the example graph.
            vertices  = exampleGraph.GetVertices();
            mapMatrix = exampleGraph.GetMatrix();

            // Initialise the table for the example graph.
            for (int i = 0; i <= mapMatrix.Count(); i++)
            {
                DataGridViewColumn newColumn = new DataGridViewColumn
                {
                    CellTemplate = new DataGridViewTextBoxCell(),
                    SortMode     = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable,
                    Width        = 60
                };
                if (i == 0)
                {
                    newColumn.Width = 41;
                }
                dataGridViewGraph.Columns.Add(newColumn);
            }

            int count = 1;

            for (int i = 0; i < mapMatrix.GetSize(); i++)
            {
                if (mapMatrix.IsVertexExisting(i))
                {
                    dataGridViewGraph.Columns[count].HeaderText = Convert.ToChar('A' + i).ToString();
                    dataGridViewGraph.Columns[count].Name       = "Column" + dataGridViewGraph.Columns[count].HeaderText;
                    count++;
                }
            }

            count = 0;
            this.dataGridViewGraph.RowCount = mapMatrix.Count();
            for (int i = 0; i < mapMatrix.GetSize(); i++)
            {
                if (mapMatrix.IsVertexExisting(i))
                {
                    this.dataGridViewGraph[0, count++].Value = (Convert.ToChar('A' + i)).ToString();
                }
            }

            for (int col = 1; col <= mapMatrix.Count(); col++)
            {
                for (int row = 0; row < mapMatrix.Count(); row++)
                {
                    int vStartIndex  = mapMatrix.GetVertexIndex(dataGridViewGraph.Columns[col].HeaderText);
                    int vFinishIndex = mapMatrix.GetVertexIndex(this.dataGridViewGraph[0, row].Value.ToString());
                    if (mapMatrix.ContainsEdge(vStartIndex, vFinishIndex))
                    {
                        this.dataGridViewGraph[col, row].Value = mapMatrix.GetEdge(vStartIndex, vFinishIndex);
                    }
                    else
                    {
                        this.dataGridViewGraph[col, row].Value = "-";
                    }
                }
            }
        }
예제 #7
0
        // Graph/Tree Traversal (Group A) is implemented here.
        private void ButtonNext_Click(object sender, EventArgs e)
        {
            if (buttonNext.Text == "Close")
            {
                this.Close();
            }
            else
            {
                labelInformation.Visible = true;
                double min;

                // Step 1 operation
                if (currentStep == 1)
                {
                    // Highlight current step
                    label1.ForeColor     = Color.Red;
                    labelStep1.ForeColor = Color.Red;
                    label2.ForeColor     = SystemColors.ControlText;
                    labelStep2.ForeColor = SystemColors.ControlText;
                    label3.ForeColor     = SystemColors.ControlText;
                    labelStep3.ForeColor = SystemColors.ControlText;
                    label4.ForeColor     = SystemColors.ControlText;
                    labelStep4.ForeColor = SystemColors.ControlText;
                    label5.ForeColor     = SystemColors.ControlText;
                    labelStep5.ForeColor = SystemColors.ControlText;

                    // Initialise Prim's algorithm
                    for (int i = 0; i < mapMatrix.GetSize(); i++)
                    {
                        if (mapMatrix.IsVertexExisting(i))
                        {
                            remainingVertices.Add(i);
                        }
                    }
                    labelInformation.Text = "Please pick a vertex of your choice:\nPlease click on the headers of the tableau.";
                    buttonNext.Enabled    = false;
                }

                // Step 2 operation
                else if (currentStep == 2)
                {
                    // Highlight current step
                    label1.ForeColor     = SystemColors.ControlText;
                    labelStep1.ForeColor = SystemColors.ControlText;
                    label2.ForeColor     = Color.Red;
                    labelStep2.ForeColor = Color.Red;
                    label3.ForeColor     = SystemColors.ControlText;
                    labelStep3.ForeColor = SystemColors.ControlText;
                    label4.ForeColor     = SystemColors.ControlText;
                    labelStep4.ForeColor = SystemColors.ControlText;
                    label5.ForeColor     = SystemColors.ControlText;
                    labelStep5.ForeColor = SystemColors.ControlText;

                    // Find minimum value of edge weight and candidate edges
                    min = double.MaxValue;
                    candidateEdges.Clear();

                    foreach (int i in visitedVertices)
                    {
                        foreach (int j in remainingVertices)
                        {
                            if (mapMatrix.ContainsEdge(i, j) && mapMatrix.GetEdge(i, j) < min) // Find minimum value of edge weight
                            {
                                min = mapMatrix.GetEdge(i, j);
                            }
                        }
                    }

                    foreach (int i in visitedVertices)
                    {
                        foreach (int j in remainingVertices)
                        {
                            if (mapMatrix.ContainsEdge(i, j) && mapMatrix.GetEdge(i, j) == min) // Find candidate edges
                            {
                                candidateEdges.Add(new int[2] {
                                    i, j
                                });
                            }
                        }
                    }

                    // Show candidate edges on the table
                    for (int i = 0; i < candidateEdges.Count; i++)
                    {
                        char v1 = Convert.ToChar(candidateEdges[i][0] + 'A');
                        char v2 = Convert.ToChar(candidateEdges[i][1] + 'A');
                        for (int col = 1; col < dataGridViewGraph.ColumnCount; col++)
                        {
                            if (dataGridViewGraph.Columns[col].HeaderText[0] == v1)
                            {
                                for (int row = 0; row < dataGridViewGraph.RowCount; row++)
                                {
                                    if (dataGridViewGraph[0, row].Value.ToString() == v2.ToString())
                                    {
                                        dataGridViewGraph[col, row].Style.ForeColor          = Color.Red;
                                        dataGridViewGraph[col, row].Style.SelectionForeColor = Color.Red;
                                    }
                                }
                            }
                        }
                    }

                    // More than two candidate edges - User operation required
                    if (candidateEdges.Count >= 2)
                    {
                        labelInformation.Text = "Edges ";
                        foreach (int[] edge in candidateEdges)
                        {
                            labelInformation.Text += Convert.ToChar(edge[0] + 'A').ToString() + Convert.ToChar(edge[1] + 'A').ToString() + ", ";
                        }
                        labelInformation.Text  = labelInformation.Text.TrimEnd(", ".ToCharArray());
                        labelInformation.Text += " have the same weight (" + min.ToString() + "). Please pick one of your choice:\n"
                                                 + "Please click on the weights in the tableau.";
                        currentStep        = 2;
                        buttonNext.Enabled = false;
                    }

                    // Only one candidate edge avaliable - No user operation needed
                    else if (candidateEdges.Count == 1)
                    {
                        newEdge = new int[2] {
                            candidateEdges[0][0], candidateEdges[0][1]
                        };
                        labelInformation.Text = "Edge " + Convert.ToChar(candidateEdges[0][0] + 'A').ToString() + Convert.ToChar(candidateEdges[0][1] + 'A').ToString()
                                                + " has the minimum weight from the uncircled entries in the marked column(s) (" + min.ToString() + "),"
                                                + " therefore it has been chosen.";
                        currentStep = 3;
                    }

                    // No candidate edge found - Algorithm about to finish
                    else
                    {
                        labelInformation.Text = "";
                        currentStep           = 3;
                    }
                }

                // Step 3 operation
                else if (currentStep == 3)
                {
                    // Highlight current step
                    label1.ForeColor     = SystemColors.ControlText;
                    labelStep1.ForeColor = SystemColors.ControlText;
                    label2.ForeColor     = SystemColors.ControlText;
                    labelStep2.ForeColor = SystemColors.ControlText;
                    label3.ForeColor     = Color.Red;
                    labelStep3.ForeColor = Color.Red;
                    label4.ForeColor     = SystemColors.ControlText;
                    labelStep4.ForeColor = SystemColors.ControlText;
                    label5.ForeColor     = SystemColors.ControlText;
                    labelStep5.ForeColor = SystemColors.ControlText;

                    // Check if Prim's algorithm has finished
                    if (candidateEdges.Count == 0)
                    {
                        labelInformation.Text = "There is no available entry to be chosen, and therefore Prim's algorithm has finished.\n"
                                                + "We have found a Minimum Spanning Tree.";
                        labelTotalWeight.Text    = labelTotalWeight.Text.TrimEnd(" + ".ToCharArray());
                        labelTotalWeight.Text   += " = " + weightMST.ToString();
                        labelTotalWeight.Visible = true;
                        buttonNext.Text          = "Close";
                    }
                    else
                    {
                        labelInformation.Text += "\nNow that we have found an entry, we should go to STEP 4.";
                        currentStep            = 4;
                    }
                }

                // Step 4 operation
                else if (currentStep == 4)
                {
                    // Highlight current step
                    label1.ForeColor     = SystemColors.ControlText;
                    labelStep1.ForeColor = SystemColors.ControlText;
                    label2.ForeColor     = SystemColors.ControlText;
                    labelStep2.ForeColor = SystemColors.ControlText;
                    label3.ForeColor     = SystemColors.ControlText;
                    labelStep3.ForeColor = SystemColors.ControlText;
                    label4.ForeColor     = Color.Red;
                    labelStep4.ForeColor = Color.Red;
                    label5.ForeColor     = SystemColors.ControlText;
                    labelStep5.ForeColor = SystemColors.ControlText;

                    // Update Prim's algorithm and show demonstration
                    labelInformation.Text = "";

                    weightMST             += mapMatrix.GetEdge(newEdge[0], newEdge[1]);
                    labelTotalWeight.Text += mapMatrix.GetEdge(newEdge[0], newEdge[1]).ToString() + " + ";
                    visitedVertices.Add(newEdge[1]);
                    remainingVertices.Remove(newEdge[1]);
                    EdgeFocusOn(newEdge[0], newEdge[1]);
                    exampleGraph.LabelFocusOn(newEdge[0], newEdge[1]);

                    char v1 = Convert.ToChar(newEdge[0] + 'A');
                    char v2 = Convert.ToChar(newEdge[1] + 'A');
                    for (int col = 1; col < dataGridViewGraph.ColumnCount; col++)
                    {
                        for (int row = 0; row < dataGridViewGraph.RowCount; row++)
                        {
                            if (dataGridViewGraph.Columns[col].HeaderText[0] == v1 && dataGridViewGraph[0, row].Value.ToString() == v2.ToString())
                            {
                                dataGridViewGraph.Columns[row + 1].HeaderCell.Style.ForeColor          = Color.Red;
                                dataGridViewGraph.Columns[row + 1].HeaderCell.Style.SelectionForeColor = Color.Red;
                                dataGridViewGraph.Columns[row + 1].HeaderCell.Value = dataGridViewGraph.Columns[row + 1].HeaderCell.Value.ToString() + " " + visitedVertices.Count.ToString();
                                dataGridViewGraph[col, row].Style.Font               = boldFont;
                                dataGridViewGraph[col, row].Style.ForeColor          = Color.Red;
                                dataGridViewGraph[col, row].Style.SelectionForeColor = Color.Red;
                            }
                            else if (dataGridViewGraph[col, row].Style.Font != boldFont)
                            {
                                dataGridViewGraph[col, row].Style.ForeColor          = SystemColors.ControlText;
                                dataGridViewGraph[col, row].Style.SelectionForeColor = SystemColors.ControlText;
                                if (visitedVertices.Contains(Convert.ToInt32(Convert.ToChar(dataGridViewGraph[0, row].Value) - 'A')))
                                {
                                    dataGridViewGraph[col, row].Style.Font = strikeoutFont;
                                }
                            }
                        }
                    }

                    currentStep = 5;
                }

                // Step 5 operation
                else // if (currentStep == 5)
                {
                    // Highlight current step
                    label1.ForeColor     = SystemColors.ControlText;
                    labelStep1.ForeColor = SystemColors.ControlText;
                    label2.ForeColor     = SystemColors.ControlText;
                    labelStep2.ForeColor = SystemColors.ControlText;
                    label3.ForeColor     = SystemColors.ControlText;
                    labelStep3.ForeColor = SystemColors.ControlText;
                    label4.ForeColor     = SystemColors.ControlText;
                    labelStep4.ForeColor = SystemColors.ControlText;
                    label5.ForeColor     = Color.Red;
                    labelStep5.ForeColor = Color.Red;

                    // Refresh and go to Step 2
                    labelInformation.Text = "";
                    currentStep           = 2;
                }
            }
        }
 /// <summary>
 /// Shows the edge weight on the label.
 /// </summary>
 public void DrawLabelWeights()
 {
     for (int v1 = 0; v1 < mapMatrix.GetSize(); v1++)
     {
         for (int v2 = 0; v2 < mapMatrix.GetSize(); v2++)
         {
             labelWeights[v1, v2].Enabled = mapMatrix.ContainsEdge(v1, v2);
             labelWeights[v1, v2].Visible = mapMatrix.ContainsEdge(v1, v2);
         }
     }
     foreach (DijkstraVertexLabel v1 in vertices)
     {
         foreach (DijkstraVertexLabel v2 in vertices)
         {
             int vStart  = v1.GetNumberIndex();
             int vFinish = v2.GetNumberIndex();
             if (mapMatrix.ContainsEdge(vStart, vFinish))
             {
                 if (mapMatrix.ContainsEdge(vFinish, vStart) && mapMatrix.GetEdge(vStart, vFinish) != mapMatrix.GetEdge(vFinish, vStart))
                 {
                     if (vFinish > vStart)
                     {
                         Point midPoint = new Point
                                          (
                             (v1.GetCentreLocation().X + v2.GetCentreLocation().X) / 2,
                             (v1.GetCentreLocation().Y + v2.GetCentreLocation().Y) / 2
                                          );
                         Point pointForward = new Point
                                              (
                             Convert.ToInt32(Math.Round(midPoint.X + 42 * (v2.GetCentreLocation().Y - v1.GetCentreLocation().Y) / v1.GetDistance(v2))),
                             Convert.ToInt32(Math.Round(midPoint.Y - 42 * (v2.GetCentreLocation().X - v1.GetCentreLocation().X) / v1.GetDistance(v2)))
                                              );
                         Point pointBackward = new Point
                                               (
                             Convert.ToInt32(Math.Round(midPoint.X - 42 * (v2.GetCentreLocation().Y - v1.GetCentreLocation().Y) / v1.GetDistance(v2))),
                             Convert.ToInt32(Math.Round(midPoint.Y + 42 * (v2.GetCentreLocation().X - v1.GetCentreLocation().X) / v1.GetDistance(v2)))
                                               );
                         labelWeights[vStart, vFinish].Location = new Point
                                                                  (
                             pointForward.X - labelWeights[vStart, vFinish].Width,
                             pointForward.Y - labelWeights[vStart, vFinish].Height
                                                                  );
                         labelWeights[vStart, vFinish].Text     = mapMatrix.GetEdge(vStart, vFinish).ToString();
                         labelWeights[vFinish, vStart].Location = new Point
                                                                  (
                             pointBackward.X - labelWeights[vFinish, vStart].Width,
                             pointBackward.Y - labelWeights[vFinish, vStart].Height
                                                                  );
                         labelWeights[vFinish, vStart].Text = mapMatrix.GetEdge(vFinish, vStart).ToString();
                     }
                 }
                 else if (labelWeights[vStart, vFinish].Enabled)
                 {
                     Point midPoint = new Point
                                      (
                         (v1.GetCentreLocation().X + v2.GetCentreLocation().X) / 2,
                         (v1.GetCentreLocation().Y + v2.GetCentreLocation().Y) / 2
                                      );
                     labelWeights[vStart, vFinish].Location = new Point
                                                              (
                         midPoint.X - labelWeights[vStart, vFinish].Width,
                         midPoint.Y - labelWeights[vStart, vFinish].Height
                                                              );
                     labelWeights[vStart, vFinish].Text    = mapMatrix.GetEdge(vStart, vFinish).ToString();
                     labelWeights[vFinish, vStart].Enabled = false;
                     labelWeights[vFinish, vStart].Visible = false;
                 }
             }
         }
     }
 }