• 图的优先级搜索


    上一篇博客里面提到了优先级搜索(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;//这里只要有一个节点更新就可以返回
             } 
         }
    }        

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

  • 相关阅读:
    Atitit.eclise的ide特性abt 编译
    Atitit python3.0 3.3 3.5 3.6 新特性 Python2.7新特性1Python 3_x 新特性1python3.4新特性1python3.5新特性1值得关注的新特性1Pyth
    Atitit. Atiposter 发帖机 新特性 poster new feature   v7 q39
    Atitit.eclipse 4.3 4.4  4.5 4.6新特性
    atitit.错误:找不到或无法加载主类 的解决 v4 qa15.doc
    Atitit RSA非对称加密原理与解决方案
    Atitti.数字证书体系cer pfx attilax总结
    Atitit ftp原理与解决方案
    Atitit qzone qq空间博客自动点赞与评论工具的设计与实现
    Atitit 软件国际化原理与概论
  • 原文地址:https://www.cnblogs.com/lustar/p/7213711.html
Copyright © 2020-2023  润新知