Dijakstra和分支限界都是基于广度优先搜索,如果说两者都是生成一棵树,那Dijakstra总是找距离树根最近的(属于贪心算法),优先队列式分支限界是在层遍历整棵搜索树的同时剪去达不到最优的树枝。

以下图为例:求从点s到点t的最短路径

1. Dijakstra

第一步:初始化:将起点s加入集合S,并对所有非集合S的点的距离dist进行初始化(若不与s邻接,距离为无穷大)

第二步:在非集合S的点集合中,寻找离点s最近的点B(argmin dist[i])并加入集合S,并对所有与B邻接且非集合S的点i的距离dist进行更新(若dist[i]>dist[B]+W[B][i] 则dist[i]=dist[B]+W[B][i])

第三步:重复第二步,直到在非集合S的点集合中,找不到离点s的距离为有限值的点(这说明存在多棵生成树)。

主程序如下

while(1){
        x = FindShortest(Graph, collected);
        if(x == -1) break;
        collected[x] = 1;
        for(int i = 0;i<Graph->Nv;i++){
            if(!collected[i] && Graph->L[x][i] != INFINITY){
                if(dist[i] > dist[x] + Graph->L[x][i]){
                    dist[i] = dist[x] + Graph->L[x][i];
                    pri[i] = pri[x] + Graph->P[x][i];
                }
            }
        }
    }

2. 优先队列式分支限界法

分支限界法有队列式和优先队列式,两者区别在于,队列式只是单纯地满足先进先出,从而实现广度有限搜索,而优先队列式是对结点按目标函数值插入一个最大(小)堆,优先处理目标函数值较大(小)的结点。

解决单源最短路径的步骤:

第一步:初始化,将起点s加入优先队列(优先队列的目标函数值为距离dist,建立最小堆),并对所有非集合S的点的距离dist进行初始化(若不与s邻接,距离为无穷大)

第二步:从优先队列中取出点,对其所有邻接结点遍历,并对距离dist进行更新(若dist[i]>dist[B]+W[B][i]     则dist[i]=dist[B]+W[B][i],并将其加入优先队列)

第三步:重复第二步,直到队列为空。

主程序如下(哈哈..这个不是我写的,看看就好)

while (true) {
     for (int j = 1; j <= n; j++)
       if ((c[E.i][j]<inf)&&(E.length+c[E.i][j]<dist[j])) {
         // 顶点i到顶点j可达,且满足控制约束
         dist[j]=E.length+c[E.i][j];
         prev[j]=E.i;
         // 加入活结点优先队列
         MinHeapNode<Type> N;
         N.i=j;
         N.length=dist[j];
         H.Insert(N);}
     try {H.DeleteMin(E);}         // 取下一扩展结点
     catch (OutOfBounds) {break;}  // 优先队列空
     }
} 

需要注意的是:在第二步中,若不满足条件dist[i]>dist[B]+W[B][i],则不会对距离进行更新,也不会将其加入优先队列,这相当于对一个二叉搜索树的树枝进行了剪枝

比如对s的邻接点进行遍历后,得到队列为BCA;然后对结点B的邻接点进行遍历,得到队列CAEDF;然后对结点C的邻接点进行遍历,首先是结点E,由于当前dist[E]>dist[C]+W[C][E],E被加入优先队列,且排在上一个E之前,即AE1EDF,而F由于不满足条件,不会被再次加入优先队列;同样地,当对A进行遍历时,由于不满足条件,没有新的结点加入优先队列(相当于被剪枝),此时队列里有  E1EDF,依次进行下去....得到树如下图。

图里的db可以忽略。。。反正真正跑程序也不会去计算所谓的限界值。

对比Dijakstra和优先队列式分支限界的更多相关文章

  1. python和go对比字符串的链式处理

    一.什么是链式处理 对数据的操作进行多步骤的处理称为链式处理,链式处理器是一种常见的编程设计,链式处理的开发思想将数据和操作拆分,解耦,让开发者可以根据自己的技术优势和需求,进行系统开发,同时将自己的 ...

  2. 结构之美——优先队列基本结构(四)——二叉堆、d堆、左式堆、斜堆

    实现优先队列结构主要是通过堆完成,主要有:二叉堆.d堆.左式堆.斜堆.二项堆.斐波那契堆.pairing 堆等. 1. 二叉堆 1.1. 定义 完全二叉树,根最小. 存储时使用层序. 1.2. 操作 ...

  3. python 列表推导式 - python基础入门(16)

    截止到目前为止,python基础内容已经学习了50%左右,在学习编程过程中,我们不仅要学习python语法,同时也需要学习如何把自己代码写的更美观,效率更高. 一.什么是推导式 推导式是从一个或者多个 ...

  4. LeetCode : 93. Restore IP Addresses

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABZ4AAAHUCAYAAAC6Zj2HAAAMFGlDQ1BJQ0MgUHJvZmlsZQAASImVlw

  5. (java)五大常用算法

    算法一:分治法 基本概念 1.把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题--直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并. 2.分治策略是对于一个 ...

  6. Web API数据传输加密

    http://www.cnblogs.com/wuhuacong/p/4620300.html Web API应用架构设计分析(2) 在上篇随笔<Web API应用架构设计分析(1)>, ...

  7. 分支界定法 branch-and-bound 分析与实现)(转载)

    1. 介绍分支界定法之前需要了解一下广度优先搜索breadth-First-search(BFS) 1.从图中某个顶点V0出发,并访问此顶点:以层为顺序,一层一层往下遍历 2.从V0出发,访问V0的各 ...

  8. javascript学习第四课函数

    函数也是一种数据类型:function类型 所以函数也可当作一个数据作参数传递 三种函数的声明示例: 一般来讲,声明方式一和声明方式二比较常用,方式三比较少. 常用函数方式示例: 注意:虽然函数支持嵌 ...

  9. 数据库软件dbForge Studio for MySQL更新至v.6.1

    本文转自:慧都控件网 说到MariaDB,这个数据库算是MySQL的一个分支.现在非常的流行,很多地方都能看到它的身影.MariaDB作为一种新的数据库管理系统,在短时间内获得如此高的关注度.这也是D ...

随机推荐

  1. 如何优雅地使用Sublime Text3

    此文非原创,出处见文章结尾. 一.Sublime Text 3插件安装 优雅使用Sublime Text,插件则是不可缺少的存在:而插件的备份就显得非常的重要(譬如:各平台同步:更换系统/电脑,迅速使 ...

  2. curator操作zookeeper

    使用zookeeper原生API实现一些复杂的东西比较麻烦.所以,出现了两款比较好的开源客户端,对zookeeper的原生API进行了包装:zkClient和curator.后者是Netflix出版的 ...

  3. ES6 In Depth: Arrow functions

    Arrows <script language="javascript"> <!-- document.bgColor = "brown"; ...

  4. Openresty 学习笔记(四)lualocks包管理器安装使用

    Luarocks是一个Lua包管理器,基于Lua语言开发,提供一个命令行的方式来管理Lua包依赖.安装第三方Lua包等,社区比较流行的包管理器之一,另还有一个LuaDist,Luarocks的包数量比 ...

  5. maven项目配置框架

    任何一个maven项目都会继承一个默认的父pom配置:Super POM,详见:https://maven.apache.org/guides/introduction/introduction-to ...

  6. Linux下的解压命令

    Linux下常见的压缩包格式有5种:zip tar.gz tar.bz2 tar.xz tar.Z 其中tar是种打包格式,gz和bz2等后缀才是指代压缩方式:gzip和bzip2 filename. ...

  7. SCTP接口模型

    一.接口模型 (1)SCTP套接字分为:一到一套接字和一到多套接字: (2)一到一套接字对应一个单独的SCTP关联(一个SCTP关联是两个系统之间的一个连接,不过可能由于多宿原因而在每个断点设计不止 ...

  8. 二叉搜索树BST

    //遍历 void print(int p){ if(!p) return; print(left[p]); printf("%d\n",a[p]); print(right[p] ...

  9. MVC下 Area和Web同名的Controller问题

    错误如下图: 解决方案: 1:Area下的XXXAreaRegistration 添加:new string[] { "xxx.Areas.xxx.Controllers" } 2 ...

  10. orcle查看表空间数据文件使用情况

    -- 查看表空间数据文件使用情况select a.*, round(a.usedgb/a.maxgb*100) || '%' usedPer from (select t.TABLESPACE_NAM ...