PHP实现的迪科斯彻(Dijkstra)最短路径算法实例


Posted in PHP onSeptember 16, 2017

本文实例讲述了PHP实现的迪科斯彻(Dijkstra)最短路径算法。分享给大家供大家参考,具体如下:

一、待解决问题

单源最短路径问题,在给定有向图中求一个顶点(单源顶点)到其他所有顶点的最短路径问题。在下图中,每条边上有一个权值,希望求解A到所有其他顶点(B/C/D/E/F/G)的最短路径。

PHP实现的迪科斯彻(Dijkstra)最短路径算法实例

二、问题分析(最短路径的子结构同样最优性)

如果P(A,G)是从顶点A到G的最短路径,假设D和F是这条路径上的中间点,那么P(D,F)一定时从D到F的最短路径。如果P(D,F)不是D到F的最短路径,那必然存在某一个节点M的另一条D到F的路径可以使P(A,B...M...F,G)比P(A,G)小,自相矛盾。

有了这样的性质,我们可以了解Dijkstra算法。

三、Dijkstra算法

Dijkstra 算法,又叫迪科斯彻算法(Dijkstra),又称为单源最短路径算法,所谓单源是在一个有向图中,从一个顶点出发,求该顶点至所有可到达顶点的最短路径问题。 问题描述为设G=(V,E)是一个有向图,V表示顶点,E表示边。它的每一条边(i,j)属于E,都有一个非负权W(I,j),在G中指定一个结点v0,要求把从v0到G的每一个接vj(vj属于V)的最短有向路径找出来(或者指出不存在)。 Dijstra算法是运用贪心的策略,从源点开始,不断地通过相联通的点找出到其他点的最短距离。

Dijkstra的贪心应用在他利用(二)中的性质,不断地选取“最近”的节点并试探每个节点的所有可能存在链接,以起始点为中心向外层层扩展,直到扩展到终点为止。对于源点A,逐步扩展,根据dist[j]=min{dist[j],dist[i]+matrix[i][j]}更新与i直接相邻的顶点信息。

算法描述

1)算法思想:

设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径 , 就将加入到集合S中,直到全部顶点都加入到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度。此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。

2)算法步骤:

a.初始时,S只包含源点,即S={v},v的距离为0。U包含除v外的其他顶点,即:U={其余顶点},若v与U中顶点u有边,则<u,v>正常有权值,若u不是v的出边邻接点,则<u,v>权值为∞。

b.从U中选取一个距离v最小的顶点k,把k,加入S中(该选定的距离就是v到k的最短路径长度)。

c.以k为新考虑的中间点,修改U中与k相邻的各顶点的距离;若从源点v到顶点u的距离(经过顶点k)比原来距离(不经过顶点k)短,则修改顶点u的距离值,修改后的距离值为顶点k的距离加上k与u边上的权。

d.重复步骤b和c直到所有顶点都包含在S中。

四、算法PHP实现

<?php
class Dijkstra
{
  private $G;
  public function __construct()
  {
    //有向图存储
    $this->G = array(
      array(0,1,2,0,0,0,0),
      array(0,0,0,1,2,0,0),
      array(0,0,0,0,0,2,0),
      array(0,0,0,0,0,1,3),
      array(0,0,0,0,0,0,3),
      array(0,0,0,0,0,0,1),
      array(0,0,0,0,0,0,0),
    );
  }
  public function calculate()
  {
    // 存储已经选择节点和剩余节点
    $U = array(0);
    $V = array(1,2,3,4,5,6);
    // 存储路径上节点距离源点的最小距离
    $d = array();
    //初始化图中节点与源点0的最小距离
    for($i=1;$i<7;$i++)
    {
      if($this->G[0][$i]>0)
      {
        $d[$i] = $this->G[0][$i];
      }
      else
      {
        $d[$i] = 1000000;
      }
    }
    // n-1次循环完成转移节点任务
    for($l=0;$l<6;$l++)
    {
      // 查找剩余节点中距离源点最近的节点v
      $current_min = 100000;
      $current_min_v = 0;
      foreach($V as $k=>$v)
      {
        if($d[$v] < $current_min)
        {
          $current_min = $d[$v];
          $current_min_v = $v;
        }
      }
      //从V中更新顶点到U中
      array_push($U,$current_min_v);
      array_splice($V,array_search($current_min_v,$V),1);
      //更新
      foreach($V as $k=>$u)
      {
        if($this->G[$current_min_v][$u]!=0&&$d[$u]>$d[$current_min_v]+$this->G[$current_min_v][$u])
        {
          $d[$u] = $d[$current_min_v]+$this->G[$current_min_v][$u];
        }
      }
    }
    foreach($d as $k => $u)
    {
      echo $k.'=>'.$u.'<br>';
    }
  }
}
?>

调用类:

$D = new Dijkstra;
$D->calculate();

执行结果:

1=>1
2=>2
3=>2
4=>3
5=>3
6=>4

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
一些PHP写的小东西
Dec 06 PHP
PHP+.htaccess实现全站静态HTML文件GZIP压缩传输(一)
Feb 15 PHP
PHP中$_SERVER的详细参数与说明
Jul 29 PHP
PHP 可阅读随机字符串代码
May 26 PHP
PHP中用正则表达式清除字符串的空白
Jan 17 PHP
Apache下禁止php文件被直接访问的解决方案
Apr 25 PHP
PHP flush()与ob_flush()的区别详解
Jun 03 PHP
解析PHP工厂模式的好处
Jun 18 PHP
PHP计算2点经纬度之间的距离代码
Aug 12 PHP
php自定义错误处理用法实例
Mar 20 PHP
PHP使用CURL实现多线程抓取网页
Apr 30 PHP
thinkPHP删除前弹出确认框的简单实现方法
May 16 PHP
PHP环形链表实现方法示例
Sep 15 #PHP
PHP实现的链式队列结构示例
Sep 15 #PHP
PHP基于堆栈实现的高级计算器功能示例
Sep 15 #PHP
PHP操作MySQL中BLOB字段的方法示例【存储文本与图片】
Sep 15 #PHP
visual studio code 调试php方法(图文详解)
Sep 15 #PHP
PHP简单实现模拟登陆功能示例
Sep 15 #PHP
Thinkphp开发--集成极光推送
Sep 15 #PHP
You might like
php中读写文件与读写数据库的效率比较分享
2013/10/19 PHP
最新版本PHP 7 vs HHVM 多角度比较
2016/02/14 PHP
Yii 2.0在Grid中格式化时间方法示例
2017/06/06 PHP
PHP implode()函数用法讲解
2019/03/08 PHP
png在IE6 下无法透明的解决方法汇总
2015/05/21 Javascript
JavaScript实现强制重定向至HTTPS页面
2015/06/10 Javascript
JS将滑动门改为选项卡(需鼠标点击)的实现方法
2015/09/27 Javascript
js倒计时简单实现方法
2015/12/17 Javascript
Bootstrap源码解读表单(2)
2016/12/22 Javascript
使用base64对图片的二进制进行编码并用ajax进行显示
2017/01/03 Javascript
js实现鼠标跟随运动效果
2020/08/02 Javascript
原生js封装运动框架的示例讲解
2017/10/01 Javascript
详解微信小程序中的页面代码中的模板的封装
2017/10/12 Javascript
JavaScript适配器模式详解
2017/10/19 Javascript
Intellij IDEA搭建vue-cli项目的方法步骤
2018/10/20 Javascript
Vue.js 事件修饰符的使用教程
2018/11/01 Javascript
解决layui弹出层layer的area过大被遮挡的问题
2019/09/21 Javascript
有趣的JavaScript隐式类型转换操作实例分析
2020/05/02 Javascript
vue 虚拟DOM的原理
2020/10/03 Javascript
[05:08]顺网杯ISS-DOTA2赛歌 少女偶像Lunar青春演绎
2013/12/05 DOTA
[36:13]Mineski vs iG 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Flask的图形化管理界面搭建框架Flask-Admin的使用教程
2016/06/13 Python
Python基于sftp及rsa密匙实现远程拷贝文件的方法
2016/09/21 Python
Python 多进程并发操作中进程池Pool的实例
2017/11/01 Python
python 线性回归分析模型检验标准--拟合优度详解
2020/02/24 Python
python简单实现插入排序实例代码
2020/12/16 Python
HTML5 Canvas API中drawImage()方法的使用实例
2016/03/25 HTML / CSS
美国著名珠宝品牌之一:Jared The Galleria Of Jewelry
2016/10/01 全球购物
Hunkemöller西班牙:欧洲最大的内衣连锁店
2018/08/15 全球购物
美国羽绒床上用品第一品牌:Pacific Coast
2018/08/25 全球购物
广州一家公司的.NET面试题
2016/06/11 面试题
财经学院自荐信范文
2014/02/02 职场文书
怎样写好创业计划书的内容
2014/02/06 职场文书
2014城乡环境综合治理工作总结
2014/12/19 职场文书
仓库管理制度范本
2015/08/04 职场文书
向Spring IOC 容器动态注册bean实现方式
2022/07/15 Java/Android