Uniform-Cost Search 是 Dijikstra 算法的一种变体。在这里,我们不是将所有顶点插入优先级队列,而是仅插入源,然后在需要时一一插入。在每一步中,我们检查项目是否已经在优先队列中(使用访问数组)。如果是,我们执行减少键,否则我们插入它。
Dijsktra 的这种变体对于无限图和那些太大而无法在内存中表示的图很有用。 Uniform-Cost Search 主要用于人工智能。
例子:
Input :
Output :
Minimum cost from S to G is =3
Uniform-Cost Search 类似于 Dijikstra 的算法。在这个算法中,我们将从起始状态开始访问相邻状态并选择成本最低的状态,然后我们将从所有未访问状态和访问状态的相邻状态中选择下一个成本最低的状态,这样我们将尝试到达目标状态(注意我们不会继续通过目标状态的路径),即使我们到达目标状态,我们也会继续寻找其他可能的路径(如果有多个目标)。我们将保留一个优先级队列,该队列将从访问状态的所有相邻状态中给出成本最低的下一个状态。
CPP
// C++ implemenatation 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 uniform_cost_search(vector goal, int start)
{
// minimum cost upto
// goal state from starting
// state
vector 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 visited;
// count
int count = 0;
// while the queue is not empty
while (queue.size() > 0) {
// get the top element of the
// priority queue
pair 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 goal;
// set the goal
// there can be multiple goal states
goal.push_back(6);
// get the answer
vector answer = uniform_cost_search(goal, 0);
// print the answer
cout << "Minimum cost from 0 to 6 is = "
<< answer[0] << endl;
return 0;
}
Python3
# Python3 implemenatation 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# implemenatation 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 uniform_cost_search(List goal, int start)
{
// minimum cost upto
// goal state from starting
// state
List answer=new List();
// 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(0, start));
// map to store visited node
Dictionary visited=new Dictionary();
// count
int count = 0;
// while the queue is not empty
while (queue.Count > 0) {
// get the top element of the
// priority queue
Tuple q = queue[0];
Tuple p = new Tuple(-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((p.Item1 + (cost.ContainsKey(new Tuple(p.Item2, graph[p.Item2][i])) ? cost[new Tuple(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());
}
// 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(0, 1)] = 2;
cost[new Tuple(0, 3)] = 5;
cost[new Tuple(1, 6)] = 1;
cost[new Tuple(3, 1)] = 5;
cost[new Tuple(3, 6)] = 6;
cost[new Tuple(3, 4)] = 2;
cost[new Tuple(2, 1)] = 4;
cost[new Tuple(4, 2)] = 4;
cost[new Tuple(4, 5)] = 3;
cost[new Tuple(5, 2)] = 6;
cost[new Tuple(5, 6)] = 3;
cost[new Tuple(6, 4)] = 7;
// goal state
List goal=new List();
// set the goal
// there can be multiple goal states
goal.Add(6);
// get the answer
List 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.
输出:
Minimum cost from 0 to 6 is = 3
复杂度: O( m ^ (1+floor(l/e)))
在哪里,
m 是节点拥有的最大邻居数
l 是到达目标状态的最短路径的长度
e 是边的最小成本
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。