Click here to Skip to main content
15,861,125 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 179.2K   11.6K   70   41
Implementation of Kruskal Algorithm in C#
Image 1

Image 2

Introduction

According to Wikipedia:"Kruskal's algorithm is an algorithm in graph theory that finds a minimum spanning tree for a connectedweighted graph. This means it finds a subset of the edges that forms a tree that includes every vertex, where the total weight of all the edges in the tree is minimized. If the graph is not connected, then it finds a minimum spanning forest (a minimum spanning tree for each connected component). Kruskal's algorithm is an example of a greedy algorithm."

In short, Kruskal's algorithm is used to connect all nodes in a graph, using the least cost possible.

Example

A cable TV company is laying a cable in a new neighborhood. An internet cafe is connecting all PCs via network.

Using the Demo

Click anywhere to plot the vertices. Hold down ctrl and select two vertices to create an edge. A popup window appears to enter edge cost. Having finished plotting the graph, click Solve.

High Level Design

Image 3

Low Level Design

Image 4

Using the Code

C#
IList<Edge> Solve(IList<Edge> graph, out int totalCost);  

How the Graph is formed with GDI is not covered as it is irrelevant.

Classes

Typically, our graph consists of two components, Vertices, and Edges connecting these vertices.

Each Edge is marked by a value or weight, which is the Cost of connecting the two vertices.

Vertex

Holds:

  • Vertex Name (which must be unique within Graph) and its Drawing Point
  • Rank and Root (we'll get to those later)
C#
using System;
using System.Drawing;

namespace Kruskal
{
    public class Vertex
    {
        #region Members

        private int name;

        #endregion

        #region Public Properties

        public int Name
        {
            get
            {
                return name;
            }
        }

        public int Rank { get; set; }

        public Vertex Root { get; set; }

        public Point Position { get; set; }

        #endregion

        #region Constructor

        public Vertex(int name, Point position)
        {
            this.name = name;
            this.Rank = 0;
            this.Root = this;
            this.Position = position;
        } 

        #endregion

        #region Methods

        internal Vertex GetRoot()
        {
            if (this.Root != this)// am I my own parent ? (am i the root ?)
            {
                this.Root = this.Root.GetRoot();// No? then get my parent
            }

            return this.Root;
        }

        internal static void Join(Vertex root1, Vertex root2)
        {
            if (root2.Rank < root1.Rank)//is the rank of Root2 less than that of Root1 ?
            {
                root2.Root = root1;//yes! then Root1 is the parent of Root2 (since it has the higher rank)
            }
            else //rank of Root2 is greater than or equal to that of Root1
            {
                root1.Root = root2;//make Root2 the parent
                if (root1.Rank == root2.Rank)//both ranks are equal ?
                {
                    root2.Rank++;//increment Root2, we need to reach a single root for the whole tree
                }
            }
        }

        #endregion
    }
} 

Edge

Holds two Vertices, Cost of connection between them, and CostDrawing Point.

Note that it implements IComparable, we'll need it to sort Edges by Cost later on.

C#
using System;
using System.Drawing;

namespace Kruskal
{
    public class Edge : IComparable
    {
        #region Members

        private Vertex v1, v2;
        private int cost;
        private Point stringPosition;

        #endregion

        #region Public Properties

        public Vertex V1
        {
            get
            {
                return v1;
            }
        }

        public Vertex V2
        {
            get
            {
                return v2;
            }
        }

        public int Cost
        {
            get
            {
                return cost;
            }
        }

        public Point StringPosition
        {
            get
            {
                return stringPosition;
            }
        }

        #endregion

        #region Constructor

        public Edge(Vertex v1, Vertex v2, int cost, Point stringPosition)
        {
            this.v1 = v1;
            this.v2 = v2;
            this.cost = cost;
            this.stringPosition = stringPosition;
        } 

        #endregion

        #region IComparable Members

        public int CompareTo(object obj)
        {
            Edge e = (Edge)obj;
            return this.cost.CompareTo(e.cost);
        }

        #endregion
    }
} 

Algorithm Implementation

Sorting Edges

Edges are sorted in ascending order according to Cost using Quick Sort.

Making Sets

Initially, every Vertex is its own Root and has rank zero.

C#
public Vertex(int name, Point position)
{
    this.name = name;
    this.Rank = 0;
    this.Root = this;
    this.Position = position;
}  

Why This Step?

We need it to ensure that, on adding our Vertices, we are not forming a loop.

Consider this example:

Image 5

The Edge BD was not considered, because B,D are already connected through B,A,D.

Thus, for every Edge we examine, we must inspect that its two Vertices belong to different sets (trees).

How To Find Out If Two Vertices Are In Different Sets?

Using the recursive function GetRoot().

C#
internal Vertex GetRoot()
        {
            if (this.Root != this)// am I my own parent ? (am i the root ?)
            {
                this.Root = this.Root.GetRoot();// No? then get my parent
            }

            return this.Root;
        } 

If roots are indeed different, (each Vertex is in a different set), Join() the two Vertices.

C#
internal static void Join(Vertex root1, Vertex root2)
        {
            if (root2.Rank < root1.Rank)//is the rank of Root2 less than that of Root1 ?
            {
                root2.Root = root1;//yes! then Root1 is the parent of Root2 (since it has the higher rank)
            }
            else //rank of Root2 is greater than or equal to that of Root1
            {
                root1.Root = root2;//make Root2 the parent
                if (root1.Rank == root2.Rank)//both ranks are equal ?
                {
                    root2.Rank++;//increment Root2, we need to reach a single root for the whole tree
                }
            }
        } 

Conclusion

Hope I delivered a clear explanation.

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

 
QuestionQuick sort Pin
mobilat28-Dec-11 22:48
mobilat28-Dec-11 22:48 
GeneralMy vote of 5 Pin
al13n9-Oct-11 21:42
al13n9-Oct-11 21:42 
QuestionSome responses to unjustified criticisms [modified] PinPopular
AndyUk0611-Sep-11 4:02
AndyUk0611-Sep-11 4:02 
AnswerRe: Some responses to unjustified criticisms Pin
Omar Gameel Salem11-Sep-11 4:09
professionalOmar Gameel Salem11-Sep-11 4:09 
GeneralRe: Some responses to unjustified criticisms Pin
AndyUk0611-Sep-11 6:52
AndyUk0611-Sep-11 6:52 
QuestionMy vote of 5 Pin
AndyUk069-Sep-11 1:01
AndyUk069-Sep-11 1:01 
GeneralMy vote of 5 Pin
naser abu khas2-Apr-11 14:24
naser abu khas2-Apr-11 14:24 
GeneralMy vote of 5 Pin
paryj9-Mar-11 18:36
paryj9-Mar-11 18:36 
Excellent article - Oram

Thanks.
GeneralMy vote of 5 Pin
EyalSch28-Mar-11 4:57
EyalSch28-Mar-11 4:57 
GeneralMy vote of 1 Pin
JV99992-Mar-11 4:16
professionalJV99992-Mar-11 4:16 
GeneralMy vote of 1 Pin
Petr Pechovic2-Mar-11 0:57
professionalPetr Pechovic2-Mar-11 0:57 
GeneralRe: My vote of 1 Pin
Omar Gameel Salem2-Mar-11 1:54
professionalOmar Gameel Salem2-Mar-11 1:54 
GeneralRe: My vote of 1 Pin
Petr Pechovic2-Mar-11 7:58
professionalPetr Pechovic2-Mar-11 7:58 
GeneralRe: My vote of 1 Pin
Omar Gameel Salem2-Mar-11 21:33
professionalOmar Gameel Salem2-Mar-11 21:33 
GeneralRe: My vote of 1 Pin
Dave Kreskowiak2-Mar-11 9:05
mveDave Kreskowiak2-Mar-11 9:05 
GeneralRe: My vote of 1 Pin
M i s t e r L i s t e r2-Mar-11 12:36
M i s t e r L i s t e r2-Mar-11 12:36 
GeneralMy vote of 1 Pin
snortle2-Mar-11 0:14
snortle2-Mar-11 0:14 
GeneralMy vote of 2 Pin
Adrian Pasik1-Mar-11 22:45
Adrian Pasik1-Mar-11 22:45 
GeneralRe: My vote of 2 Pin
Omar Gameel Salem1-Mar-11 23:28
professionalOmar Gameel Salem1-Mar-11 23:28 
GeneralMy vote of 5 Pin
Bill SerGio, The Infomercial King1-Mar-11 10:17
Bill SerGio, The Infomercial King1-Mar-11 10:17 
GeneralRe: My vote of 5 Pin
Omar Gameel Salem1-Mar-11 21:58
professionalOmar Gameel Salem1-Mar-11 21:58 
General[My vote of 1] Not good a article... Pin
Dave Kreskowiak1-Mar-11 8:39
mveDave Kreskowiak1-Mar-11 8:39 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.