Click here to Skip to main content
15,891,864 members
Articles / Multimedia / GDI+

Kruskal Algorithm

Rate me:
Please Sign up or sign in to vote.
4.84/5 (47 votes)
5 Jul 2012CPOL2 min read 183.8K   11.6K   70  
Implementation of Kruskal Algorithm in C#
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace Kruskal
{
    public partial class frmMain : Form
    {

        #region Member Variables

        const int _radius = 20;
        const int _halfRadius = (_radius / 2);

        Color _vertexColor = Color.Aqua;
        Color _edgeColor = Color.Red;

        IList<Vertex> _vertices;
        IList<Edge> _graph, _graphSolved;

        Vertex _firstVertex, _secondVertex;

        bool _drawEdge, _solved;

        #endregion

        public frmMain()
        {
            InitializeComponent();
            Clear();
        }

        #region Events

        private void panel1_MouseClick(object sender, MouseEventArgs e)
        {
            Point clicked = new Point(e.X - _halfRadius, e.Y - _halfRadius);
            if (Control.ModifierKeys == Keys.Control)//if Ctrl is pressed
            {
                if (!_drawEdge)
                {
                    _firstVertex = GetSelectedVertex(clicked);
                    _drawEdge = true;
                }
                else
                {
                    _secondVertex = GetSelectedVertex(clicked);
                    _drawEdge = false;
                    if (_firstVertex != null && _secondVertex != null && _firstVertex.Name != _secondVertex.Name)
                    {
                        frmCost formCost = new frmCost();
                        formCost.ShowDialog();

                        Point stringPoint = GetStringPoint(_firstVertex.Position, _secondVertex.Position);
                        _graph.Add(new Edge(_firstVertex, _secondVertex, formCost._cost, stringPoint));
                        panel1.Invalidate();
                    }
                }
            }
            else
            {
                _vertices.Add(new Vertex(_vertices.Count, clicked));
                panel1.Invalidate();
            }
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            DrawVertices(g);
            DrawEdges(g);
            g.Dispose();
        }

        private void btnSolve_Click(object sender, EventArgs e)
        {
            if (_vertices.Count > 2)
            {
                if (_graph.Count < _vertices.Count - 1)
                {
                    MessageBox.Show("Missing Edges", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
                else
                {
                    btnSolve.Enabled = false;
                    IKruskal kruskal = new Kruskal();
                    int totalCost;
                    _graphSolved = kruskal.Solve(_graph, out totalCost);
                    _solved = true;
                    panel1.Invalidate();
                    MessageBox.Show("Total Cost: " + totalCost.ToString(), "Solution", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            DialogResult dr = MessageBox.Show("Clear form ?", "Alert", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
            if (dr == DialogResult.Yes)
            {
                btnSolve.Enabled = true;
                Graphics g = panel1.CreateGraphics();
                g.Clear(panel1.BackColor);
                Clear();
            }
        }

        #endregion

        #region Private Methods

        private void DrawEdges(Graphics g)
        {
            Pen p = new Pen(_edgeColor);
            var edges = _solved ? _graphSolved : _graph;

            foreach (Edge e in edges)
            {
                Point v1 = new Point(e.V1.Position.X + _halfRadius, e.V1.Position.Y + _halfRadius);
                Point v2 = new Point(e.V2.Position.X + _halfRadius, e.V2.Position.Y + _halfRadius);
                g.DrawLine(p, v1, v2);
                DrawString(e.Cost.ToString(), e.StringPosition, g);
            }
        }

        private void DrawString(string strText, Point pDrawPoint, Graphics g)
        {
            Font drawFont = new Font("Arial", 15);
            SolidBrush drawBrush = new SolidBrush(Color.Black);
            g.DrawString(strText, drawFont, drawBrush, pDrawPoint);
        }

        private void DrawVertices(Graphics g)
        {
            Pen p = new Pen(_vertexColor);
            Brush b = new SolidBrush(_vertexColor);
            foreach (Vertex v in _vertices)
            {
                g.DrawEllipse(p, v.Position.X, v.Position.Y, _radius, _radius);
                g.FillEllipse(b, v.Position.X, v.Position.Y, _radius, _radius);
                DrawString(v.Name.ToString(), v.Position, g);
            }
        }

        private Vertex GetSelectedVertex(Point pClicked)
        {
            foreach (Vertex v in _vertices)
            {
                var distance = GetDistance(v.Position, pClicked);
                if (distance <= _radius)
                {
                    return v;
                }
            }
            return null;
        }

        private double GetDistance(Point start, Point end)
        {
            return Math.Sqrt(Math.Pow(start.X - end.X, 2) + Math.Pow(start.Y - end.Y, 2));
        }

        private Point GetStringPoint(Point start, Point end)
        {
            int X = (start.X + end.X) / 2;
            int Y = (start.Y + end.Y) / 2;
            return new Point(X, Y);
        }

        private void Clear()
        {
            _vertices = new List<Vertex>();
            _graph = new List<Edge>();
            _solved = false;
            _firstVertex = _secondVertex = null;
        }

        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Egypt Egypt
Enthusiastic programmer/researcher, passionate to learn new technologies, interested in problem solving, data structures, algorithms, AI, machine learning and nlp.

Amateur guitarist/ keyboardist, squash player.

Comments and Discussions