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. python 发送邮件模板

    ##发送普通txt文件(与发送html邮件不同的是邮件内容设置里的type设置为text,下面代码为发送普通邮件的另一种方法) import smtplibimport stringfrom emai ...

  2. 使用yum源的方式单机部署MySQL8.0.13

    使用yum源的方式单机部署MySQL8.0.13 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 基本上开源的软件都支持三种安装方式,即rmp方式安装,源码安装和二进制方式安装.在 ...

  3. JAVA-Proxy 代理

    jdk静态代理 interface Dao { void save(); } class DaoImpl implements Dao { @Override public void save() { ...

  4. C++回顾day01---<命名空间>

    一:namespace是指标识符的各种控件范围(类java中package) C++语言引入命名空间(Namespace)这一概念主要是为了避免命名冲突,其关键字为 namespace 二:iostr ...

  5. json 模块 与 pickle 模块

    1 import json 3 dic={'name':'alvin','age':23,'sex':'male'} 4 print(type(dic))#<class 'dict'> 6 ...

  6. 063、如何使用weave网络(2019-04-03 周三)

    参考https://www.cnblogs.com/CloudMan6/p/7471162.html   weave是Weaveworks开发的容器网络解决方案.weave创建的虚拟网络可以将部署在多 ...

  7. 深入理解Python异步编程(上)

    本文代码整理自:深入理解Python异步编程(上) 参考:A Web Crawler With asyncio Coroutines 一.同步阻塞方式 import socket def blocki ...

  8. hadoop1.2.1的安装

    前提:1.机器最好都做ssh免密登录,最后在启动hadoop的时候会简单很多 免密登录看免密登录 2.集群中的虚拟机最好都关闭防火墙,否则很麻烦 3集群中的虚拟机中必须安装jdk. 具体安装步骤如下: ...

  9. 二十四、Linux 进程与信号---wait 函数

    24.1 wait 函数说明 24.1.1 waitpid---等待子进程中断或结束 waitpid(等待子进程中断或结束) 相关函数 wait,fork #include <sys/types ...

  10. vs不自动退出控制台程序的办法

    1.在主函数rerurn 前加上getchar();即可. 2.ctrl+F5;