-
-
Notifications
You must be signed in to change notification settings - Fork 155
dijkstra algo added #602
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
Merged
dijkstra algo added #602
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"label": "Algorithms", | ||
"position": 7, | ||
"link": { | ||
"type": "generated-index", | ||
"description": "In This section all the Algorithms are defined in DSA for graphs,trees,DP are meant to be added" | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,365 @@ | ||
--- | ||
id: dijkstra | ||
title: Dijkstra's Algorithm | ||
sidebar_label: Dijkstra's Algorithm | ||
tags: [python, java, c++, javascript, programming, algorithms, dijkstra, graph, shortest-path, data structures, tutorial, in-depth] | ||
description: In this tutorial, we will learn about Dijkstra's Algorithm and its implementation in Python, Java, C++, and JavaScript with detailed explanations and examples. | ||
--- | ||
|
||
# Dijkstra's Algorithm | ||
|
||
Dijkstra's Algorithm is a popular algorithm used for finding the shortest paths between nodes in a graph. This tutorial will cover the basics of Dijkstra's Algorithm, its applications, and how to implement it in Python, Java, C++, and JavaScript. We will also delve into various optimizations and advanced use cases. | ||
|
||
## Introduction to Dijkstra's Algorithm | ||
|
||
Dijkstra's Algorithm was conceived by computer scientist Edsger W. Dijkstra in 1956. It is used to find the shortest path from a starting node to all other nodes in a weighted graph, where the weights represent the cost to traverse from one node to another. | ||
|
||
## How Dijkstra's Algorithm Works | ||
|
||
- **Initialization**: Start with a set of nodes. Assign a tentative distance value to every node: set it to zero for the initial node and to infinity for all other nodes. Set the initial node as the current node. | ||
- **Visit Neighbors**: For the current node, consider all its unvisited neighbors and calculate their tentative distances. Compare the newly calculated tentative distance to the current assigned value and assign the smaller one. | ||
- **Mark Visited**: Once all neighbors are visited, mark the current node as visited. A visited node will not be checked again. | ||
- **Select Next Node**: Select the unvisited node that is marked with the smallest tentative distance and set it as the new current node. | ||
- **Repeat**: Continue the process until all nodes have been visited. | ||
|
||
 | ||
|
||
## Pseudocode for Dijkstra's Algorithm | ||
|
||
Here is the pseudocode for Dijkstra's Algorithm: | ||
|
||
``` | ||
function Dijkstra(Graph, source): | ||
create vertex set Q | ||
|
||
for each vertex v in Graph: | ||
dist[v] ← INFINITY | ||
prev[v] ← UNDEFINED | ||
add v to Q | ||
dist[source] ← 0 | ||
|
||
while Q is not empty: | ||
u ← vertex in Q with min dist[u] | ||
remove u from Q | ||
|
||
for each neighbor v of u: | ||
alt ← dist[u] + length(u, v) | ||
if alt < dist[v]: | ||
dist[v] ← alt | ||
prev[v] ← u | ||
|
||
return dist[], prev[] | ||
``` | ||
|
||
## Implementing Dijkstra's Algorithm | ||
|
||
### Python Implementation | ||
|
||
```python | ||
import heapq | ||
|
||
def dijkstra(graph, start): | ||
priority_queue = [(0, start)] | ||
distances = {vertex: float('infinity') for vertex in graph} | ||
distances[start] = 0 | ||
previous_nodes = {vertex: None for vertex in graph} | ||
|
||
while priority_queue: | ||
current_distance, current_vertex = heapq.heappop(priority_queue) | ||
|
||
if current_distance > distances[current_vertex]: | ||
continue | ||
|
||
for neighbor, weight in graph[current_vertex].items(): | ||
distance = current_distance + weight | ||
|
||
if distance < distances[neighbor]: | ||
distances[neighbor] = distance | ||
previous_nodes[neighbor] = current_vertex | ||
heapq.heappush(priority_queue, (distance, neighbor)) | ||
|
||
return distances, previous_nodes | ||
|
||
def shortest_path(graph, start, goal): | ||
distances, previous_nodes = dijkstra(graph, start) | ||
path = [] | ||
while goal: | ||
path.append(goal) | ||
goal = previous_nodes[goal] | ||
return path[::-1] | ||
|
||
graph = { | ||
'A': {'B': 1, 'C': 4}, | ||
'B': {'A': 1, 'C': 2, 'D': 5}, | ||
'C': {'A': 4, 'B': 2, 'D': 1}, | ||
'D': {'B': 5, 'C': 1} | ||
} | ||
|
||
print(shortest_path(graph, 'A', 'D')) | ||
``` | ||
|
||
### Java Implementation | ||
|
||
```java | ||
import java.util.*; | ||
|
||
public class Dijkstra { | ||
|
||
public static void dijkstra(Map<String, Map<String, Integer>> graph, String start) { | ||
PriorityQueue<Node> priorityQueue = new PriorityQueue<>(Comparator.comparingInt(node -> node.distance)); | ||
Map<String, Integer> distances = new HashMap<>(); | ||
Map<String, String> previousNodes = new HashMap<>(); | ||
|
||
for (String vertex : graph.keySet()) { | ||
distances.put(vertex, Integer.MAX_VALUE); | ||
previousNodes.put(vertex, null); | ||
} | ||
distances.put(start, 0); | ||
priorityQueue.add(new Node(start, 0)); | ||
|
||
while (!priorityQueue.isEmpty()) { | ||
Node current = priorityQueue.poll(); | ||
|
||
if (current.distance > distances.get(current.name)) { | ||
continue; | ||
} | ||
|
||
for (Map.Entry<String, Integer> neighbor : graph.get(current.name).entrySet()) { | ||
int distance = current.distance + neighbor.getValue(); | ||
|
||
if (distance < distances.get(neighbor.getKey())) { | ||
distances.put(neighbor.getKey(), distance); | ||
previousNodes.put(neighbor.getKey(), current.name); | ||
priorityQueue.add(new Node(neighbor.getKey(), distance)); | ||
} | ||
} | ||
} | ||
|
||
for (Map.Entry<String, Integer> entry : distances.entrySet()) { | ||
System.out.println(entry.getKey() + " : " + entry.getValue()); | ||
} | ||
} | ||
|
||
public static List<String> shortestPath(Map<String, Map<String, Integer>> graph, String start, String goal) { | ||
dijkstra(graph, start); | ||
List<String> path = new ArrayList<>(); | ||
for (String at = goal; at != null; at = previousNodes.get(at)) { | ||
path.add(at); | ||
} | ||
Collections.reverse(path); | ||
return path; | ||
} | ||
|
||
public static void main(String[] args) { | ||
Map<String, Map<String, Integer>> graph = new HashMap<>(); | ||
graph.put("A", Map.of("B", 1, "C", 4)); | ||
graph.put("B", Map.of("A", 1, "C", 2, "D", 5)); | ||
graph.put("C", Map.of("A", 4, "B", 2, "D", 1)); | ||
graph.put("D", Map.of("B", 5, "C", 1)); | ||
|
||
System.out.println(shortestPath(graph, "A", "D")); | ||
} | ||
|
||
static class Node { | ||
String name; | ||
int distance; | ||
|
||
Node(String name, int distance) { | ||
this.name = name; | ||
this.distance = distance; | ||
} | ||
} | ||
} | ||
``` | ||
|
||
### C++ Implementation | ||
|
||
```cpp | ||
#include <iostream> | ||
#include <vector> | ||
#include <unordered_map> | ||
#include <queue> | ||
#include <stack> | ||
#include <limits> | ||
#include <algorithm> | ||
|
||
using namespace std; | ||
|
||
typedef pair<int, int> Node; | ||
typedef unordered_map<string, unordered_map<string, int>> Graph; | ||
|
||
unordered_map<string, int> dijkstra(const Graph& graph, const string& start, unordered_map<string, string>& previousNodes) { | ||
unordered_map<string, int> distances; | ||
for (const auto& node : graph) { | ||
distances[node.first] = numeric_limits<int>::max(); | ||
} | ||
distances[start] = 0; | ||
|
||
auto cmp = [](Node left, Node right) { return left.second > right.second; }; | ||
priority_queue<Node, vector<Node>, decltype(cmp)> priorityQueue(cmp); | ||
priorityQueue.push({start, 0}); | ||
|
||
while (!priorityQueue.empty()) { | ||
string current = priorityQueue.top().first; | ||
int currentDistance = priorityQueue.top().second; | ||
priorityQueue.pop(); | ||
|
||
if (currentDistance > distances[current]) { | ||
continue; | ||
} | ||
|
||
for (const auto& neighbor : graph.at(current)) { | ||
int distance = currentDistance + neighbor.second; | ||
if (distance < distances[neighbor.first]) { | ||
distances[neighbor.first] = distance; | ||
previousNodes[neighbor.first] = current; | ||
priorityQueue.push({neighbor.first, distance}); | ||
} | ||
} | ||
} | ||
|
||
return distances; | ||
} | ||
|
||
vector<string> shortestPath(const Graph& graph, const string& start, const string& goal) { | ||
unordered_map<string, string> previousNodes; | ||
dijkstra(graph, start, previousNodes); | ||
|
||
vector<string> path; | ||
for (string at = goal; !at.empty(); at = previousNodes[at]) { | ||
path.push_back(at); | ||
} | ||
reverse(path.begin(), path.end()); | ||
return path; | ||
} | ||
|
||
int main() { | ||
Graph graph = { | ||
{"A", {{"B", 1}, {"C", 4}}}, | ||
{"B", {{"A", 1}, {"C", 2}, {"D", 5}}}, | ||
{"C", {{"A", 4}, {"B", 2}, {"D", 1}}}, | ||
{"D", {{"B", 5}, {"C", 1}}} | ||
}; | ||
|
||
vector<string> path = shortestPath(graph, "A", "D"); | ||
for (const string& node : path) { | ||
cout << node << " "; | ||
} | ||
cout << endl; | ||
return 0; | ||
} | ||
``` | ||
|
||
### JavaScript Implementation | ||
|
||
```javascript | ||
function dijkstra(graph, start) { | ||
let distances = {}; | ||
let previousNodes = {}; | ||
let priorityQueue = new PriorityQueue(); | ||
|
||
for (let vertex in graph) { | ||
if (vertex === start) { | ||
distances[vertex] = 0; | ||
priorityQueue.enqueue(vertex, 0); | ||
} else { | ||
|
||
|
||
distances[vertex] = Infinity; | ||
priorityQueue.enqueue(vertex, Infinity); | ||
} | ||
previousNodes[vertex] = null; | ||
} | ||
|
||
while (!priorityQueue.isEmpty()) { | ||
let currentVertex = priorityQueue.dequeue().element; | ||
|
||
for (let neighbor in graph[currentVertex]) { | ||
let distance = distances[currentVertex] + graph[currentVertex][neighbor]; | ||
if (distance < distances[neighbor]) { | ||
distances[neighbor] = distance; | ||
previousNodes[neighbor] = currentVertex; | ||
priorityQueue.enqueue(neighbor, distance); | ||
} | ||
} | ||
} | ||
|
||
return { distances, previousNodes }; | ||
} | ||
|
||
function shortestPath(graph, start, goal) { | ||
let { distances, previousNodes } = dijkstra(graph, start); | ||
let path = []; | ||
while (goal) { | ||
path.push(goal); | ||
goal = previousNodes[goal]; | ||
} | ||
return path.reverse(); | ||
} | ||
|
||
class PriorityQueue { | ||
constructor() { | ||
this.values = []; | ||
} | ||
|
||
enqueue(element, priority) { | ||
this.values.push({ element, priority }); | ||
this.sort(); | ||
} | ||
|
||
dequeue() { | ||
return this.values.shift(); | ||
} | ||
|
||
isEmpty() { | ||
return this.values.length === 0; | ||
} | ||
|
||
sort() { | ||
this.values.sort((a, b) => a.priority - b.priority); | ||
} | ||
} | ||
|
||
let graph = { | ||
'A': { 'B': 1, 'C': 4 }, | ||
'B': { 'A': 1, 'C': 2, 'D': 5 }, | ||
'C': { 'A': 4, 'B': 2, 'D': 1 }, | ||
'D': { 'B': 5, 'C': 1 } | ||
}; | ||
|
||
console.log(shortestPath(graph, 'A', 'D')); | ||
``` | ||
|
||
## Applications of Dijkstra's Algorithm | ||
|
||
- **Network Routing**: Finding the shortest path in network routing protocols such as OSPF. | ||
- **Map Services**: Computing the shortest routes in map services like Google Maps. | ||
- **Robotics**: Pathfinding in autonomous robots to navigate through environments. | ||
- **Game Development**: Pathfinding for game AI to navigate through game worlds. | ||
|
||
## Advanced Topics and Optimizations | ||
|
||
### Bidirectional Dijkstra | ||
|
||
Bidirectional Dijkstra runs two simultaneous searches: one forward from the source and one backward from the target. This can significantly speed up the search in large graphs. | ||
|
||
### Time Complexity | ||
|
||
The time complexity of Dijkstra's Algorithm depends on the data structures used: | ||
- Using a simple list: O(V^2) | ||
- Using a binary heap (priority queue): O((V + E) log V) | ||
Yashgabani845 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- Using a Fibonacci heap: O(V log V + E) | ||
Yashgabani845 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### Handling Negative Weights | ||
|
||
Dijkstra's Algorithm does not work with graphs that have negative weights. For such graphs, the Bellman-Ford Algorithm or Johnson's Algorithm can be used. | ||
|
||
### Path Reconstruction | ||
|
||
To reconstruct the shortest path from the source to a target node, we can backtrack from the target node using the `previous_nodes` dictionary. | ||
|
||
## Conclusion | ||
|
||
In this tutorial, we covered the fundamentals of Dijkstra's Algorithm, its implementation in Python, Java, C++, and JavaScript, and various optimizations and applications. Dijkstra's Algorithm is a powerful tool for finding the shortest path in graphs and is widely used in numerous domains. By mastering this algorithm, you can effectively solve a variety of shortest path problems in your projects. | ||
|
||
Happy coding! | ||
Yashgabani845 marked this conversation as resolved.
Show resolved
Hide resolved
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.