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. saltstack SLS 安装haproxy+nginx实例分析学习

    本文主要以实例的形式去熟悉sls的部署流程及相关模块的使用 文件下载:https://github.com/unixhot/saltbook-code 目录结构 [root@k8s_master sa ...

  2. MacOS环境中 python3 部署

    MacOS环境中 python3 部署 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.在MacOS安装Python3.6 1>.打开python关于MacOS版本的官方网 ...

  3. Hadoop记录-hdfs转载

    Hadoop 存档 每个文件均按块存储,每个块的元数据存储在namenode的内存中,因此hadoop存储小文件会非常低效.因为大量的小文件会耗尽namenode中的大部分内存.但注意,存储小文件所需 ...

  4. springboot打包成war,部署到tomcat无法访问的问题

    如题:实在是太坑.平时本地测试觉得很方便,但是到了项目打包发布掉链子了. 如很多帖子一样: 首先springboot内嵌的tomcat,再依赖servlet-api,修改启动类继承SpringBoot ...

  5. PHP7 网络编程(五)进程间通信【待】

    https://blog.csdn.net/godleading/article/details/78391159

  6. SQL Server进阶(十一)临时表、表变量

    临时表 本地临时表 适合开销昂贵   结果集是个非常小的集合 -- Local Temporary Tables IF OBJECT_ID('tempdb.dbo.#MyOrderTotalsByYe ...

  7. Android SVN上传项目

    方式一: 1 工具栏 VCS ——import into Version Control - Share Project (SubVersion)(注意不要用import into SubVersio ...

  8. 使用 JS 实现文字上下跑马灯

    Ø  前言 今天在做商城首页时,遇到一个上下跑马灯功能,因为之前也只是接触过左右的跑马灯,一时还不知道从何下手.在网上看了几个 demo,并亲自运行了一下,是可以实现的.但是,能运行不知其所以然也不行 ...

  9. Javascript async异步操作库简介

    异步操作知识 在js世界中, 异步操作非常流行, nodejs就是特点基于异步非阻塞. js语言支持的异步语法包括, Promise  async await generator yield. 这些语 ...

  10. 在window上使用 linux shell 删除文件夹递归地

    目的 在windows环境下, 整理代码,代码中含有 .svn 文件夹, 此文件夹在所有受控目录下都存在, 需要统一删除. 但是对windows的shell不熟悉,想用linux rm来删除, 如何实 ...