Open In App

Parallel Dijkstra’s Algorithm: SSSP in Parallel

Last Updated : 30 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

The Parallel computing has become essential for solving computationally intensive problems efficiently. Dijkstra’s algorithm is a well-known graph algorithm used to find the shortest paths from a single source vertex to all other vertices in a graph. When dealing with large graphs and it becomes necessary to parallelize the algorithm to achieve faster results.

Approaches :

  • Data Parallelism using OpenMP
  • Task Parallelism using OpenMP

Approach 1: Data Parallelism using OpenMP

Divide the nodes into chunks and assign each chunk to the thread. Each thread computes the shortest path for its assigned nodes in the parallel.

Syntax:

#include <omp.h>

#pragma omp parallel for

for (int i = 0; i < num_nodes; ++i) {

// Compute shortest path for node i

}

Below is the implementation of the algorithm:

C++
#include <iostream>
#include <vector>
#include <limits>
#include <omp.h>
#define INF std::numeric_limits<int>::max()

void GFG(const std::vector<std::vector<int>>& graph, int start) {
    int num_nodes = graph.size();
    std::vector<int> dist(num_nodes, INF);
    std::vector<bool> visited(num_nodes, false);
    dist[start] = 0;
    #pragma omp parallel for
    for (int i = 0; i < num_nodes; ++i) {
        int u = -1, min_dist = INF;
        // Find the node with the shortest distance
        for (int j = 0; j < num_nodes; ++j) {
            if (!visited[j] && dist[j] < min_dist) {
                u = j;
                min_dist = dist[j];
            }
        }
        if (u == -1) break;
        // Relax adjacent nodes
        for (int v = 0; v < num_nodes; ++v) {
            if (!visited[v] && graph[u][v] && dist[u] + graph[u][v] < dist[v]) {
                dist[v] = dist[u] + graph[u][v];
            }
        }
        visited[u] = true;
    }
    // Print the shortest distances
    std::cout << "Vertex \t Distance from Source\n";
    for (int i = 0; i < num_nodes; ++i) {
        std::cout << i << "\t\t" << dist[i] << "\n";
    }
}
int main() {
    std::vector<std::vector<int>> graph = {
        {0, 4, 0, 0, 0, 0, 0, 8, 0},
        {4, 0, 8, 0, 0, 0, 0, 11, 0},
        {0, 8, 0, 7, 0, 4, 0, 0, 2},
        {0, 0, 7, 0, 9, 14, 0, 0, 0},
        {0, 0, 0, 9, 0, 10, 0, 0, 0},
        {0, 0, 4, 14, 10, 0, 2, 0, 0},
        {0, 0, 0, 0, 0, 2, 0, 1, 6},
        {8, 11, 0, 0, 0, 0, 1, 0, 7},
        {0, 0, 2, 0, 0, 0, 6, 7, 0}
    };
    GFG(graph, 0);
    return 0;
}
Java
import java.util.ArrayList;
import java.util.Arrays;

public class DijkstraAlgorithm {
    static final int INF = Integer.MAX_VALUE;

    static void dijkstra(ArrayList<ArrayList<Integer>> graph, int start) {
        int numNodes = graph.size();
        int[] dist = new int[numNodes];
        boolean[] visited = new boolean[numNodes];
        Arrays.fill(dist, INF);
        dist[start] = 0;

        for (int count = 0; count < numNodes - 1; count++) {
            int u = -1, minDist = INF;
            // Find the vertex with the minimum distance
            for (int v = 0; v < numNodes; v++) {
                if (!visited[v] && dist[v] < minDist) {
                    u = v;
                    minDist = dist[v];
                }
            }
            if (u == -1) break;
            visited[u] = true;
            // Update distances for adjacent vertices
            for (int v = 0; v < numNodes; v++) {
                if (!visited[v] && graph.get(u).get(v) != 0 &&
                        dist[u] != INF && dist[u] + graph.get(u).get(v) < dist[v]) {
                    dist[v] = dist[u] + graph.get(u).get(v);
                }
            }
        }
        // Print the shortest distances
        System.out.println("Vertex \t Distance from Source");
        for (int i = 0; i < numNodes; i++) {
            System.out.println(i + "\t\t" + dist[i]);
        }
    }

    public static void main(String[] args) {
        ArrayList<ArrayList<Integer>> graph = new ArrayList<>(Arrays.asList(
                new ArrayList<>(Arrays.asList(0, 4, 0, 0, 0, 0, 0, 8, 0)),
                new ArrayList<>(Arrays.asList(4, 0, 8, 0, 0, 0, 0, 11, 0)),
                new ArrayList<>(Arrays.asList(0, 8, 0, 7, 0, 4, 0, 0, 2)),
                new ArrayList<>(Arrays.asList(0, 0, 7, 0, 9, 14, 0, 0, 0)),
                new ArrayList<>(Arrays.asList(0, 0, 0, 9, 0, 10, 0, 0, 0)),
                new ArrayList<>(Arrays.asList(0, 0, 4, 14, 10, 0, 2, 0, 0)),
                new ArrayList<>(Arrays.asList(0, 0, 0, 0, 0, 2, 0, 1, 6)),
                new ArrayList<>(Arrays.asList(8, 11, 0, 0, 0, 0, 1, 0, 7)),
                new ArrayList<>(Arrays.asList(0, 0, 2, 0, 0, 0, 6, 7, 0))
        ));
        dijkstra(graph, 0);
    }
}

// This code is contributed by shivamgupta0987654321
Python3
import sys
from typing import List

# Define infinity as a large enough integer. This will represent 
#the maximum possible distance in the graph.
INF = sys.maxsize


def GFG(graph: List[List[int]], start: int):
    num_nodes = len(graph)
    dist = [INF] * num_nodes
    visited = [False] * num_nodes
    dist[start] = 0

    for _ in range(num_nodes):
        u = -1
        min_dist = INF

        # Find the node with the shortest distance
        for j in range(num_nodes):
            if not visited[j] and dist[j] < min_dist:
                u = j
                min_dist = dist[j]

        if u == -1:
            break

        # Relax adjacent nodes
        for v in range(num_nodes):
            if not visited[v] and graph[u][v] and dist[u] + graph[u][v] < dist[v]:
                dist[v] = dist[u] + graph[u][v]

        visited[u] = True

    # Print the shortest distances
    print("Vertex \t Distance from Source")
    for i in range(num_nodes):
        print(f"{i} \t\t {dist[i]}")


def main():
    graph = [
        [0, 4, 0, 0, 0, 0, 0, 8, 0],
        [4, 0, 8, 0, 0, 0, 0, 11, 0],
        [0, 8, 0, 7, 0, 4, 0, 0, 2],
        [0, 0, 7, 0, 9, 14, 0, 0, 0],
        [0, 0, 0, 9, 0, 10, 0, 0, 0],
        [0, 0, 4, 14, 10, 0, 2, 0, 0],
        [0, 0, 0, 0, 0, 2, 0, 1, 6],
        [8, 11, 0, 0, 0, 0, 1, 0, 7],
        [0, 0, 2, 0, 0, 0, 6, 7, 0]
    ]
    GFG(graph, 0)


if __name__ == "__main__":
    main()
JavaScript
function dijkstra(graph, start) {
    const INF = Number.MAX_SAFE_INTEGER;
    const numNodes = graph.length;
    const dist = new Array(numNodes).fill(INF);
    const visited = new Array(numNodes).fill(false);
    dist[start] = 0;

    for (let count = 0; count < numNodes - 1; count++) {
        let u = -1, minDist = INF;
        // Find the vertex with the minimum distance
        for (let v = 0; v < numNodes; v++) {
            if (!visited[v] && dist[v] < minDist) {
                u = v;
                minDist = dist[v];
            }
        }
        if (u === -1) break;
        visited[u] = true;
        // Update distances for adjacent vertices
        for (let v = 0; v < numNodes; v++) {
            if (!visited[v] && graph[u][v] !== 0 &&
                dist[u] !== INF && dist[u] + graph[u][v] < dist[v]) {
                dist[v] = dist[u] + graph[u][v];
            }
        }
    }
    // Print the shortest distances
    console.log("Vertex \t Distance from Source");
    for (let i = 0; i < numNodes; i++) {
        console.log(i + "\t\t" + dist[i]);
    }
}

// Driver code
const graph = [
    [0, 4, 0, 0, 0, 0, 0, 8, 0],
    [4, 0, 8, 0, 0, 0, 0, 11, 0],
    [0, 8, 0, 7, 0, 4, 0, 0, 2],
    [0, 0, 7, 0, 9, 14, 0, 0, 0],
    [0, 0, 0, 9, 0, 10, 0, 0, 0],
    [0, 0, 4, 14, 10, 0, 2, 0, 0],
    [0, 0, 0, 0, 0, 2, 0, 1, 6],
    [8, 11, 0, 0, 0, 0, 1, 0, 7],
    [0, 0, 2, 0, 0, 0, 6, 7, 0]
];
dijkstra(graph, 0);

Output
Vertex      Distance from Source
0        0
1        4
2        12
3        19
4        21
5        11
6        9
7        8
8        14

Approach 2: Task Parallelism using OpenMP

Create parallel tasks for the each node. Each task computes the shortest path for its assigned node independently.

Syntax:

#include <omp.h>

#pragma omp parallel

{

#pragma omp single nowait

{

for (int i = 0; i < num_nodes; ++i) {

#pragma omp task

{

// Compute shortest path for node i

}

}

}

}

Implementation :

C++
#include <iostream>
#include <limits>
#include <omp.h>
#include <vector>
#define INF std::numeric_limits<int>::max()

void GFG(const std::vector<std::vector<int> >& graph,
         int start)
{
    int num_nodes = graph.size();
    std::vector<int> dist(num_nodes, INF);
    std::vector<bool> visited(num_nodes, false);
    dist[start] = 0;
#pragma omp parallel
    {
#pragma omp single nowait
        {
            for (int i = 0; i < num_nodes; ++i) {
#pragma omp task
                {
                    int u = -1, min_dist = INF;
                    // Find the node with shortest distance
                    for (int j = 0; j < num_nodes; ++j) {
                        if (!visited[j]
                            && dist[j] < min_dist) {
                            u = j;
                            min_dist = dist[j];
                        }
                    }
                    if (u != -1) {
                        // The Relax adjacent nodes
                        for (int v = 0; v < num_nodes;
                             ++v) {
                            if (!visited[v] && graph[u][v]
                                && dist[u] + graph[u][v]
                                       < dist[v]) {
                                dist[v]
                                    = dist[u] + graph[u][v];
                            }
                        }

                        visited[u] = true;
                    }
                }
            }
        }
    }
    // Print the shortest distances
    std::cout << "Vertex \t Distance from Source\n";
    for (int i = 0; i < num_nodes; ++i) {
        std::cout << i << "\t\t" << dist[i] << "\n";
    }
}
int main()
{
    std::vector<std::vector<int> > graph
        = { { 0, 4, 0, 0, 0, 0, 0, 8, 0 },
            { 4, 0, 8, 0, 0, 0, 0, 11, 0 },
            { 0, 8, 0, 7, 0, 4, 0, 0, 2 },
            { 0, 0, 7, 0, 9, 14, 0, 0, 0 },
            { 0, 0, 0, 9, 0, 10, 0, 0, 0 },
            { 0, 0, 4, 14, 10, 0, 2, 0, 0 },
            { 0, 0, 0, 0, 0, 2, 0, 1, 6 },
            { 8, 11, 0, 0, 0, 0, 1, 0, 7 },
            { 0, 0, 2, 0, 0, 0, 6, 7, 0 } };
    GFG(graph, 0);
    return 0;
}
Java
import java.util.Arrays;
import java.util.List;

public class ShortestPath {
    // Define a constant for infinity value as there's no
    // direct equivalent in Java as in C++.
    private static final int INF = Integer.MAX_VALUE;

    public static void
    computePaths(List<List<Integer> > graph, int start)
    {
        int numNodes = graph.size();
        int[] dist
            = new int[numNodes]; // Distance array to store
                                 // the shortest path to
                                 // each vertex
        boolean[] visited
            = new boolean[numNodes]; // Boolean array to
                                     // track visited
                                     // vertices
        Arrays.fill(
            dist,
            INF); // Initialize all distances to infinity
        dist[start] = 0; // Distance from the start vertex
                         // to itself is always 0

        // Loop to find shortest path for all vertices
        for (int i = 0; i < numNodes; ++i) {
            int u = -1;
            int minDist = INF;
            // Find the unvisited vertex with the shortest
            // distance from the source
            for (int j = 0; j < numNodes; ++j) {
                if (!visited[j] && dist[j] < minDist) {
                    u = j;
                    minDist = dist[j];
                }
            }

            // If no vertex is found (u remains -1),
            // continue to the next iteration
            if (u == -1)
                continue;

            // Visit the vertex with the shortest distance
            // found in this iteration
            for (int v = 0; v < numNodes; ++v) {
                // Relax the edge if a shorter path through
                // u is found
                if (!visited[v] && graph.get(u).get(v) != 0
                    && dist[u] + graph.get(u).get(v)
                           < dist[v]) {
                    dist[v] = dist[u] + graph.get(u).get(v);
                }
            }

            // Mark the current node as visited
            visited[u] = true;
        }

        // Print the shortest distances from the source to
        // each vertex
        System.out.println(
            "Vertex \t Distance from Source");
        for (int i = 0; i < numNodes; ++i) {
            System.out.println(
                i + "\t\t"
                + (dist[i] == INF ? "Infinity" : dist[i]));
        }
    }

    public static void main(String[] args)
    {
        // Graph represented as an adjacency matrix
        List<List<Integer> > graph = Arrays.asList(
            Arrays.asList(0, 4, 0, 0, 0, 0, 0, 8, 0),
            Arrays.asList(4, 0, 8, 0, 0, 0, 0, 11, 0),
            Arrays.asList(0, 8, 0, 7, 0, 4, 0, 0, 2),
            Arrays.asList(0, 0, 7, 0, 9, 14, 0, 0, 0),
            Arrays.asList(0, 0, 0, 9, 0, 10, 0, 0, 0),
            Arrays.asList(0, 0, 4, 14, 10, 0, 2, 0, 0),
            Arrays.asList(0, 0, 0, 0, 0, 2, 0, 1, 6),
            Arrays.asList(8, 11, 0, 0, 0, 0, 1, 0, 7),
            Arrays.asList(0, 0, 2, 0, 0, 0, 6, 7, 0));

        // Call the function to compute the shortest paths
        // from vertex 0
        computePaths(graph, 0);
    }
}
Python3
import numpy as np

def GFG(graph, start):
    num_nodes = len(graph)
    dist = [float('inf')] * num_nodes
    visited = [False] * num_nodes
    dist[start] = 0

    for _ in range(num_nodes):
        u = -1
        min_dist = float('inf')
        # Find the node with shortest distance
        for j in range(num_nodes):
            if not visited[j] and dist[j] < min_dist:
                u = j
                min_dist = dist[j]

        if u != -1:
            # Relax adjacent nodes
            for v in range(num_nodes):
                if not visited[v] and graph[u][v] and dist[u] + graph[u][v] < dist[v]:
                    dist[v] = dist[u] + graph[u][v]

            visited[u] = True

    # Print the shortest distances
    print("Vertex \t Distance from Source")
    for i in range(num_nodes):
        print(i, "\t\t", dist[i])

if __name__ == "__main__":
    graph = [
        [0, 4, 0, 0, 0, 0, 0, 8, 0],
        [4, 0, 8, 0, 0, 0, 0, 11, 0],
        [0, 8, 0, 7, 0, 4, 0, 0, 2],
        [0, 0, 7, 0, 9, 14, 0, 0, 0],
        [0, 0, 0, 9, 0, 10, 0, 0, 0],
        [0, 0, 4, 14, 10, 0, 2, 0, 0],
        [0, 0, 0, 0, 0, 2, 0, 1, 6],
        [8, 11, 0, 0, 0, 0, 1, 0, 7],
        [0, 0, 2, 0, 0, 0, 6, 7, 0]
    ]
    GFG(graph, 0)

    # This code is contributed by Ayush Mishra
JavaScript
const INF = Number.MAX_SAFE_INTEGER;

function GFG(graph, start) {
    const num_nodes = graph.length;
    const dist = new Array(num_nodes).fill(INF);
    const visited = new Array(num_nodes).fill(false);
    dist[start] = 0;

    for (let i = 0; i < num_nodes; ++i) {
        let u = -1, min_dist = INF;

        // Find the node with shortest distance
        for (let j = 0; j < num_nodes; ++j) {
            if (!visited[j] && dist[j] < min_dist) {
                u = j;
                min_dist = dist[j];
            }
        }

        if (u !== -1) {
            // Relax adjacent nodes
            for (let v = 0; v < num_nodes; ++v) {
                if (!visited[v] && graph[u][v] && dist[u] + graph[u][v] < dist[v]) {
                    dist[v] = dist[u] + graph[u][v];
                }
            }

            visited[u] = true;
        }
    }

    // Print the shortest distances
    console.log("Vertex \t Distance from Source");
    for (let i = 0; i < num_nodes; ++i) {
        console.log(i + "\t\t" + dist[i]);
    }
}

const graph = [
    [0, 4, 0, 0, 0, 0, 0, 8, 0],
    [4, 0, 8, 0, 0, 0, 0, 11, 0],
    [0, 8, 0, 7, 0, 4, 0, 0, 2],
    [0, 0, 7, 0, 9, 14, 0, 0, 0],
    [0, 0, 0, 9, 0, 10, 0, 0, 0],
    [0, 0, 4, 14, 10, 0, 2, 0, 0],
    [0, 0, 0, 0, 0, 2, 0, 1, 6],
    [8, 11, 0, 0, 0, 0, 1, 0, 7],
    [0, 0, 2, 0, 0, 0, 6, 7, 0]
];

GFG(graph, 0);

Output
Vertex      Distance from Source
0        0
1        4
2        12
3        19
4        21
5        11
6        9
7        8
8        14




Similar Reads

Edge Relaxation Property for Dijkstra’s Algorithm and Bellman Ford's Algorithm
In the field of graph theory, various shortest path algorithms especially Dijkstra’s algorithm and Bellmann-Ford’s algorithm repeatedly employ the use of the technique called Edge Relaxation. The idea of relaxation is the same in both algorithms and it is by understanding, the 'Relaxation property' we can fully grasp the working of the two algorith
4 min read
Dijkstra's shortest path algorithm in Java using PriorityQueue
Dijkstra’s algorithm is very similar to Prim’s algorithm for minimum spanning tree. Like Prim’s MST, we generate a SPT (shortest path tree) with a given source as a root. We maintain two sets, one set contains vertices included in the shortest-path tree, other set includes vertices not yet included in the shortest-path tree. At every step of the al
5 min read
Widest Path Problem | Practical application of Dijkstra's Algorithm
It is highly recommended to read Dijkstra's algorithm using the Priority Queue first.Widest Path Problem is a problem of finding a path between two vertices of the graph maximizing the weight of the minimum-weight edge in the path. See the below image to get the idea of the problem: Practical Application Example: This problem is a famous variant of
10 min read
Applications of Dijkstra's shortest path algorithm
Dijkstra’s algorithm is one of the most popular algorithms for solving many single-source shortest path problems having non-negative edge weight in the graphs i.e., it is to find the shortest distance between two vertices on a graph. It was conceived by computer scientist Edsger W. Dijkstra in 1956 and published three years later. Dijkstra’s Algori
4 min read
Can we use Simple Queue instead of Priority queue to implement Dijkstra's Algorithm?
What is Dijkstra's Algorithm? Dijkstra's Algorithm is used for finding the shortest path between any two vertices of a graph. It uses a priority queue for finding the shortest path. For more detail, about Dijkstra's Algorithm, you can refer to this article. Why Dijkstra's Algorithm uses a Priority Queue? We use min heap in Dijkstra's Algorithm beca
2 min read
Why does Dijkstra's Algorithm fail on negative weights?
Dijkstra's Algorithm: It is a graph searching algorithm that uses a Greedy Approach to find the shortest path from the source node to all other remaining nodes. It solves the single-source shortest path problem for a weighted graph. This algorithm keeps track of the weights of the edges for finding the path that minimizes the total distance. Time C
4 min read
Dijkstra’s shortest path algorithm using set in STL
Given a graph and a source vertex in graph, find shortest paths from source to all vertices in the given graph. Input : Source = 0Output : Vertex Distance from Source 0 0 1 4 2 12 3 19 4 21 5 11 6 9 7 8 8 14We have discussed Dijkstra's shortest Path implementations. Dijkstra’s Algorithm for Adjacency Matrix Representation (In C/C++ with time comple
13 min read
Shortest path in a directed graph by Dijkstra’s algorithm
Given a directed graph and a source vertex in the graph, the task is to find the shortest distance and path from source to target vertex in the given graph where edges are weighted (non-negative) and directed from parent vertex to source vertices. Approach: Mark all vertices unvisited. Create a set of all unvisited vertices.Assign zero distance val
15 min read
Dijkstra’s Algorithm for Adjacency List Representation | Greedy Algo-8
We recommend reading the following two posts as a prerequisite for this post. Greedy Algorithms | Set 7 (Dijkstra’s shortest path algorithm) Graph and its representations We have discussed Dijkstra's algorithm and its implementation for adjacency matrix representation of graphs. The time complexity for the matrix representation is O(V^2). In this p
21 min read
Java Program for Dijkstra's Algorithm with Path Printing
import java.util.Scanner; //Scanner Function to take in the Input Values public class Dijkstra { static Scanner scan; // scan is a Scanner Object public static void main(String[] args) { int[] preD = new int[5]; int min = 999, nextNode = 0; // min holds the minimum value, nextNode holds the value for the next node. scan = new Scanner(System.in); in
2 min read
Article Tags :
Practice Tags :