Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Dijkstra's algorithm #428

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
kelvinlauKL merged 53 commits into kodecocodes:master from wow-such-amazing:dijkstra
Jun 20, 2017
Merged

Dijkstra's algorithm #428

kelvinlauKL merged 53 commits into kodecocodes:master from wow-such-amazing:dijkstra
Jun 20, 2017

Conversation

@wow-such-amazing
Copy link
Contributor

@wow-such-amazing wow-such-amazing commented Apr 4, 2017

No description provided.

Copy link
Contributor Author

should i change something?

Copy link
Member

@crabman448 checking it out now

Copy link
Member

@kelvinlauKL kelvinlauKL left a comment
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First of all, great work!

It's great to have one of the most famous algorithms written up for our repo.

The readme file needs a fair bit of work. I've left some more details below, but ideally you should give a mid to high level explanation of the interesting bits of the algorithm. Given the fame of this algorithm, there should be lots to write about.

In addition to the code level comments written below, I've got a few RW style guidelines I want to mention:

  • omit needless self references. You've got many of those in your implementations
  • extensions can give your code better readability for protocol conformances

The tool looks/sounds interesting. I won't be reviewing the code that implements it, but I'm looking forward to playing around with it!

Cheers!

@@ -0,0 +1,23 @@
# Dijkstra-algorithm
WWDC 2017 Scholarship Project
Created by [Taras Nikulin](https://github.com/crabman448)
Copy link
Member

@kelvinlauKL kelvinlauKL Apr 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put the credits at the bottom.


## About
Dijkstra's algorithm is used for finding shortest paths from start vertex in graph(with weighted vertices) to all other vertices.
More algorithm's description can be found in playground or on wikipedia:
Copy link
Member

@kelvinlauKL kelvinlauKL Apr 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dijkstra's algorithm is one of the most famous graph algorithms. Instead of giving a link to wikipedia, we'll want a bigger sample of what this algorithm is about.

Some things to talk about:

  • Why it is so often studied
  • Real life problems that it solves
  • A summary of how the algorithm works

More algorithm's description can be found in playground or on wikipedia:
[Wikipedia](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm)

To understand how does this algorithm works, I have created **VisualizedDijkstra.playground.** It works in auto and interactive modes. Moreover there are play/pause/stop buttons.
Copy link
Member

@kelvinlauKL kelvinlauKL Apr 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds cool, will check this out.


## Screenshots

<img src="Screenshots/screenshot1.jpg" height="400" />
Copy link
Member

@kelvinlauKL kelvinlauKL Apr 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These screenshots don't give me any context on what it's about. If this is just to showcase your visualization tool, 1 screenshot right below the paragraph where you introduce your tool is enough.

@@ -0,0 +1,137 @@
//: Playground - noun: a place where people can play

import Foundation
Copy link
Member

@kelvinlauKL kelvinlauKL Apr 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove unnecessary imports.

}

public static func ==(lhs: Vertex, rhs: Vertex) -> Bool {
if lhs.hashValue == rhs.hashValue {
Copy link
Member

@kelvinlauKL kelvinlauKL Apr 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if lhs.hashValue == rhs.hashValue {
 return true
}
return false

is equivalent to

return lhs.hashValue == rhs.hashValue


open class Vertex: Hashable, Equatable {

open var identifier: String!
Copy link
Member

@kelvinlauKL kelvinlauKL Apr 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this an implicitly unwrapped optional (IUO)?


open var identifier: String!
open var neighbors: [(Vertex, Double)] = []
open var pathLengthFromStart: Double = Double.infinity
Copy link
Member

@kelvinlauKL kelvinlauKL Apr 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Double type can be inferred from Double.infinity, no need to do explicit typing.

}
}

public class Dijkstra {
Copy link
Member

@kelvinlauKL kelvinlauKL Apr 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As with Vertex, let's put Dijkstra in it's own file in the Sources directory.

startVertex.pathLengthFromStart = 0
startVertex.pathVerticesFromStart.append(startVertex)
var currentVertex: Vertex! = startVertex
while currentVertex != nil {
Copy link
Member

@kelvinlauKL kelvinlauKL Apr 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method depending on an IUO (implicitly unwrapped optional) makes me nervous.

For starters, instead of using Vertex!, you can have it as Vertex? and achieve the same looping logic:

while let vertex = currentVertex { ... }

Try to refactor this method based on that.

Copy link
Contributor Author

Thank you for your comments! 👍
I will fix it as soon as possible :)

Taras Nikulin added 20 commits April 17, 2017 12:11
This reverts commit a153067.
This reverts commit 3f6be33.
This reverts commit a153067.
Copy link
Member

@kelvinlauKL kelvinlauKL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few more comments on your latest change.

//: Playground - noun: a place where people can play
import Foundation

var _vertices: Set<Vertex> = Set()
Copy link
Member

@kelvinlauKL kelvinlauKL Apr 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason for the _ in front of this variable name?

@@ -0,0 +1,45 @@
# Dijkstra-algorithm

## About this repository
Copy link
Member

@kelvinlauKL kelvinlauKL Apr 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put the About, Demo Video, and Screenshots section at the bottom of this file.


<img src="Images/Dijkstra_Animation.gif" height="250" />

[Wikipedia](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm)'s explanation:
Copy link
Member

@kelvinlauKL kelvinlauKL Apr 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't just copy from Wikipedia. If it helps, you can quote a small paragraph from it, but most of the writing should be in your own words.

What you've put here is the procedure of Dijkstra's algorithm. Before talking about the procedure, you need to talk about what the algorithm is, and what it will solve. I suggest you take some inspiration from this article: https://github.com/raywenderlich/swift-algorithm-club/tree/master/Merge%20Sort


## Dijkstra's algorithm explanation

<img src="Images/Dijkstra_Animation.gif" height="250" />
Copy link
Member

@kelvinlauKL kelvinlauKL Apr 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This diagram needs more context for the reader.

Consider that the reader is new and first opens this article. That person wouldn't and shouldn't know what this diagram is. You'll want to place this diagram in between an explanation to give it context.

Copy link
Contributor Author

Will improve it in a couple days. Thank you again! : )

Copy link
Member

@kelvinlauKL kelvinlauKL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @crabman448,

Great improvements overall, but the explanations still need some work! I've left some comments that I feel would greatly improve this article.

For now, let's focus on polishing the first half of your readme. Some things to keep a note of:

  • grammar
  • punctuation
  • spelling mistakes

There are many of these in the readme. Try to fix those as you're making changes.


Let's imagine, you want to go to the shop. Your house is A vertex and there are 4 possible stores around your house. How to find the closest one/ones? Luckily, you have graph, that connects your house with all these stores. So, you know what to do :)

## Initialization
Copy link
Member

@kelvinlauKL kelvinlauKL May 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename this to "Example" instead. Initialization doesn't mean anything to the reader for this section.


I have created **VisualizedDijkstra.playground** to improve your understanding of the algorithm's flow. Besides, below is step by step algorithm's description.

Let's imagine, you want to go to the shop. Your house is A vertex and there are 4 possible stores around your house. How to find the closest one/ones? Luckily, you have graph, that connects your house with all these stores. So, you know what to do :)
Copy link
Member

@kelvinlauKL kelvinlauKL May 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's focus on 1 example, you mentioned that you wanted to find the shortest path from your house to your job.


## Initialization

When the algorithm starts to work initial graph looks like this:
Copy link
Member

@kelvinlauKL kelvinlauKL May 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sentence doesn't make sense.

In the intro, your example was about going from your house to your [job] company office. It'll read much better to refocus the reader on that example.

This diagram is a bit too noisy to start off with. Let's simplify it a bit. For instance, you could start without the weights of the graph:

screen shot 2017年05月01日 at 5 16 53 pm

Explain what the lines are, and what the circles represents.


<img src="Images/image1.png" height="250" />

The table below represents graph state:
Copy link
Member

@kelvinlauKL kelvinlauKL May 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of jumping straight to a table, gradually warm up the reader by introducing the concept of a weighted graph. This is where you update your diagram with more information:

screen shot 2017年05月01日 at 5 17 56 pm

For simplicity, tell the reader this is only a one way street (directed graph).

| Visited | F | F | F | F | F |
| Path Length From Start | inf | inf | inf | inf | inf |
| Path Vertices From Start | [ ] | [ ] | [ ] | [ ] | [ ] |

Copy link
Member

@kelvinlauKL kelvinlauKL May 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before you introduce this table for computing Dijkstra's algorithm, its sometimes helpful to give the reader a concrete goal to think about. Tell them their goal is to find the shortest path from A to E:

screen shot 2017年05月01日 at 5 25 11 pm

Afterwards, you can talk about how to reason about it. That's where the table comes into play.

Then we check all of its neighbors.
If checking vertex path length from start + edge weigth is smaller than neighbor's path length from start, then we set neighbor's path length from start new value and append to its pathVerticesFromStart array new vertex: checkingVertex. Repeat this action for every vertex.

for clarity:
Copy link
Member

@kelvinlauKL kelvinlauKL May 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Diagrams here will help a lot. You could do something like this:

screen shot 2017年05月01日 at 5 31 24 pm

This diagram focuses the reader on what you're currently trying to show (the path from A to B), while phasing out everything else. You'll leave the goal (Vertex E) in plain sight to remind the reader of the goal.


<img src="Images/image3.png" height="250" />

And its state is here:
Copy link
Member

@kelvinlauKL kelvinlauKL May 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Thanks a lot again) But I'm not agree with concept, that it would be better to use directed graph. Because, about 2 months ago I was looking for algorithm, that will be possible to use in not directed graph. And I thought, that Dijkstra won't satisfy my requirements, because explanations mostly used directed graphs, but I needed to go in both directions on every edge.
Maybe it would be better to add both directed and not directed graph explanations?

Copy link
Member

Interesting. Dijkstra's algorithm should be functionally identical for both undirected and directed graphs. I can't picture why you would want to go in both directions for every edge. You'd never want to travel back and forth since that only increases your total distance.

Could you explain why you needed to go in both directions using Dijkstra's?

Copy link
Contributor Author

wow-such-amazing commented May 2, 2017
edited
Loading

In my app I have a graph, that is not directed at all. You can go in both directions on every edge. And when I was searching for suitable algorithm, I've seen some explanations with directed graph and I was like: "That won't work in my case, because I have not directed weighted graph". But it would, because it works for not directed graphs to.

Copy link
Contributor Author

wow-such-amazing commented May 2, 2017
edited
Loading

In a park, for example, people can go in both directions on footpaths.

Copy link
Member

Let's take this step by step. If you want to find the shortest path between 2 vertexes in a graph, would you ever want to travel down a single undirected edge more than once?

Copy link
Contributor Author

wow-such-amazing commented May 3, 2017
edited
Loading

Probably I won't. But I don't know whether i'll travel up or down an edge. So it doesn't make sense to create directed graph with both directions on every edge.

Copy link
Member

Can you elaborate on that? One of the most common ways to represent an undirected graph is to use a directed graph where every edge is paired with another edge going in the opposite direction.

Copy link
Contributor Author

But why? It is extra work, isn't it? :)

Copy link
Contributor Author

If I have not directed graph, why should I make it directed?

Copy link
Member

@crabman448 I took a look at your implementation, here's what I mean:

func setupConnections() {
 // ...
 let neighbor1 = (neighborVertex, randomWeight)
 let neighbor2 = (vertex, randomWeight)
 vertex.neighbors.append(neighbor1)
 neighborVertex.neighbors.append(neighbor2)
}

neighbor1 and neighbor2 are your directed edges. They represent the destination and the weight of the edge. Your undirected graph is built by using a pair of directed edges. Every connection you make is done by adding a pair of edges.

You're right about it being extra work - hence I suggest we base the explanation based on a directed graph.

To create a directed graph, all you need to do is remove one of the pairs:

func setupConnections() {
 // ...
 let neighbor1 = (neighborVertex, randomWeight)
 vertex.neighbors.append(neighbor1)
}

Now your graph is a directed graph, with exactly half as many edges than your previous undirected graph. I recommend reading our tutorial on adjacency lists for more info.

Copy link
Contributor Author

wow-such-amazing commented May 3, 2017
edited
Loading

Hmm, got you)
"In an undirected graph, you can treat it as a directed graph that goes both ways."
So, when all graph's edges are bidirectional, then it is still directed graph? And there is no other way to achieve such behaviour?

Copy link
Member

Yes

An undirected graph is a directed graph where every edge has another edge going in the opposite direction

  • All undirected graphs can be viewed as a directed graph.
  • A directed graph is undirected if and only if every edge is paired with an edge going in the opposite direction

Copy link
Contributor Author

Things have become clearer)) Thank you again. I will mention this statement in the beginning of the readme.

kelvinlauKL reacted with hooray emoji

Copy link
Contributor Author

I'm currently busy with my graduating project in the university. I'll fix description as soon as I will have enough time)

kelvinlauKL reacted with thumbs up emoji

Copy link
Contributor

scha00 commented May 22, 2017

Awesome work. I can see both of you are diligently making progress over many days. Looking forward to see this completed.

rrecio reacted with thumbs up emoji

Copy link
Contributor Author

wow-such-amazing commented May 24, 2017
edited
Loading

I'm back now :)
Hope, that I will finish in a couple of days.

Copy link
Contributor Author

wow-such-amazing commented May 24, 2017
edited
Loading

I've added some general concepts about graphs, but I would like to use example with shops and choosing the closest one of them, because it correlates better with Dijkstra's algorithm: Shortest paths from source vertex to all others.
I'll check grammar, punctuation and spelling mistakes soon)

kelvinlauKL reacted with thumbs up emoji

Copy link
Contributor Author

wow-such-amazing commented Jun 12, 2017
edited
Loading

@kelvinlauKL I've checked grammar etc and hope it is ready for merge now :)

Copy link
Member

Nice. I just did a quick read and it's shaping up very nicely. Great improvements!

I'll do a more thorough review in the next few days.

Copy link
Member

Woot, I had a chance to read over it. It's much nicer than before. This is ready for a merge.

I think there's still lots of room for improvement in areas like readability, so if you have time, consider spending more time improving the readme files. Thanks @crabman448!

wow-such-amazing and rrecio reacted with hooray emoji

@kelvinlauKL kelvinlauKL merged commit 5f4e339 into kodecocodes:master Jun 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@kelvinlauKL kelvinlauKL kelvinlauKL requested changes

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /