GeeksforGeeks App
Open App
Browser
Continue

# Uniform-Cost Search (Dijkstra for large Graphs)

Uniform-Cost Search is a variant of Dijikstra’s algorithm. Here, instead of inserting all vertices into a priority queue, we insert only the source, then one by one insert when needed. In every step, we check if the item is already in the priority queue (using the visited array). If yes, we perform the decrease key, else we insert it.

This variant of Dijkstra is useful for infinite graphs and that graph which are too large to represent in memory. Uniform-Cost Search is mainly used in Artificial Intelligence.

Examples:

`Input :`

```Output :
Minimum cost from S to G is =3```

Uniform-Cost Search is similar to Dijikstra’s algorithm. In this algorithm from the starting state, we will visit the adjacent states and will choose the least costly state then we will choose the next least costly state from the all un-visited and adjacent states of the visited states, in this way we will try to reach the goal state (note we won’t continue the path through a goal state ), even if we reach the goal state we will continue searching for other possible paths( if there are multiple goals). We will keep a priority queue that will give the least costly next state from all the adjacent states of visited states.

## C++

 `// C++ implementation of above approach` `#include ` `using` `namespace` `std;` `// graph``vector > graph;` `// map to store cost of edges``map, ``int``> cost;` `// returns the minimum cost in a vector( if``// there are multiple goal states)``vector<``int``> uniform_cost_search(vector<``int``> goal, ``int` `start)``{``    ``// minimum cost upto``    ``// goal state from starting``    ``// state``    ``vector<``int``> answer;` `    ``// create a priority queue``    ``priority_queue > queue;` `    ``// set the answer vector to max value``    ``for` `(``int` `i = 0; i < goal.size(); i++)``        ``answer.push_back(INT_MAX);` `    ``// insert the starting index``    ``queue.push(make_pair(0, start));` `    ``// map to store visited node``    ``map<``int``, ``int``> visited;` `    ``// count``    ``int` `count = 0;` `    ``// while the queue is not empty``    ``while` `(queue.size() > 0) {` `        ``// get the top element of the``        ``// priority queue``        ``pair<``int``, ``int``> p = queue.top();` `        ``// pop the element``        ``queue.pop();` `        ``// get the original value``        ``p.first *= -1;` `        ``// check if the element is part of``        ``// the goal list``        ``if` `(find(goal.begin(), goal.end(), p.second) != goal.end()) {` `            ``// get the position``            ``int` `index = find(goal.begin(), goal.end(),``                             ``p.second) - goal.begin();` `            ``// if a new goal is reached``            ``if` `(answer[index] == INT_MAX)``                ``count++;` `            ``// if the cost is less``            ``if` `(answer[index] > p.first)``                ``answer[index] = p.first;` `            ``// pop the element``            ``queue.pop();` `            ``// if all goals are reached``            ``if` `(count == goal.size())``                ``return` `answer;``        ``}` `        ``// check for the non visited nodes``        ``// which are adjacent to present node``        ``if` `(visited[p.second] == 0)``            ``for` `(``int` `i = 0; i < graph[p.second].size(); i++) {` `                ``// value is multiplied by -1 so that``                ``// least priority is at the top``                ``queue.push(make_pair((p.first +``                  ``cost[make_pair(p.second, graph[p.second][i])]) * -1,``                  ``graph[p.second][i]));``            ``}` `        ``// mark as visited``        ``visited[p.second] = 1;``    ``}` `    ``return` `answer;``}` `// main function``int` `main()``{``    ``// create the graph``    ``graph.resize(7);` `    ``// add edge``    ``graph[0].push_back(1);``    ``graph[0].push_back(3);``    ``graph[3].push_back(1);``    ``graph[3].push_back(6);``    ``graph[3].push_back(4);``    ``graph[1].push_back(6);``    ``graph[4].push_back(2);``    ``graph[4].push_back(5);``    ``graph[2].push_back(1);``    ``graph[5].push_back(2);``    ``graph[5].push_back(6);``    ``graph[6].push_back(4);` `    ``// add the cost``    ``cost[make_pair(0, 1)] = 2;``    ``cost[make_pair(0, 3)] = 5;``    ``cost[make_pair(1, 6)] = 1;``    ``cost[make_pair(3, 1)] = 5;``    ``cost[make_pair(3, 6)] = 6;``    ``cost[make_pair(3, 4)] = 2;``    ``cost[make_pair(2, 1)] = 4;``    ``cost[make_pair(4, 2)] = 4;``    ``cost[make_pair(4, 5)] = 3;``    ``cost[make_pair(5, 2)] = 6;``    ``cost[make_pair(5, 6)] = 3;``    ``cost[make_pair(6, 4)] = 7;` `    ``// goal state``    ``vector<``int``> goal;` `    ``// set the goal``    ``// there can be multiple goal states``    ``goal.push_back(6);` `    ``// get the answer``    ``vector<``int``> answer = uniform_cost_search(goal, 0);` `    ``// print the answer``    ``cout << ``"Minimum cost from 0 to 6 is = "``         ``<< answer[0] << endl;` `    ``return` `0;``}`

## Java

 `// Java implementation of above approach` `import` `java.util.*;` `public` `class` `GFG {` `    ``// graph``    ``static` `List> graph = ``new` `ArrayList>();` `    ``// map to store cost of edges``    ``static` `HashMap, Integer> cost = ``new` `HashMap, Integer>();` `// returns the minimum cost in a vector( if``// there are multiple goal states)``    ``static` `List uniform_cost_search(List goal, ``int` `start) {` `    ``// minimum cost upto``    ``// goal state from starting``    ``// state``        ``List answer = ``new` `ArrayList();` `        ``// create a priority queue``        ``List> queue = ``new` `ArrayList>();` `        ``// set the answer vector to max value``        ``for` `(``int` `i = ``0``; i < goal.size(); i++)``            ``answer.add(Integer.MAX_VALUE);` `        ``// insert the starting index``        ``queue.add(``new` `Tuple(``0``, start));` `        ``// map to store visited node``        ``HashMap visited = ``new` `HashMap();` `        ``// count``        ``int` `count = ``0``;` `        ``// while the queue is not empty``        ``while` `(!queue.isEmpty()) {` `        ``// get the top element of the``        ``// priority queue``            ``Tuple q = queue.get(``0``);``            ``Tuple p = ``new` `Tuple(-q.x, q.y);` `            ``// pop the element``            ``queue.remove(``0``);` `            ``if` `(goal.contains(p.y)) {``                ``// get the position``                ``int` `index = goal.indexOf(p.y);``                ``// if a new goal is reached``                ``if` `(answer.get(index) == Integer.MAX_VALUE)``                    ``count++;``                ``// if the cost is less``                ``if` `(answer.get(index) > p.x)``                    ``answer.set(index, p.x);``                ``// pop the element``                ``queue.remove(``0``);``                ``// if all goals are reached``                ``if` `(count == goal.size())``                    ``return` `answer;``            ``}``            ``if` `(!visited.containsKey(p.y))``                ``for` `(``int` `i = ``0``; i < graph.get(p.y).size(); i++) {``                ``// value is multiplied by -1 so that``                ``// least priority is at the top``                    ``queue.add(``new` `Tuple((p.x + (cost.containsKey(Arrays.asList(p.y, graph.get(p.y).get(i))) ? cost.get(Arrays.asList(p.y, graph.get(p.y).get(i))) : ``0``)) * -``1``,``                            ``graph.get(p.y).get(i)));``                ``}` `            ``// mark as visited``            ``visited.put(p.y, ``1``);``        ``}` `        ``return` `answer;``    ``}` `    ``// main function``    ``public` `static` `void` `main(String[] args) {``        ``// create the graph``        ``graph = ``new` `ArrayList>();` `        ``for` `(``int` `i = ``0``; i < ``7``; i++) {``            ``graph.add(``new` `ArrayList());``        ``}``        ` `        ``// add edges``        ``graph.get(``0``).add(``1``);``        ``graph.get(``0``).add(``3``);``        ``graph.get(``3``).add(``1``);``        ``graph.get(``3``).add(``6``);``        ``graph.get(``3``).add(``4``);``        ``graph.get(``1``).add(``6``);``        ``graph.get(``4``).add(``2``);``        ``graph.get(``4``).add(``5``);``        ``graph.get(``2``).add(``1``);``        ``graph.get(``5``).add(``2``);``        ``graph.get(``5``).add(``6``);``        ``graph.get(``6``).add(``4``);` `        ``// add the cost``        ``cost.put(Arrays.asList(``0``, ``1``), ``2``);``        ``cost.put(Arrays.asList(``0``, ``3``), ``5``);``        ``cost.put(Arrays.asList(``1``, ``6``), ``1``);``        ``cost.put(Arrays.asList(``3``, ``1``), ``5``);``        ``cost.put(Arrays.asList(``3``, ``6``), ``6``);``        ``cost.put(Arrays.asList(``3``, ``4``), ``2``);``        ``cost.put(Arrays.asList(``2``, ``1``), ``4``);``        ``cost.put(Arrays.asList(``4``, ``2``), ``4``);``        ``cost.put(Arrays.asList(``4``, ``5``), ``3``);``        ``cost.put(Arrays.asList(``5``, ``2``), ``6``);``        ``cost.put(Arrays.asList(``5``, ``6``), ``3``);``        ``cost.put(Arrays.asList(``6``, ``4``), ``7``);` `        ``// goal state``        ``List goal = ``new` `ArrayList();``        ``goal.add(``6``);` `        ``List answer = uniform_cost_search(goal, ``0``);` `        ``// print the answer``        ``System.out.print(``"Minimum cost from 0 to 6 is = "` `+ answer.get(``0``));``    ``}``}` `class` `Tuple {``    ``public` `final` `X x;``    ``public` `final` `Y y;` `    ``public` `Tuple(X x, Y y) {``        ``this``.x = x;``        ``this``.y = y;``    ``}``}`

## Python3

 `# Python3 implementation of above approach` `# returns the minimum cost in a vector( if``# there are multiple goal states)``def`  `uniform_cost_search(goal, start):``    ` `    ``# minimum cost upto``    ``# goal state from starting``    ``global` `graph,cost``    ``answer ``=` `[]` `    ``# create a priority queue``    ``queue ``=` `[]` `    ``# set the answer vector to max value``    ``for` `i ``in` `range``(``len``(goal)):``        ``answer.append(``10``*``*``8``)` `    ``# insert the starting index``    ``queue.append([``0``, start])` `    ``# map to store visited node``    ``visited ``=` `{}` `    ``# count``    ``count ``=` `0` `    ``# while the queue is not empty``    ``while` `(``len``(queue) > ``0``):` `        ``# get the top element of the``        ``queue ``=` `sorted``(queue)``        ``p ``=` `queue[``-``1``]` `        ``# pop the element``        ``del` `queue[``-``1``]` `        ``# get the original value``        ``p[``0``] ``*``=` `-``1` `        ``# check if the element is part of``        ``# the goal list``        ``if` `(p[``1``] ``in` `goal):` `            ``# get the position``            ``index ``=` `goal.index(p[``1``])` `            ``# if a new goal is reached``            ``if` `(answer[index] ``=``=` `10``*``*``8``):``                ``count ``+``=` `1` `            ``# if the cost is less``            ``if` `(answer[index] > p[``0``]):``                ``answer[index] ``=` `p[``0``]` `            ``# pop the element``            ``del` `queue[``-``1``]` `            ``queue ``=` `sorted``(queue)``            ``if` `(count ``=``=` `len``(goal)):``                ``return` `answer` `        ``# check for the non visited nodes``        ``# which are adjacent to present node``        ``if` `(p[``1``] ``not` `in` `visited):``            ``for` `i ``in` `range``(``len``(graph[p[``1``]])):` `                ``# value is multiplied by -1 so that``                ``# least priority is at the top``                ``queue.append( [(p[``0``] ``+` `cost[(p[``1``], graph[p[``1``]][i])])``*` `-``1``, graph[p[``1``]][i]])` `        ``# mark as visited``        ``visited[p[``1``]] ``=` `1` `    ``return` `answer` `# main function``if` `__name__ ``=``=` `'__main__'``:``    ` `    ``# create the graph``    ``graph,cost ``=` `[[] ``for` `i ``in` `range``(``8``)],{}` `    ``# add edge``    ``graph[``0``].append(``1``)``    ``graph[``0``].append(``3``)``    ``graph[``3``].append(``1``)``    ``graph[``3``].append(``6``)``    ``graph[``3``].append(``4``)``    ``graph[``1``].append(``6``)``    ``graph[``4``].append(``2``)``    ``graph[``4``].append(``5``)``    ``graph[``2``].append(``1``)``    ``graph[``5``].append(``2``)``    ``graph[``5``].append(``6``)``    ``graph[``6``].append(``4``)` `    ``# add the cost``    ``cost[(``0``, ``1``)] ``=` `2``    ``cost[(``0``, ``3``)] ``=` `5``    ``cost[(``1``, ``6``)] ``=` `1``    ``cost[(``3``, ``1``)] ``=` `5``    ``cost[(``3``, ``6``)] ``=` `6``    ``cost[(``3``, ``4``)] ``=` `2``    ``cost[(``2``, ``1``)] ``=` `4``    ``cost[(``4``, ``2``)] ``=` `4``    ``cost[(``4``, ``5``)] ``=` `3``    ``cost[(``5``, ``2``)] ``=` `6``    ``cost[(``5``, ``6``)] ``=` `3``    ``cost[(``6``, ``4``)] ``=` `7` `    ``# goal state``    ``goal ``=` `[]` `    ``# set the goal``    ``# there can be multiple goal states``    ``goal.append(``6``)` `    ``# get the answer``    ``answer ``=` `uniform_cost_search(goal, ``0``)` `    ``# print the answer``    ``print``(``"Minimum cost from 0 to 6 is = "``,answer[``0``])` `# This code is contributed by mohit kumar 29`

## C#

 `// C# implementation of above approach``using` `System;``using` `System.Collections;``using` `System.Collections.Generic;` `class` `GFG``{` `// graph``static` `List> graph=``new` `List>();` `// map to store cost of edges``static` `Dictionary,``int``> cost= ``new` `Dictionary,``int``>();` `// returns the minimum cost in a vector( if``// there are multiple goal states)``static` `List<``int``> uniform_cost_search(List<``int``> goal, ``int` `start)``{``    ``// minimum cost upto``    ``// goal state from starting``    ``// state``    ``List<``int``> answer=``new` `List<``int``>();` `    ``// create a priority queue``    ``List > queue = ``new` `List >();` `    ``// set the answer vector to max value``    ``for` `(``int` `i = 0; i < goal.Count; i++)``        ``answer.Add(``int``.MaxValue);` `    ``// insert the starting index``    ``queue.Add(``new` `Tuple<``int``,``int``>(0, start));` `    ``// map to store visited node``    ``Dictionary<``int``, ``int``> visited=``new` `Dictionary<``int``,``int``>();` `    ``// count``    ``int` `count = 0;` `    ``// while the queue is not empty``    ``while` `(queue.Count > 0) {` `        ``// get the top element of the``        ``// priority queue``        ``Tuple<``int``, ``int``> q = queue[0];``        ``Tuple<``int``, ``int``> p = ``new` `Tuple<``int``,``int``>(-q.Item1,q.Item2);` `        ``// pop the element``        ``queue.RemoveAt(0);`  `        ``// check if the element is part of``        ``// the goal list``        ``if` `(goal.Contains(p.Item2)) {` `            ``// get the position``            ``int` `index = goal.IndexOf(p.Item2);` `            ``// if a new goal is reached``            ``if` `(answer[index] == ``int``.MaxValue)``                ``count++;` `            ``// if the cost is less``            ``if` `(answer[index] > p.Item1)``                ``answer[index] = p.Item1;` `            ``// pop the element``            ``queue.RemoveAt(0);` `            ``// if all goals are reached``            ``if` `(count == goal.Count)``                ``return` `answer;``        ``}` `        ``// check for the non visited nodes``        ``// which are adjacent to present node``        ``if` `(!visited.ContainsKey(p.Item2))``            ``for` `(``int` `i = 0; i < graph[p.Item2].Count; i++) {` `                ``// value is multiplied by -1 so that``                ``// least priority is at the top``                ``queue.Add(``new` `Tuple<``int``,``int``>((p.Item1 + (cost.ContainsKey(``new` `Tuple<``int``,``int``>(p.Item2, graph[p.Item2][i])) ? cost[``new` `Tuple<``int``,``int``>(p.Item2, graph[p.Item2][i])] : 0))*-1,``                ``graph[p.Item2][i]));``            ``}` `        ``// mark as visited``        ``visited[p.Item2] = 1;``    ``}` `    ``return` `answer;``}` `// main function``public` `static` `void` `Main(``params` `string` `[]args)``{``    ``// create the graph``    ``graph=``new` `List>();` `    ``for``(``int` `i=0;i<7;i++)``    ``{``        ``graph.Add(``new` `List<``int``>());``    ``}` `    ``// add edge``    ``graph[0].Add(1);``    ``graph[0].Add(3);``    ``graph[3].Add(1);``    ``graph[3].Add(6);``    ``graph[3].Add(4);``    ``graph[1].Add(6);``    ``graph[4].Add(2);``    ``graph[4].Add(5);``    ``graph[2].Add(1);``    ``graph[5].Add(2);``    ``graph[5].Add(6);``    ``graph[6].Add(4);` `    ``// add the cost``    ``cost[``new` `Tuple<``int``,``int``>(0, 1)] = 2;``    ``cost[``new` `Tuple<``int``,``int``>(0, 3)] = 5;``    ``cost[``new` `Tuple<``int``,``int``>(1, 6)] = 1;``    ``cost[``new` `Tuple<``int``,``int``>(3, 1)] = 5;``    ``cost[``new` `Tuple<``int``,``int``>(3, 6)] = 6;``    ``cost[``new` `Tuple<``int``,``int``>(3, 4)] = 2;``    ``cost[``new` `Tuple<``int``,``int``>(2, 1)] = 4;``    ``cost[``new` `Tuple<``int``,``int``>(4, 2)] = 4;``    ``cost[``new` `Tuple<``int``,``int``>(4, 5)] = 3;``    ``cost[``new` `Tuple<``int``,``int``>(5, 2)] = 6;``    ``cost[``new` `Tuple<``int``,``int``>(5, 6)] = 3;``    ``cost[``new` `Tuple<``int``,``int``>(6, 4)] = 7;` `    ``// goal state``    ``List<``int``> goal=``new` `List<``int``>();` `    ``// set the goal``    ``// there can be multiple goal states``    ``goal.Add(6);` `    ``// get the answer``    ``List<``int``> answer = uniform_cost_search(goal, 0);` `    ``// print the answer``    ``Console.Write(``"Minimum cost from 0 to 6 is = "` `+ answer[0]);` `}``}` `// This code is contributed by rutvik_56.`

## Javascript

 `// returns the minimum cost in a vector( if``// there are multiple goal states)``function` `uniform_cost_search(goal, start) {``  ``// minimum cost upto``  ``// goal state from starting``  ``let answer = [];` `  ``// create a priority queue``  ``let queue = [];` `  ``// set the answer vector to max value``  ``for` `(let i = 0; i < goal.length; i++) {``    ``answer.push(10 ** 8);``  ``}` `  ``// insert the starting index``  ``queue.push([0, start]);` `  ``// map to store visited node``  ``let visited = {};` `  ``// count``  ``let count = 0;` `  ``// while the queue is not empty``  ``while` `(queue.length > 0) {``    ``// get the top element of the``    ``queue.sort();``    ``let p = queue[queue.length - 1];` `    ``// pop the element``    ``queue.splice(queue.length - 1, 1);` `    ``// get the original value``    ``p[0] *= -1;` `    ``// check if the element is part of``    ``// the goal list``    ``if` `(goal.includes(p[1])) {``      ``// get the position``      ``let index = goal.indexOf(p[1]);` `      ``// if a new goal is reached``      ``if` `(answer[index] === 10 ** 8) {``        ``count += 1;``      ``}` `      ``// if the cost is less``      ``if` `(answer[index] > p[0]) {``        ``answer[index] = p[0];``      ``}` `      ``// pop the element``      ``queue.splice(queue.length - 1, 1);``      ``queue.sort();``      ``if` `(count === goal.length) {``        ``return` `answer;``      ``}``    ``}` `    ``// check for the non visited nodes``    ``// which are adjacent to present node``    ``if` `(!visited[p[1]]) {``      ``for` `(let i = 0; i < graph[p[1]].length; i++) {``        ``// value is multiplied by -1 so that``        ``// least priority is at the top``        ``queue.push([``          ``(p[0] + cost[p[1] + ``","` `+ graph[p[1]][i]]) * -1,``          ``graph[p[1]][i],``        ``]);``      ``}``    ``}` `    ``// mark as visited``    ``visited[p[1]] = ``true``;``  ``}` `  ``return` `answer;``}` `// create the graph``let graph = [[], [], [], [], [], [], [], []];``let cost = {};` `// add edge``graph[0].push(1);``graph[0].push(3);``graph[3].push(1);``graph[3].push(6);``graph[3].push(4);``graph[1].push(6);``graph[4].push(2);``graph[4].push(5);``graph[2].push(1);``graph[5].push(2);``graph[5].push(6);``graph[6].push(4);` `// add the cost``cost[``"0,1"``] = 2;``cost[``"0,3"``] = 5;``cost[``"1,6"``] = 1;``cost[``"3,1"``] = 5;``cost[``"3,6"``] = 6;``cost[``"3,4"``] = 2;``cost[``"2,1"``] = 4;``cost[``"4,2"``] = 4;``cost[``"4,5"``] = 3;``cost[``"5,2"``] = 6;``cost[``"5,6"``] = 3;``cost[``"6,4"``] = 7;` `// goal state``    ``goal = []` `   ``// set the goal``   ``// there can be multiple goal states``    ``goal.push(6)` `   ``// get the answer``    ``answer = uniform_cost_search(goal, 0)` `   ``// print the answer``    ``console.log(``"Minimum cost from 0 to 6 is = "``,answer[0])``    ` `    ``// This code is contributed by lokeshpotta20.`

Output:

`Minimum cost from 0 to 6 is = 3`

Time Complexity: O( m ^ (1+floor(l/e)))

where,
m is the maximum number of neighbors a node has
l is the length of the shortest path to the goal state
e is the least cost of an edge

My Personal Notes arrow_drop_up