一致代价搜索问题
问题描述
Consider the graph shown in Figure 2. Let S be the initial state and G be the goal state.
The cost of each action is as indicated. (搜索求解☆☆☆☆)
(a) Give a trace of uniform-cost search.
(b) When A generates G which is the goal with a path cost of 11, why doesn’t the algorithm halt and return the search result since the goal has been found? With your observation, discuss how uniform-cost search ensures that the shortest path solution is selected.
问题分析
本次讨论的主题是一致代价搜索(UCS uniform-cost search)
基本原理
一致代价搜索是在广度优先搜索上进行扩展的,也被成为代价一致搜索,他的基本原理是:一致代价搜索总是扩展路径消耗最小的节点N。N点的路径消耗等于前一节点N-1的路径消耗加上N-1到N节点的路径消耗。
算法实现
数据结构:探索集(closed表 表示已扩展的结点集合)、边缘(开节点表 open表 表示待扩展的结点)、parent表
算法步骤:
- 如果边缘为空,则返回失败。
- 否则从边缘中选择一个叶子节点。
- 目标测试:通过返回,否则将叶子节点的状态放入中。
- 遍历叶子节点操作:
- 产生子节点,如果不在open也不在close中,则插入open
- 如果close中存在且有更高的路径消耗,则用子节点代替close中的状态
样例推导
-
初始化 c l o s e d = ∅ , o p e n = { S } closed={\empty},open=\{S\} closed=∅,open={S}
-
o p e n . i s e m p t y ( ) = = f a l s e open.isempty()==false open.isempty()==false,从 o p e n open open中选择S。
S不是目标节点,生成子节点A(1),B(5),C(15)三者都不在open和closed中,因此插入open,并进行排序。 o p e n = { A , B , C } , c l o s e d = { S } open=\{A,B,C\},closed=\{S\} open={A,B,C},closed={S}
A S B G C S -1 S -1 S -
o p e n . i s e m p t y ( ) = = f a l s e open.isempty()==false open.isempty()==false,从 o p e n open open中选择A。
A不是目标结点,生成子节点S、G(11),S在closed中不插入open,G不在closed和open中,因此插入open,并进行排序。 o p e n = { B , G , C } , c l o s e d = { S , A } open=\{B,G,C\},closed=\{S,A\} open={B,G,C},closed={S,A}
A S B G C S -1 S A S -
o p e n . i s e m p t y ( ) = = f a l s e open.isempty()==false open.isempty()==false,从 o p e n open open中选择B。
B不是目标节点,生成子节点G,G在open表中,且g(G in open)=11
g(G) = 10, g(G in open)>g(G),所以需要更新open表中的G,并进行排序。
o p e n = { G , C } , c l o s e d = { S , A , B } open=\{G,C\},closed=\{S,A,B\} open={G,C},closed={S,A,B}
A S B G C S -1 S B S -
o p e n . i s e m p t y ( ) = = f a l s e open.isempty()==false open.isempty()==false,从 o p e n open open中选择G。
G是目标节点,通过测试,返回路径:S->B->G
代码实现
bool list[20];
vector<node> openList;
bool closeList[20];
int parent[20];
void UCS(int goal,node &src,Graph &graph)
{
openList.push_back(src);
list[src.name]=true;
while (!openList.empty())
{
/********** Begin **********/
sort(openList.begin(), openList.end());
node curr = openList.front();
closeList[curr.name] = true;
if(curr.name==goal) {return;}
else{
for(int i=0;i<=5;i++)
{
if((graph.getEdge(curr.name,i)!=-1) && (closeList[i]==false) && (i!=parent[curr.name]) )
{
node chld(i,curr.g+graph.getEdge(curr.name,i),h[i]);
if(list[i]==true)
{
int Gopen = 0;
//寻找到openList中的该点
for(int j=0;j<openList.size();j++)
{
if(openList[j].name==i)
{
gpen = openList[j].g;
}
}
//计算新的值
int gnew = 0;
int pa = parent[i];
//寻找closeList中的父亲
gnew = curr.g+graph.getEdge(curr.name,i);
if(gnew<gopen){
parent[i]=curr.name;
}
}
else
{
parent[i]=curr.name;
list[i]=true;
node nnode = node(i,curr.g+graph.getEdge(curr.name,i));
openList.push_back(nnode);
}
}
}
openList.erase(openList.begin());
}
/********** End **********/
}
}
问题讨论
当A生成结点G时,为什么不停止计算并将S-A-G作为寻找到的路径?一致代价搜索如何确保这是最短距离?
其实这个问题就是在问,为什么一致代价搜索在扩展结点的时候做目标测试,而不是在生成结点的时候。因为在该父节点生成结点时,可能会有另一条路径用更小的代价到达目标节点的该父节点。由于每一步的代价是非负的,随着结点的增加路径不会变短,所以第一个被选择扩展的结点一定是最优解。