Click here to Skip to main content
Click here to Skip to main content

Dijkstra:Shortest Route Calculation - Object Oriented

By , 3 Jan 2008
 
All points are locations. The connections between the points have a specific weight. Not all connections are bidirectional (a dot marks a start travel point). When Calculate is pressed, all routes from the selected location are calculated. When a route is selected in the listbox, the shortest route is visually shown by coloring the start dots red.
In this example, the shortest route from 0 to 4 is going through location 2, 1 and then 4.

Introduction

Dijkstra was a Dutch computer scientist who invented a fast and simple way to calculate the shortest path between two points. Many examples I have found on the Internet implement that algorithm but none of them have done it in an Object Oriented way. So I thought of making my own.

Background

Information about Dijkstra can be found here.

Using the Code

The code contains two Project classes:

  1. GUI: Shows the information visually
    • To add locations, click on the 'Add Location' button and then click on the map where you want to add locations.
    • To add routes, click on the 'Add Location' button to deactivate the add location, then click on a start location, then click on a end location. The weight of the route can be configured on top.
  2. RouteEngine: Calculates the route

I will only go into details about the RouteEngine. How the UI is handled is not so important for this article but if you need information about it, you can always ask.

Project RouteEngine

  1. Connection: This class holds the information about the connection between two dots. This is a one directional connection from A (the startpoint is visually shown with a dot) to B with a specific weight attached.
  2. Location: Just a location (for example 1).
  3. RouteEngine: This class will calculate all routes from one given startPoint.
  4. Route: This class holds the information about a route between two points (generated with the RouteEngine class).

Location

The most simple class. It only holds a name to display.

Connection

This class contains two Location objects and a weight.

public Connection(Location a, Location b, int weight)
{
    this._a = a;
    this._b = b;
    this._weight = weight;
}

Route

This class contains a route. It has only a list of connections and the total weight. This class is generated by the route engine.

Route Engine

This is the class that drives the component. The algorithm is as follows:

  1. Set the startPosition as active
  2. Set the total weight to all routes to infinite
  3. Iterate through all connections of the active position and store their weight if their weight is smaller than their current weight
  4. Set the active position as used
  5. Set the nearest point (on whatever location) that isn't used as active
  6. Repeat 3, 4, 5 until all positions are used

The following method will perform all these steps (and some extra checking and thinking). The Dictionary returned is a list of destination locations and the corresponding route to each destination location.

/// <summary />
/// Calculates the shortest route to all the other locations
/// </summary />
/// <returns />List of all locations and their shortest route</returns />
public Dictionary<location, /> CalculateMinCost(Location _startLocation)
{
    //Initialise a new empty route list
    Dictionary<location, /> _shortestPaths = new Dictionary<location, />();
    //Initialise a new empty handled locations list
    List<location /> _handledLocations = new List<location />();

    //Initialise the new routes. the constructor will set the route weight to in.max
    foreach (Location location in _locations)
    {
        _shortestPaths.Add(location, new Route(location.Identifier));
    }

    //The startPosition has a weight 0.
    _shortestPaths[_startLocation].Cost = 0;

    //If all locations are handled, stop the engine and return the result
    while (_handledLocations.Count != _locations.Count)
    {
        //Order the locations
        List<location /> _shortestLocations = (List < Location > )(from s in _shortestPaths
                                orderby s.Value.Cost
                                select s.Key).ToList();

        Location _locationToProcess = null;

        //Search for the nearest location that isn't handled
        foreach (Location _location in _shortestLocations)
        {
            if (!_handledLocations.Contains(_location))
            {
                //If the cost equals int.max, there are no more possible connections 
                //to the remaining locations
                if (_shortestPaths[_location].Cost == int.MaxValue)
                    return _shortestPaths;
                _locationToProcess = _location;
                break;
            }
        }

        //Select all connections where the startposition is the location to Process
        var _selectedConnections = from c in _connections
                                   where c.A == _locationToProcess
                                   select c;

        //Iterate through all connections and search for a connection which is shorter
        foreach (Connection conn in _selectedConnections)
        {
            if (_shortestPaths[conn.B].Cost > conn.Weight + _shortestPaths[conn.A].Cost)
            {
                _shortestPaths[conn.B].Connections = 
                        _shortestPaths[conn.A].Connections.ToList();
                _shortestPaths[conn.B].Connections.Add(conn);
                _shortestPaths[conn.B].Cost = conn.Weight + _shortestPaths[conn.A].Cost;
            }
        }
        //Add the location to the list of processed locations
        _handledLocations.Add(_locationToProcess);
    }

    return _shortestPaths;
}

History

  • 24 December, 2007: First release

License

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

About the Author

Michael Demeersseman
Belgium Belgium
Member
No Biography provided

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.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberJocelyn62France3 Jul '12 - 23:49 
Thank you, you save my life for an apply!!
BugPersistent GUImemberMember 842553613 Feb '12 - 15:50 
I was using this as an example to learn GUI, but the graphics would disappear if minimised or covered up in any way.
 
To make graphics persistent just add this line to InitialiseComponent() in Form1.designer.cs
 
this.pnlView.Paint += new System.Windows.Forms.PaintEventHandler(this.pnlView_Paint);
 
I think this is a bug because otherwise the pnlView_Paint function is never called.
QuestionPoint to Point searchingmembermaralita4 Sep '11 - 0:43 
I'm trying to reverse engineer this application and I came to a road block
 
What I'm trying to do is to search a path from a starting point to an end point, like from point A to point Z
 
in this program, the search is for the whole points. Can somebody help me in this?
Generalc projctmemberdeepakptl4341@Gmail.com18 Mar '11 - 7:33 
degrre of seperation .
how can i find out
maximum degree of seperation code in c programing?
please send the massage to my g-mail-deepakptl4341@Gmail.com
Generalc progamingmemberdeepakptl4341@Gmail.com18 Mar '11 - 7:31 
degrre of seperation .
how can i find out
maximum degree of seperation code in c programing?
QuestionC++ conversionmemberxumepoc10 Nov '10 - 3:18 
Can that be done in C++/MFC? If yes can someone help me with it
GeneralSubjectmemberjcdentondx28 May '10 - 10:13 
cool code!
i use it
thanks
Questionrun time?memberPeter Cacioppi3 Jan '10 - 9:58 
Thanks for putting together this coding project.
 
I was wondering if you are interested in upgrading the code slightly to implement a more expected big-O run time? Your version appears to take O(v log(v)) time to find the unexplored node with the minimum working distance. This will lead to an overall run time of O(e + v^2log(v)). Implementing a priority queue to maintain the working distances would result in the "update working distance" step and the "find minimum working distance" step both taking O(log (v)) and thus the full execution taking O(e log(v) + v log (v) ). For cases where e is much smaller than v^2, this implementation will be much faster. In the worst case, where e = v^2, the two run times should be roughly similar. However, the e << v^2 case should be more reflective of a real world distance matrix where each edge represents a relatively short, straight path of direct roadway.
 
I could put together a priority queue C# implementation if you are interested in seeing one. The easiest implementation would involve maintaining a List whereby each node could find it's parents and children based on simple modulo/rounding arithmetic of it's index. You would then simply maintain the invariant that a parent node always has a key value less than or equal to that of it's children.
 
Cheers
Pete
AnswerRe: run time?memberMichael Demeersseman3 Jan '10 - 23:28 
Interesting. You can always send me one. i'll have a look at it
QuestionInstallation on Windows Vistamemberssnc17 Mar '09 - 8:38 
Hi, How do I install on Windows Vista? and, do you know how it integrates with MapGuide to calculate the shortest path between two points on a map with sdf or shp format?
Thanx.
QuestionFile 'usrLocation.cs' not found.memberMember 330569822 Apr '08 - 19:52 
I downloaded and compiled and the program works. The problem is that the program is trying to access the 'usrLocation.cs' and this file was not in the zip download. How do I fix this?
 
Thanks for the help and thanks for the writing the app.
CT
AnswerRe: File 'usrLocation.cs' not found.memberMichael Demeersseman23 May '08 - 20:58 
You can just delete it out of the project. i shouldn't be included. strange it is. I'll send an update to codeproject.
GeneralBug!memberManjit Dosanjh9 Jan '08 - 23:46 
I added 12 points with weights ranging from 3 to 7. On the calculation, the first 10 seem to be OK but the 11th and 12th show the cost as 2,147,483,647! Some sort of overflow??
 
"If the facts don't fit the theory, change the facts."

GeneralRe: Bug!memberMichael Demeersseman10 Jan '08 - 9:24 
2,147,483,647 is shown(=infinite) if there is no connection to the the point. Keep in mind that the connections you draw are not bidirectional. If you want to draw bidirectional connections you have to connect point A to B and B to A again.
 
greetings
GeneralRe: Bug!memberManjit Dosanjh11 Jan '08 - 0:03 
Thanks. I had a feeling that it was some sort of overflow.
 
"If the facts don't fit the theory, change the facts."

GeneralRe: Bug!memberMichael Demeersseman23 May '08 - 20:58 
You can just delete it out of the project. i shouldn't be included. strange it is. I'll send an update to codeproject.
QuestionWhat version?memberManjit Dosanjh9 Jan '08 - 11:40 
What version of .NET do we need to run this?
 
I get the following error:
 
Could not load file or assembly 'System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The system cannot find the file specified.
File name: 'System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
 
Also, I take it this is built using the full VS2008 version?
 
Many thanks
 
Manjit Dosanjh
 
"If the facts don't fit the theory, change the facts."

GeneralRe: What version?memberManjit Dosanjh9 Jan '08 - 23:43 
I answered myown question. It should be 3.5. I thought that I had installed this but I hadn't. Apologies
 
"If the facts don't fit the theory, change the facts."

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

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130523.1 | Last Updated 3 Jan 2008
Article Copyright 2008 by Michael Demeersseman
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid