Introduction to Graph Theory: Finding The Shortest Path (Posted on February 9th, 2013)

Graph theory is one of those things in the computer science field that has the stigma of being extremely hard and near impossible to understand. My goal for this post is to introduce you to graph theory and show you one approach to finding the shortest path in a graph using Dijkstra's Algorithm. Don't worry about learning everything in one go. If you can walk away with a few concepts and one or two things implanted in your memory you're well on your way to understanding path searching in graph theory.

I'll be deviating from python and going with ruby for this post. If you're here for your usual dose of python code feel free to follow along and reference the code at the very bottom of this post where I've completed a python implementation. Python and ruby are similar enough where you should be able to understand most of the code though.

The Setup

Just need one gem for this one. PriorityQueue will allow us to have a heap where we can change the priority and have the tree automatically rebalance which is nice.

gem install PriorityQueue

A Little About Graphs

In the computer science world a graph is a data structure that represents a connected plot of points. You can kind of think of the points (verticies) as cities and the lines (edges) that connect those points as roads. If you're familiar with trees you can think of it as a tree where a node on the tree can link to many or no other nodes on the tree. You can use graphs to do all sorts of cool things such as find a person's Bacon Number, find all the Married people who like Prostitutes, or get directions to my house.

The Graph

This is a picture of the weighted graph we'll be implementing/searching. A weighted graph simply means that the edges (roads) of the graph have a value. In our case we'll be using that value as a distance. It's a rather small graph but it will definitely help to give us an idea of how we can efficiently search a graph.

Visual representation of the computer science graph that's being implemented

Inplementing this graph is only a few lines for the class and some calls to our add_vertex method.

class Graph
    def initialize()
        @vertices = {}
    end
  
    def add_vertex(name, edges)
        @vertices[name] = edges
    end
    
    def to_s
        return @vertices.inspect
    end
end

So in our case we want to create a graph and add a vertex "A" which has paths to vertices "B" and "C" with distances 7 and 8 respectively. It's as simple as:

g = Graph.new
g.add_vertex('A', {'B' => 7, 'C' => 8})

Here's the code to add the rest of the verticies to match the graph picture above. Feel free to add your own and make your own graph. As long as the weights (distances) are positive the algorithm will work.

g.add_vertex('B', {'A' => 7, 'F' => 2})
g.add_vertex('C', {'A' => 8, 'F' => 6, 'G' => 4})
g.add_vertex('D', {'F' => 8})
g.add_vertex('E', {'H' => 1})
g.add_vertex('F', {'B' => 2, 'C' => 6, 'D' => 8, 'G' => 9, 'H' => 3})
g.add_vertex('G', {'C' => 4, 'F' => 9})
g.add_vertex('H', {'E' => 1, 'F' => 3})

Dijkstra's Algorithm Overview

Back before computers were a thing, around 1956, Edsger Dijkstra came up with a way to find the shortest path within a graph whose edges were all non-negative values. To this day, almost 50 years later, his algorithm is still being used in things such as link-state routing. It has also been extended by others to create more advanced path finding algorithms such as A*.

The algorithm starts with a graph and a source vertex which serves as the root node. For our graph let's use "A" as the source. Starting with "A" we want to calculate the path to all of our connected nodes from "A" which happens to be "B" and "C". When we do that we'll see something like:

Vertex Distance Node We Came From
A 0
B 7 A
C 8 A
D
E
F
G
H

Our next step will be to grab the next shortest path from "A" that we haven't visted yet and set that as our new source. We'll store this in a min-heap for easy O(1) retrieval. In this case the next closest would be "B". So we'll head to "B" and repeat the process. We keeping doing this until all vertices have been found or we find our target vertex if one is set. After the algorithm runs we'll end up with a table that looks like:

Vertex Distance Node We Came From
A 0
B 7 A
C 8 A
D 17 F
E 13 H
F 9 B
G 12 C
H 12 F

If we wanted to find the path from "A" to "H" we'll start at "H" and work our way backwards. We already know the distance from "A" to "H" is 12 so we just need the path that we took to get there. So starting from "H" we see the shortest path came from "F". The shortest path from "F" to "A" was through the vertex "B". The shortest path from "B" to "A" was the direct path we have "B" to "A". Therefore our path is A → B → F → H.

Dijkstra's Algorithm Implementation

Let's go ahead and setup our search method and initialize our variables. Our function will take in 2 parameters. The start vertex and the finish vertex. Note the "require 'priority_queue'" that was added at the top. Our Graph class now looks like this:

require 'priority_queue'

class Graph
    def initialize()
        @vertices = {}
    end
  
    def add_vertex(name, edges)
        @vertices[name] = edges
    end
    
    def shortest_path(start, finish)
        maxint = (2**(0.size * 8 -2) -1)
        distances = {}
        previous = {}
        nodes = PriorityQueue.new
    end
    
    def to_s
        return @vertices.inspect
    end
end

Maxint will serve as our infinity. Distances will be a hash that stores the vertex and the distance from our original source vertex. Previous will be a hash that stores the vertex we came from to get to this node in the shortest path. Nodes will be our min-heap that holds unvisited nodes.

Let's now go ahead and initialize the values of our variables.

def shortest_path(start, finish)
    maxint = (2**(0.size * 8 -2) -1)
    distances = {}
    previous = {}
    nodes = PriorityQueue.new
    
    @vertices.each do | vertex, value |
        if vertex == start
            distances[vertex] = 0
            nodes[vertex] = 0
        else
            distances[vertex] = maxint
            nodes[vertex] = maxint
        end
        previous[vertex] = nil
    end
end

Now we want to start churning through all the nodes. So let's grab our min heap and pop off (in this case the method is called "delete_min_return_key") the smallest vertex, or basically the vertex with the shortest distance from the start vertex which we have not yet visted. For the first run through this will always be the source node since the distance is set to 0. If we ever pop off a vertex with maxint as the distance than we know there are no more paths to the source node so we can just return. If we try to pop off the heap with nothing there then smallest will be nil so we should also check for that as well. Both of these conditions essentially mean we've exhausted all search efforts.

while nodes
    smallest = nodes.delete_min_return_key
    
    if smallest == nil or distances[smallest] == maxint
        break            
    end
end

If we get past this check then we know there's still a chance to find more nodes. Let's check our neighbors (connected vertices) and see if we can find any shorter paths to our current node. Believe it or not this is called relaxing. To get a better understanding of this concept let's go back to the picture of our graph:

Visual representation of the computer science graph that's being implemented

Say our source node is "A". That means that A's neighbors are "B" and "C". When looping through the neighbors we'll start with "B". We take the distance "A" is from "A" (0) and add it to the distance "B" is from our current vertex (not the original source, they just happen to be the same in this case) which is A. 0 + 7 = 7. We then compare this number to the distance "B" is from the original source. Since we haven't calculated this value the distance is set to our maxint variable. So we can then go ahead and update our distance of "A" to "B" as 7 and set an entry in the "previous" variable as the shortest path from "A" to "B" is through A. We then go ahead and update our min heap to say that the shortest distance from our original source to any node is 7.

Here's how our variables look in memory:

Distance
Vertex Distance From Start
B 7
C
D
E
F
G
H
Previous
Vertex Node We Came From
B A
C
D
E
F
G
H

The first node in the min-heap (nodes variable) is 'B' => 7.

Here is the code that produces all of that magic:

def shortest_path(start, finish)
    maxint = (2**(0.size * 8 -2) -1)
    distances = {}
    previous = {}
    nodes = PriorityQueue.new
    
    @vertices.each do | vertex, value |
        if vertex == start
            distances[vertex] = 0
            nodes[vertex] = 0
        else
            distances[vertex] = maxint
            nodes[vertex] = maxint
        end
        previous[vertex] = nil
    end
    
    while nodes
        smallest = nodes.delete_min_return_key
        
        if smallest == nil or distances[smallest] == maxint
            break            
        end
        
        @vertices[smallest].each do | neighbor, value |
            alt = distances[smallest] + @vertices[smallest][neighbor]
            if alt < distances[neighbor]
                distances[neighbor] = alt
                previous[neighbor] = smallest
                nodes[neighbor] = alt
            end
        end
    end
    return distances.inspect
end

With just this code we can go ahead and return the distances hash after the while loop finishes and we'll have the distance each node is from "A", our start node.

puts g.shortest_path("A", "F")
{"A"=>0, "B"=>7, "C"=>8, "D"=>17, "E"=>13, "F"=>9, "G"=>12, "H"=>12}

However, our goal was to find the shortest path so let's keep going. In order to find our shortest path we need to know when we reach our target node. Once we've reached our target node we've found the guranteed shortest path to the finish so now all we need to do is print it out. The code for that looks like this:

if smallest == finish
    path = []
    while previous[smallest]
        path.push(smallest)
        smallest = previous[smallest]
    end
    return path
end

Since our smallest node is our finish node we check which vertex got us there using the "previous" variable and add that to our path variable. Then we check which vertex got us to that vertex and so on and so forth until we reach our start vertex. When we reach our start vertex the associated value in the previous hash will be nil which will cause the while loop to exit and return the path.

That's our implementation of Dijkstra's algorithm in ruby. It's definitely a lot to take in so don't worry if you didn't get it all the first time through. Give it a re-read or 5, ask questions, search the web, and try implementing it on your own. For completion here is the final code in ruby:

require 'priority_queue'

class Graph
    def initialize()
        @vertices = {}
    end
  
    def add_vertex(name, edges)
        @vertices[name] = edges
    end
    
    def shortest_path(start, finish)
        maxint = (2**(0.size * 8 -2) -1)
        distances = {}
        previous = {}
        nodes = PriorityQueue.new
        
        @vertices.each do | vertex, value |
            if vertex == start
                distances[vertex] = 0
                nodes[vertex] = 0
            else
                distances[vertex] = maxint
                nodes[vertex] = maxint
            end
            previous[vertex] = nil
        end
        
        while nodes
            smallest = nodes.delete_min_return_key
            
            if smallest == finish
                path = []
                while previous[smallest]
                    path.push(smallest)
                    smallest = previous[smallest]
                end
                return path
            end
            
            if smallest == nil or distances[smallest] == maxint
                break            
            end
            
            @vertices[smallest].each do | neighbor, value |
                alt = distances[smallest] + @vertices[smallest][neighbor]
                if alt < distances[neighbor]
                    distances[neighbor] = alt
                    previous[neighbor] = smallest
                    nodes[neighbor] = alt
                end
            end
        end
        return distances.inspect
    end
    
    def to_s
        return @vertices.inspect
    end
end

g = Graph.new
g.add_vertex('A', {'B' => 7, 'C' => 8})
g.add_vertex('B', {'A' => 7, 'F' => 2})
g.add_vertex('C', {'A' => 8, 'F' => 6, 'G' => 4})
g.add_vertex('D', {'F' => 8})
g.add_vertex('E', {'H' => 1})
g.add_vertex('F', {'B' => 2, 'C' => 6, 'D' => 8, 'G' => 9, 'H' => 3})
g.add_vertex('G', {'C' => 4, 'F' => 9})
g.add_vertex('H', {'E' => 1, 'F' => 3})
puts g.shortest_path('A', 'H')
>>> H
>>> F
>>> B

Python Code

I know a lot of my readers are pythonistas so I've also went ahead and did a python implementation. You'll notice in the relax section there is some extra code. This is me just rerunning the heap since the builtin heapq module doesn't have the ability to modify priorities and have the heap be resorted. If you're familiar with the module you could go ahead and call the internal _siftdown(nodes, node_index, len(nodes)-1) method but that's not really recommended.

import heapq
import sys

class Graph:
    
    def __init__(self):
        self.vertices = {}
        
    def add_vertex(self, name, edges):
        self.vertices[name] = edges
    
    def shortest_path(self, start, finish):
        distances = {} # Distance from start to node
        previous = {}  # Previous node in optimal path from source
        nodes = [] # Priority queue of all nodes in Graph

        for vertex in self.vertices:
            if vertex == start: # Set root node as distance of 0
                distances[vertex] = 0
                heapq.heappush(nodes, [0, vertex])
            else:
                distances[vertex] = sys.maxint
                heapq.heappush(nodes, [sys.maxint, vertex])
            previous[vertex] = None
        
        while nodes:
            smallest = heapq.heappop(nodes)[1] # Vertex in nodes with smallest distance in distances
            if smallest == finish: # If the closest node is our target we're done so print the path
                path = []
                while previous[smallest]: # Traverse through nodes til we reach the root which is 0
                    path.append(smallest)
                    smallest = previous[smallest]
                return path
            if distances[smallest] == sys.maxint: # All remaining vertices are inaccessible from source
                break
            
            for neighbor in self.vertices[smallest]: # Look at all the nodes that this vertex is attached to
                alt = distances[smallest] + self.vertices[smallest][neighbor] # Alternative path distance
                if alt < distances[neighbor]: # If there is a new shortest path update our priority queue (relax)
                    distances[neighbor] = alt
                    previous[neighbor] = smallest
                    for n in nodes:
                        if n[1] == neighbor:
                            n[0] = alt
                            break
                    heapq.heapify(nodes)
        return distances
        
    def __str__(self):
        return str(self.vertices)
        
g = Graph()
g.add_vertex('A', {'B': 7, 'C': 8})
g.add_vertex('B', {'A': 7, 'F': 2})
g.add_vertex('C', {'A': 8, 'F': 6, 'G': 4})
g.add_vertex('D', {'F': 8})
g.add_vertex('E', {'H': 1})
g.add_vertex('F', {'B': 2, 'C': 6, 'D': 8, 'G': 9, 'H': 3})
g.add_vertex('G', {'C': 4, 'F': 9})
g.add_vertex('H', {'E': 1, 'F': 3})
print g.shortest_path('A', 'H')
>>> ['H', 'F', 'B']

You can grab the source from this post at https://github.com/mburst/dijkstras-algorithm. I encourage you to implement this in another language or in a different way than I have shown and submit a pull request. I think it would be cool to have a huge collection of implementations from different people.

As always if you have any feedback or questions feel free to drop them in the comments below or contact me privately on my contact page. Thanks for reading!

P.S. If your company is looking to hire an awesome soon-to-be college graduate (May 2013) let me know!

Tags: Python, Data Structures, Ruby

Comments:

  • Scott Brickey - 2 years, 6 months ago

    My .NET implementation using Generics has been available at http://www.sbrickey.com/Tech/Code/Dijkstra_s_Algorithm_in_C_with_Generics I used it because I was querying AD directly, and needed to be able to determine the best (closest) domain controllers.

    reply

  • really cheap instagram followers - 2 weeks, 2 days ago

    Absolutely fantastic posting! Lots of useful information and inspiration, both of which we all need!Relay appreciate your work.

    reply

  • Gabriel - 2 years, 6 months ago

    And here you can find it in Scala :)

    reply

  • Anonymous - 2 years, 6 months ago

    God bless you.

    reply

  • Nick - 2 years, 6 months ago

    I've never used Ruby but should the check for the empty priority queue / maxint distance be reversed? distances[smallest] == maxint or smallest == nil If smallest is nil, what happens when you try to evaluate distances[smallest]?

    reply

  • Max Burstein - 2 years, 6 months ago

    Indeed you are correct. Good catch! I've updated my post to reflect this fix. distances[nil] will throw: TypeError: no implicit conversion from nil to integer.

    reply

  • mspy discount coupon 2015 - 2 months, 1 week ago

    I high appreciate this post. It’s hard to find the good from the bad sometimes, but I think you’ve nailed it! would you mind updating your blog with more information?

    reply

  • Alex Ungur - 2 years, 6 months ago

    Why not use "infinity" if it is available anyway? Just set (preferably a constant) to 1.0/0 and there you have it.

    reply

  • Max Burstein - 2 years, 6 months ago

    Yea that would absolutely work.

    reply

  • Anonymous - 1 year, 11 months ago

    are there any sample implementations of other shortest path algorithms in Ruby? :)

    reply

  • Max Burstein - 1 year, 11 months ago

    I'm sure there are but I don't have any links or recommendations off the top of my head. I'm a huge fan of what I like to call Wikipedia programming. A lot of algorithm related articles have sudo code for them. Python and Ruby lend well to sudo code examples. I'd recommend checking out http://en.wikipedia.org/wiki/Shortest_path_problem#Algorithms and trying to implement ones you find interesting/useful. If you run in to any trouble with them feel free to shoot me a message and I'll help you out the best I can.

    reply

  • Rinjani Trekking - 1 week, 1 day ago

    You know your projects stand out of the herd. There is something special about them. It seems to me all of them are really brilliant!

    reply

  • Mount Rinjani - 5 days, 14 hours ago

    Very good points you wrote here..Great stuff...I think you've made some truly interesting points.Keep up the good work.

    reply

  • Rahul - 1 year, 9 months ago

    Hi, Thanks for this code.. But i want to find shortest path for 'weighted directed graph' i'm trying but not getting solution.. please help to make code.. if possible then give the whole code... thanks

    reply

  • Max Burstein - 1 year, 9 months ago

    This is the algorithm you're looking for complete with psuedocode http://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm

    reply

  • Haushaltshilfe Hannover - 5 days, 17 hours ago

    Great article with excellent idea!Thank you for such a valuable article. I really appreciate for this great information..

    reply

  • cheat - 3 days, 15 hours ago

    I can set up my new idea from this post. It gives in depth information. Thanks for this valuable information for all,..

    reply

  • auto balkan - 14 hours ago

    I really impressed after read this because of some quality work and informative thoughts . I just wanna say thanks for the writer and wish you all the best for coming!.

    reply

  • Wezu - 1 year, 9 months ago

    Hi, Just the thing I needed, and it runs ~20% faster then the next best thing I found (http://code.activestate.com/recipes/119466-dijkstras-algorithm-for-shortest-paths/)... at least on my data set.

    I'd like to use this code as a basis for a path-finding AI for a game (non-profit or not-likely-to-make-a-profit). Are there any legal restrictions(license) on your code? Can I use it for that? How should I credit You?

    reply

  • Max Burstein - 1 year, 8 months ago

    Sorry for not getting around to answering this sooner. You're free to use any code posted on this site in any way you'd like. A link back to this article is always nice in the comments but in no way required. Consider it an MIT license.

    reply

  • Anonymous - 7 months ago

    Hello, I'm not a programmer, but...I've to write an algorithm with ruby for my last exam :(. Can you help me? Dijkstra or Floyd Warshall is the first step of the project.

    Thank you, Roberta

    reply

  • Tom - 5 months ago

    Hi there, I would like to know What does this line of code means : maxint = (2**(0.size * 8 -2) -1) How did you even know what are the values for maxint?

    reply

  • Patsy - 1 month, 2 weeks ago

    Hi Tom, I was wondering myself. Here is some research: Fixnum holds Integer values that can be represented in a native machine word (minus 1 bit). If any operation on a Fixnum exceeds this range, the value is automatically converted to a Bignum.

    [2] pry(main)> 2 (0.size * 8 - 2) => 4611686018427387904 [3] pry(main)> (2 (0.size * 8 - 2)).class => Bignum [4] pry(main)> (2 ** (0.size * 8 - 2) - 1).class => Fixnum

    reply

  • super - 4 months, 3 weeks ago

    Hello!

    reply

  • viagra_sample - 4 months, 3 weeks ago

    Hello!

    reply

  • buy_cialis - 4 months, 3 weeks ago

    Hello!

    reply

  • without - 4 months ago

    Hello!

    reply

  • cialis - 4 months ago

    Hello!

    reply

  • generic viagra - 2 months, 1 week ago

    [url=http://www.genericmedshome.com/]generic viagra[/url] <a href=http://www.genericmedshome.com/>cheap viagra</a> http://www.genericmedshome.com/

    reply

  • girlsdoporn - 2 months ago

    Thanks for sharing this. There are many events which are celebrated all over the world. we have a website about mothers day event so have a look at it.

    reply

  • Point Of Sales - 3 days, 9 hours ago

    Your music is amazing. You have some very talented artists. I wish you the best of success.

    reply

  • Software Testing Training in Chennai - 2 months ago

    Informative article on Graph Theory. Thanks.

    reply

  • Buy Facebook Likes - 1 month, 4 weeks ago

    All the contents you mentioned in post is too good and can be very useful. I will keep it in mind, thanks for sharing the information keep updating, looking forward for more posts.Thanks

    reply

  • UK Courtesans Escorts London - 1 month, 4 weeks ago

    Your work is very good and I appreciate you and hopping for some more informative posts. Thank you for sharing great information to us.

    reply

  • Provillus Reviews - 1 month, 3 weeks ago

    I wish more authors of this type of content would take the time you did to research and write so well. I am very impressed with your vision and insight.

    reply

  • appethyl reviews - 1 month, 3 weeks ago

    Great info! I recently came across your blog and have been reading along. I thought I would leave my first comment. I don’t know what to say except that I have.

    reply

  • Every Graduate Student Needs Funding - 1 month, 3 weeks ago

    You actually make it look so easy with your performance but I find this matter to be actually.

    reply

  • list academy - 1 month, 3 weeks ago

    hello!! Very interesting discussion glad that I came across such informative post. Keep up the good work friend. Glad to be part of your net community.

    reply

  • http://holisticdentistrynews.yolasite.com - 1 month, 2 weeks ago

    As I am a programmer in Bioinformatics i would love to know about the programming using the Python language.I have got a good set of introduction over the topic. Good post. Nice way of making a beginner understand the language.

    reply

  • http://holisticdentistrynews.bravesites.com - 1 month, 2 weeks ago

    It's full of information I am looking for and I love to post a comment that "The content of your post is awesome" Great work!

    reply

  • oceanfront homes Miami - 1 month, 2 weeks ago

    I really enjoyed reading this post, big fan. Keep up the good work andplease tell me when can you publish more articles or where can I read more on the subject?

    reply

  • shed extra weight in weeks - 1 month, 2 weeks ago

    I found your this post while searching for information about blog-related research ... It's a good post .. keep posting and updating information.

    reply

  • fliptunes.net - Agar.Io Hack - 1 month, 2 weeks ago

    i was just browsing along and came upon your blog. just wanted to say good blog and this article really helped me.

    reply

  • Movie Tube - 1 month, 1 week ago

    Here you will learn what is important, it gives you a link to an interesting web page:

    reply

  • green smart living - 1 month, 1 week ago

    Such intelligent work on the subject and ideal way of writing here. I am really impressed! This post is a helpful overview of the particular topic and very actionable. Interesting approach!

    reply

  • support education - 1 month, 1 week ago

    This is very appealing, however , it is very important that will mouse click on the connection:

    reply

  • web developers london - 1 month, 1 week ago

    So lot to occur over your amazing blog. Your blog procures me a fantastic transaction of enjoyable.. Salubrious lot beside the scene.

    reply

  • Play darts games on the beach - 1 month, 1 week ago

    Thank you for taking the time to publish this information very useful!

    reply

  • Luxury media buying agency - 1 month, 1 week ago

    It's superior, however , check out material at the street address.

    reply

  • برش لیزر - 1 month ago

    I appreciate everything you have added to my knowledge base.Admiring the time and effort you put into your blog and detailed information you offer.Thanks.

    reply

  • Elk grove carpet cleaning - 1 month ago

    We are really grateful for your blog post. You will find a lot of approaches after visiting your post. I was exactly searching for. Thanks for such post and please keep it up.

    reply

  • Buying Hiking Boots - 1 month ago

    I really am no programmer but this will certainly spark the interest of my boyfriends brother, will pass it on to him.

    reply

  • Pick Boots for Backpacking - 1 month ago

    I implemented this in another language and the outcome is amazing, thank you for this code. Well done.

    reply

  • Needed Gear for Fishing - 1 month ago

    I tried to implement this into another language, but struggled a bit with the outcome, so reverted back to yours. Definitely one of my favorites.

    reply

  • The Best Fishing Footwear - 1 month ago

    I just love the python implementation, nothing better for me!! Love it.

    reply

  • The Perfect Shoes - 1 month ago

    Source codes are definitely not my forte, but loved reading this, some very helpful hints and tips in here, might just give it another go soon.

    reply

  • https://www.rebelmouse.com/textyourexback2review/ - 1 month ago

    Text Your Ex Back by Michael Fiore gives you instant, online access to a simple, step-by-step system in which Mike teaches you his powerful secrets, techniques, and unique method for quickly and easily reconnecting with your ex through the use of specially crafted text messages and texting formulas.

    reply

  • http://www.bbb.org/sdoc/business-reviews/mold-and- - 1 month ago

    I have bookmarked it and I am looking forward to reading new articles.I am really enjoying reading your well written articles. It looks like you spend a lot of effort and time on your blog.

    reply

  • youtube on fire - 4 weeks ago

    Nice post.It is really very good post.

    reply

  • Vera Bradley - 4 weeks ago

    Excellent .. Amazing .. I’ll bookmark your blog and take the feeds also…I’m happy to find so many useful info here in the post, we need work out more techniques in this regard, thanks for sharing.

    reply

  • elo boosting - 4 weeks ago

    Hi, I find reading this article a joy. It is extremely helpful and interesting and very much looking forward to reading more of your work..

    reply

  • Buying Hiking Boots - 3 weeks, 6 days ago

    Nice post.It is really very good post. Thank you

    reply

  • Pick Boots for Backpacking - 3 weeks, 6 days ago

    Really cool, not much of an expert on this, but trying my hand at it and this is super useful, thanks.

    reply

  • Needed Gear for Fishing - 3 weeks, 6 days ago

    Super and cool info given. Very useful, will definitely try my own spin on it.

    reply

  • The Best Fishing Footwear - 3 weeks, 6 days ago

    Absolutely amazing, love reading all the positive comments. Thank you for a great post.

    reply

  • The Perfect Shoes - 3 weeks, 6 days ago

    Very nice. Love this post, the info is amazing and really helpful. Thank you for a great site.

    reply

  • motor trade insurance brokers - 3 weeks, 5 days ago

    Paradoxically, baseding on electric motor trade specialists, the insurance coverage business could cut its losses by doing this.

    reply

  • http://orvmedia.com/index.php/component/k2/item/42 - 3 weeks, 5 days ago

    When it come to products carriers, which enjoy subsidized diesel and subsidized insurance coverage premiums, it doesn't obtain much better compared to this.

    reply

  • angelspeak.com.au - 3 weeks, 5 days ago

    We comprehend the insurance coverage demands of the electric motor profession and also would welcome the chance to recommend you even more.

    reply

  • ljmkala.com - 3 weeks, 5 days ago

    In charge of the insurance provider's picture as well as responsibility to insurance policy buying public and employers to prevent blunders.

    reply

  • Prepare Boots for Hiking - 3 weeks ago

    Really interesting, didn't quite think of it that way, really need to try this one. Thanks

    reply

  • Clothe shops Online - 3 weeks ago

    Very cool, will definitely need to pass this onto my students.

    reply

  • Quality Backpacking Shoes - 3 weeks ago

    Oh wow, this is really helpful, thank you for the insight.

    reply

  • Clothes for Hiking - 3 weeks ago

    I was looking for a quick answer for this. Thanks for posting this and making my life so much easier. Great blog.

    reply

  • Tips for a Wilderness Trip - 3 weeks ago

    Really interesting approach. Love your explanation, and approach, very simple actually, thanks.

    reply

  • https://www.rebelmouse.com/tinnitusmiraclesystem/ - 2 weeks, 4 days ago

    This site is a leading resource for information about the Thomas Coleman Tinnitus Miracle PDF book and complete tinnitus cure that teaches you unique and rare tips on how to naturally eliminate the ringing in your ears and keep it from ever coming back.

    reply

  • http://memoryhealer.angelfire.com/ - 2 weeks, 4 days ago

    Memory difficulties continue to worsen, there are significant personality changes, which require extensive help with customary daily activities. People in this Alzheimer's stage are not aware of recent experiences, events or their surroundings. They need to be taken care of for 24hr/day.

    reply

  • Carp Fishing Baits - 2 weeks, 2 days ago

    I found this post quite insightful and interesting, I'm not much of a tech person, but this is valuable.

    reply

  • preview - 2 weeks, 2 days ago

    The high-def videos and real demonstrations with women from the audience also mean you get to pick up on things like tone of voice, delivery, and body language which is something you just can't get from reading a typical ebook.

    reply

  • Hiking in Europe - 2 weeks, 2 days ago

    I saw a similar post a while ago, also helpful but didn't have as much detail as yours. Thank you for filling in the gaps that I missed. Great post.

    reply

  • Quality Fishing Alarms - 2 weeks, 2 days ago

    I have to admit that I didn't understand this too well, then I sat step by step and I'm glad to say you are a genius. Thank you so much for the info.

    reply

  • Super Hiking Boots - 2 weeks, 2 days ago

    Really interesting and informative. Well done on a great and interactive post. Love it.

    reply

  • slimfy reviews - 2 weeks, 2 days ago

    When people recuperate with this system, they get to determine how to compress excessive body fat and how to burn it for good.

    reply

  • electricity freedom system pdf - 2 weeks, 1 day ago

    Keep up the excellent work , I read few articles on this site and I think that your web blog is real interesting and Power to the People of excellent information.

    reply

  • Puja Kumari - 2 weeks ago

    Thanks for post this helpful post - Please visit for More information about: http://www.top9th.in/packers-and-movers-pune/ http://www.top9th.in/packers-and-movers-noida/ http://www.top9th.in/packers-and-movers-chennai/ http://www.top9th.in/packers-and-movers-kolkata/ http://www.top9th.in/packers-and-movers-ahmedabad/ http://www.top9th.in/packers-and-movers-surat/

    reply

  • Puja Kumari - 2 weeks ago

    Thanks for Nice and Informative Post. This article is really contains lot more information about This Topic http://www.top9th.in/packers-and-movers-bangalore/ http://www.top9th.in/packers-and-movers-hyderabad/ http://www.top9th.in/packers-and-movers-mumbai/ http://www.top9th.in/packers-and-movers-delhi/ http://www.top9th.in/packers-and-movers-gurgaon/ http://www.top9th.in/

    reply

  • Leer meer oor aasbote - 1 week, 6 days ago

    Best explanation I have found by far, and I have seen a few, thank you.

    reply

  • Aas Boot hengel - 1 week, 6 days ago

    Hi, Well, I actually was wonder what you are doing now. Your last sentence states your a soon to be graduate, obviously you graduated now, so now what? Did someone hire you?

    reply

  • Aasboot info - 1 week, 6 days ago

    Love this post. Definitely tried implementing it in another language, and it came out amazingly. Thank you for the advice and tips.

    reply

  • Buy backpacks online - 1 week, 6 days ago

    It just makes me super excited when I stumble upon a post like this, very interesting.

    reply

  • Outdoors accessories - 1 week, 6 days ago

    Love this, and I have so many colleagues that could benefit from this ;-) thank you

    reply

  • Knives - 1 week, 6 days ago

    Fantastic that a young mind such as yours can create this. Well done, and all the best of luck for the future.

    reply

  • Camping Gear - 1 week, 6 days ago

    Well done, this is quite interesting, very useful.

    reply

  • Outdoor clothing - 1 week, 6 days ago

    Scala, well no need to say more. Great post.

    reply

  • Outdoor back packs - 1 week, 6 days ago

    Very good catch on this. New in the industry and you have quite a good post here.

    reply

  • Luggage - 1 week, 6 days ago

    It was wondering if I could use this write-up on my other website, I will link it back to your website though.Great Thanks.

    reply

  • go to ebay.com - 1 week, 6 days ago

    If we ever pop off a vertex with maxint as the distance than we know there are no more paths to the source node so we can just return. If we try to pop off the heap with nothing there then smallest will be nil so we should also check for that as well.

    reply

  • nigerianpalsgist - 1 week, 5 days ago

    Your website is really cool and this is a great inspiring article.

    reply

  • parket - 1 week, 5 days ago

    Kwaliteitparket.nl is fabrikant en leverancier van verschillende soorten Parket, Massief parket, Traditionele Tapis parket vloeren, Bourgogne Parketvloeren, Design parketvloeren en Visgraat parketvloeren vloeren. Onze parketvloeren zijn alleen verkrijgbaar in verschillende houtsoorten, kwaliteiten, breedte en dikte. Doordat wij zelf ruwhout importeren en verwerken zijn wij in staat een zeer breed assortiment aan te bieden tegen de meest scherpe prijzen voor de beste kwaliteitsproducten.

    reply

  • how to eat foods that burn belly fat - 1 week, 4 days ago

    E-Factor Diet Review: Facts And Figures Every Consumer Should Know About John Rowley's Guide to Increase Your Fat Burning Hormones. Below you will find the important facts and figures I feel every consumer should know surrounding John Rowley's E-Factor Diet book and complete guide for taking necessary precautions and improve weight loss simultaneously.

    reply

  • Texas Charter Bus - 1 week, 4 days ago

    Great survey, I'm sure you're getting a great response.

    reply

  • carry-on - 1 week, 3 days ago

    You completed a few fine points there. I did a search on the subject and found nearly all persons will go along with with your blog.

    reply

  • orthodontic supplies - 1 week, 3 days ago

    Consumer graph is very complicated, the consumer buying process.

    reply

  • Useful activities darts - 1 week, 2 days ago

    Such a cool post, thank you for the codes, came in quite helpful.

    reply

  • Exclusionary rule for darts - 1 week, 2 days ago

    Love this post, even if it's a bit old, still helpful and cool.

    reply

  • The financial darts crisis - 1 week, 2 days ago

    Really helpful post, thanks for the data supplies. Great take on Python.

    reply

  • Re-evaluate what we've done darts - 1 week, 2 days ago

    Very interesting, thanks for the codes, came in super helpful. Def going to play with this one

    reply

  • Use games to teach darts - 1 week, 2 days ago

    Such a cool post. Thanks man for the codes. Very cool

    reply

  • Darts get things done - 1 week, 2 days ago

    Short and sweet and to the point, thank you.

    reply

  • Darts can give some cases - 1 week, 2 days ago

    So glad I didn't miss this, stumbled upon it by accident and super glad I did, seriously need to share.

    reply

  • Landscapes darts - 6 days, 20 hours ago

    Oh wow, you have an amazing brain, would actually be interested in using this code in another project, will let you know how it goes.

    reply

  • Darts have the same ways - 6 days, 19 hours ago

    Love this code, have been using it for a while now and found your post a week or so ago, best ever.

    reply

  • Darts and ammendments - 6 days, 19 hours ago

    Best ever, and I have seen a few posts on this before, you have really simplified it so anyone can use this code, well done.

    reply

  • Darts like online business - 6 days, 19 hours ago

    Well done on an excellent find. Fantastic posting and very useful

    reply

  • Darts for online - 6 days, 19 hours ago

    So informative and interesting, not much of a tech person myself but found this quite useful.

    reply

  • Darts are good - 6 days, 19 hours ago

    Gobsmacked at what you have done, great work

    reply

  • Darts and how they work - 6 days, 19 hours ago

    Fantastic post, well done and great job, absolutely loved reading this, will def forward.

    reply

  • tent overview - 6 days, 19 hours ago

    So, scala it was all along lol

    reply

  • tents view - 6 days, 19 hours ago

    Absolutely love scala, great post.

    reply

  • Tents chronicles - 6 days, 19 hours ago

    I just love this site, and this post has just been amazingly useful. Thank you so much

    reply

  • Camping Equipment - 6 days, 19 hours ago

    The functionality of this is quite outstanding, great job hey, you really do know what you are doing.

    reply

  • Camping Gear - 6 days, 19 hours ago

    Simple functions that can make a complicated problem so much easier, great article.

    reply

  • Camping Tents - 6 days, 19 hours ago

    I highly appreciate this post. I think you’ve nailed it! would you mind updating your blog with more information?

    reply

  • Anonymous - 4 days, 20 hours ago

    Mate this is a very nice blog here. I wanted to comment & say that I enjoyed reading your posts & they are all very well written out. You make blogging look easy lol I’ll attemp to start a blog later today and I hope it’s half as good as your blog! Much success to you! <a title="naked pictures" href="http://thefappening.wiki">naked pictures</a>

    reply

  • naked pictures - 4 days, 20 hours ago

    I Really Liked The Font You’ve Chose To Use In This Article. Could I Please Get The Name Of That Font ? I Wanted To Use It In My Project Now. Thanks Very Much!

    reply

  • Hostgator offers - 3 days, 17 hours ago

    Wow this post is awesome and very nice.

    reply

  • buy quality backlinks - 3 days, 7 hours ago

    Please continue this great work and I look forward to more of your awesome blog posts.

    reply

  • More info - 2 days, 17 hours ago

    Exceptional post, thanks so much for this

    reply

  • Click here - 2 days, 17 hours ago

    Such a cool post, amazing blog.

    reply

  • See here - 2 days, 17 hours ago

    Fabulous code, thank you so much dude

    reply

  • Learn more - 2 days, 17 hours ago

    Very cool code man, thanx so much for this, very helpful

    reply

  • Look here - 2 days, 17 hours ago

    Such a unique post, thanks for the code, love Scala

    reply

  • Good info - 2 days, 16 hours ago

    Excited to read this, very helpful with my project.

    reply

  • List idea - 2 days, 16 hours ago

    Scala is just the best, thanks so much, tried it on a different platform and it works wonders.

    reply

  • See here - 2 days, 16 hours ago

    Hi, just wanted to leave a quick comment, nice one

    reply

  • Click now - 2 days, 16 hours ago

    Such a deserving post, well done

    reply

  • carpet cleaners - 2 days, 9 hours ago

    You completed a few fine points there. I did a search on the subject and found nearly all persons will go along with with your blog.

    reply

  • gut dysbiosis treatment - 1 day, 21 hours ago

    Interesting and amazing how your post is! It Is Useful and helpful for me That I like it very much, and I am looking forward to Hearing from your next..

    reply

  • Zero Halliburton - 16 hours ago

    Its a great pleasure reading your post.Its full of information I am looking for and I love to post a comment that "The content of your post is awesome" Great work.

    reply

  • More info - 16 hours ago

    Really cool post, thank you for the info, very helpful

    reply

  • Click here - 16 hours ago

    Such an informative post, very useful, thanks so much for this.

    reply

  • See here - 16 hours ago

    Oh wow, you are amazing, thank you

    reply

  • Learn more - 16 hours ago

    Very informative post, thank you for the scala code.

    reply

  • Look here - 16 hours ago

    Really interesting what you did there, I see you lol. Thanks for the code and the info, great help

    reply

  • Click now - 16 hours ago

    Such a nice and explanatory post, thanks for the info, it really is quite helpful with my current project.

    reply

  • Good info - 15 hours ago

    Just love your explanation, thanks

    reply

  • Click - 15 hours ago

    Your are great, this really saved my life, great job

    reply

  • See here - 15 hours ago

    Fabulous explanation, very useful

    reply

  • List idea - 15 hours ago

    Such a great post, thank you, will definitely use it on my own code as well

    reply

  • This link - 15 hours ago

    Truly one of the best articles I have seen by far

    reply

  • girlfriend activation system v2 user reviews - 15 hours ago

    The tips and techniques taught inside the course cover all the skill-sets you need to become a true Boss with women and include things like inner game, approaching, getting numbers, asking women out, going on dates, texting, escalating to kissing and sex, and ultimately creating a long-term committed relationship.

    reply