Click here to Skip to main content
Licence CPOL
First Posted 1 Mar 2011
Views 27,697
Downloads 2,098
Bookmarked 37 times

Kruskal Algorithm

By | 9 Mar 2011 | Article
Implementation of Kruskal Algorithm in C#

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

Low Level Design

Using the Code

private List<Edge> SolveGraph(ref int nTotalCost)
        {
            Edge.QuickSort(m_lstEdgesInitial, 0, m_lstEdgesInitial.Count - 1);
            List<Edge> lstEdgesReturn = new List<Edge>(m_lstEdgesInitial.Count);
            foreach (Edge ed in m_lstEdgesInitial)
            {
                Vertex vRoot1, vRoot2;
                vRoot1 = ed.V1.GetRoot();
                vRoot2 = ed.V2.GetRoot();
                if (vRoot1.Name != vRoot2.Name)
                {
                    nTotalCost += ed.Cost;
                    Vertex.Join(vRoot1, vRoot2);
                    lstEdgesReturn.Add
			(new Edge(ed.V1, ed.V2, ed.Cost, ed.StringPosition));
                }
            }
            return lstEdgesReturn;
        }

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)
class Vertex
{
    #region Members
    int nName;
    public int nRank;
    public Vertex vRoot;
    public System.Drawing.Point pPosition;
    #endregion

    #region Properties
    public int Name
    {
        get
        {
            return nName;
        }
    }
    #endregion

    public Vertex(int nName, System.Drawing.Point pPosition)
    {
        this.nName = nName;
        nRank = 0;
        this.vRoot = this;
        this.pPosition = pPosition;
    }

    #region Methods
    internal Vertex GetRoot()
    {
        if (this.vRoot != this)// am I my own root ? (am i the root ?)
        {
            this.vRoot = this.vRoot.GetRoot();// No? then get my root
        }
        return this.vRoot;
    }

    internal static void Join(Vertex vRoot1, Vertex vRoot2)
    {
        if (vRoot2.nRank < vRoot1.nRank)//is the rank of Root2 less than that of Root1 ?
        {
            vRoot2.vRoot = vRoot1;	//yes! then make Root1 the root of Root2 
            			//(since it has the higher rank)
        }
        else //rank of Root2 is greater than or equal to that of Root1
        {
            vRoot1.vRoot = vRoot2;	//make Root2 the root of Root1
            if (vRoot1.nRank == vRoot2.nRank)//both ranks are equal ?
            {
                vRoot1.nRank++;	//increment one of them, 
                			//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.

class Edge : IComparable
    {
        #region Members
        Vertex v1, v2;
        int nCost;
        System.Drawing.Point pStringPosition;
        #endregion

        #region Properties
        public Vertex V1
        {
            get
            {
                return v1;
            }
        }
        public Vertex V2
        {
            get
            {
                return v2;
            }
        }
        public int Cost
        {
            get
            {
                return nCost;
            }
        }
        public System.Drawing.Point StringPosition
        {
            get
            {
                return pStringPosition;
            }
        }
        #endregion

        public Edge(Vertex v1, Vertex v2, int nCost, System.Drawing.Point pStringPosition)
        {
            this.v1 = v1;
            this.v2 = v2;
            this.nCost = nCost;
            this.pStringPosition = pStringPosition;
        }

        #region IComparable Members

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

        #endregion

        internal static void QuickSort
		(List<Edge> m_lstEdgesInitial, int nLeft, int nRight)
        {
            int i, j, x;
            i = nLeft; j = nRight;
            x = m_lstEdgesInitial[(nLeft + nRight) / 2].Cost;

            do
            {
                while ((m_lstEdgesInitial[i].Cost < x) && (i < nRight)) i++;
                while ((x < m_lstEdgesInitial[j].Cost) && (j > nLeft)) j--;

                if (i <= j)
                {
                    Edge y = m_lstEdgesInitial[i];
                    m_lstEdgesInitial[i] = m_lstEdgesInitial[j];
                    m_lstEdgesInitial[j] = y;
                    i++; j--;
                }
            } while (i <= j);

            if (nLeft < j) QuickSort(m_lstEdgesInitial, nLeft, j);
            if (i < nRight) QuickSort(m_lstEdgesInitial, i, nRight);
        }
    }

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.

public Vertex(int nName, System.Drawing.Point pPosition)
{
    this.nName = nName;
    nRank = 0;
    this.vRoot = this;
    this.pPosition = pPosition;
}

Why This Step?

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

Consider this example:

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().

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

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

internal static void Join(Vertex vRoot1, Vertex vRoot2)
{
    if (vRoot2.nRank < vRoot1.nRank)//is the rank of Root2 less than that of Root1 ?
    {
        vRoot2.vRoot = vRoot1;		//yes! then Root1 is the root of Root2 
					//(since it has the higher rank)
    }
    else //rank of Root2 is greater than or equal to that of Root1
    {
        vRoot1.vRoot = vRoot2;		//make Root2 the root
        if (vRoot1.nRank == vRoot2.nRank)	//both ranks are equal ?
        {
            vRoot1.nRank++;		//increment one of them, 
				//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)

About the Author

Omar Gamil

Software Developer

Egypt Egypt

Member

Enthusiastic programmer/researcher, passionate to learn new technologies, interested in problem solving,data structures, algorithms and automation.
 
If you have a question\suggestion about one of my articles, or you want an algorithm implemented in C#, feel free to contact me.
 
Résumé
vWorker Account

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralMy vote of 5 PinmemberAbinash Bishoyi3:05 6 Apr '12  
GeneralMy vote of 5 Pinmembermanoj kumar choubey23:44 27 Mar '12  
GeneralMy Vote of 5 PinmemberRaviRanjankr4:58 30 Dec '11  
GeneralRe: My Vote of 5 Pinmembermobilat6:39 30 Dec '11  
QuestionQuick sort Pinmembermobilat22:48 28 Dec '11  
GeneralMy vote of 5 Pinmemberal13n21:42 9 Oct '11  
QuestionSome responses to unjustified criticisms [modified] PinmemberAndyUk064:02 11 Sep '11  
AnswerRe: Some responses to unjustified criticisms PinmemberOmar Gamil4:09 11 Sep '11  
GeneralRe: Some responses to unjustified criticisms PinmemberAndyUk066:52 11 Sep '11  
QuestionMy vote of 5 PinmemberAndyUk061:01 9 Sep '11  
GeneralMy vote of 5 Pinmembernaser abu khas14:24 2 Apr '11  
GeneralMy vote of 5 Pinmemberparyj18:36 9 Mar '11  
GeneralMy vote of 5 PinmemberEyalSch24:57 8 Mar '11  
GeneralMy vote of 1 PinmemberJV99994:16 2 Mar '11  
GeneralMy vote of 1 PinmemberPetr Pechovic0:57 2 Mar '11  
GeneralRe: My vote of 1 PinmemberOmar Gamil1:54 2 Mar '11  
GeneralRe: My vote of 1 PinmemberPetr Pechovic7:58 2 Mar '11  
GeneralRe: My vote of 1 PinmemberOmar Gamil21:33 2 Mar '11  
GeneralRe: My vote of 1 PinmvpDave Kreskowiak9:05 2 Mar '11  
GeneralRe: My vote of 1 PinmemberM i s t e r L i s t e r12:36 2 Mar '11  
GeneralMy vote of 1 Pinmembersnortle0:14 2 Mar '11  
GeneralMy vote of 2 PinmemberAdrian Pasik22:45 1 Mar '11  
GeneralRe: My vote of 2 PinmemberOmar Gamil23:28 1 Mar '11  
GeneralMy vote of 5 PinmemberTV Mogul10:17 1 Mar '11  
GeneralRe: My vote of 5 PinmemberOmar Gamil21:58 1 Mar '11  

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

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

Permalink | Advertise | Privacy | Mobile
Web03 | 2.5.120517.1 | Last Updated 9 Mar 2011
Article Copyright 2011 by Omar Gamil
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid