图的优先级搜索

本文介绍了优先级搜索(priority first search)的基本概念及实现框架,并将其应用于广度优先搜索(BFS)与深度优先搜索(DFS)中,展示了如何通过定义不同的优先级更新策略来实现这两种经典的图搜索算法。
摘要由CSDN通过智能技术生成

上一篇博客里面提到了优先级搜索(priority first search),单独拿出来写一篇,因为优先级搜索可以适用大部分图搜算算法。所谓优先级搜索,是在图的遍历过程中,每次迭代都更新图中某些点或者是边的优先级,随着算法的不断推进调整,每次选取顶点或者边中优先级最高的那个元素进行访问。按照这种思想,深度优先搜索和广度优先搜索其实都可以纳入到这个框架中,因为他们的不同之处仅仅在于,每次选择点的时候,点的优先级策略是不同的。约定优先级数值越小,优先级越高。下面,给出优先级搜索的框架:

 1 template<typename Tv, typename Te> template<typename PU> void Graph<Tv, Te>::pfs(int s,PU prioUpdater)//优先级搜索
 2 {
 3     reset(); int clock = 0; int v = s;
 4     do
 5         if (stasus(v) == UNDISCOVERED)//遇到未发现的顶点
 6             PFS(v, clock);//执行一次pFS
 7     while (s != (v = (++v%n)));//做到不重不漏
 8 }
 9 template<typename Tv, typename Te> template<typename PU>//优先级更新器
10 void Graph<Tv, Te>::PFS(int s, PU prioUpdater)
11 {
12     priority(s) = 0; status(s) = VISITED; parent(s) = -1;
13     while (1)
14     {
15         for (int w = firstNbr(s); w > -1; w = nextNbr(s, w))//更新所有的邻接顶点
16             prioUpdater(this, s, w);
17         for(int shortest = INT_MAX, w = 0; w < n; w++)//在所有顶点中寻找优先级最低的顶点
18             if(status(w) == UNDISCOVERED)
19                 if (priority(w) < shortest)
20                 {
21                     shortest = priority(w);
22                     s = w;
23                 }
24         if (status(s) == VISITED) break;//优先级最高的顶点已经被访问
25         status(s) = VISITED; type(parent(s), s) = TREE;
26     }
27 }

优先级搜索的流程,可以总结如下:对于当前节点的所有邻居,按照某种更新策略,更新他们的优先级;然后,从所有的点中找出优先级最高的顶点进行访问;当取出的优先级最高的顶点已经访问完成,算法结束。这样我们同样得到了和之前相同的,图的一颗遍历树。算法每次迭代都要访问所有的n个节点,时间复杂度为O(n^2)。

 

下面,把BFS和DFS纳入这个框架中,它们的更新器如下:

 1 template <typename Tv, typename Te> struct BfsPU
 2 { 
 3     virtual void operator() ( Graph<Tv, Te>* g, int uk, int v ) 
 4     {
 5         if ( g->status ( v ) == UNDISCOVERED ) 
 6         if ( g->priority ( v ) > g->priority ( uk ) + 1 ) 
 7         {
 8              g->priority ( v ) = g->priority ( uk ) + 1; //更新优先级(数)
 9              g->parent ( v ) = uk; //更新父节点
10         } 
11     }
12 }

广度优先搜索,只需要每次将UNDISCOVERED的点,优先级设置为当前点优先级数+1,这样每次新发现的点都要比以前发现的点优先级低。

 template <typename Tv, typename Te> struct DfsPU
{ 
    virtual void operator() ( Graph<Tv, Te>* g, int uk, int v ) 
    {
         if ( g->status ( v ) == UNDISCOVERED ) 
         if ( g->priority ( v ) > g->priority ( uk ) - 1 ) 
         {
              g->priority ( v ) = g->priority ( uk ) - 1; //更新优先级(数)
              g->parent ( v ) = uk; //更新父节点
              return;//这里只要有一个节点更新就可以返回
         } 
     }
}        

深度优先搜索,每次新发现的顶点都比父亲节点优先级低。要注意的是,每当有一个节点的优先级发生了改变,就可以直接返回。

转载于:https://www.cnblogs.com/lustar/p/7213711.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值