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 相关文章推荐
PHP5权威编程阅读学习笔记 附电子书下载
Jul 05 PHP
php导出word格式数据的代码实例
Nov 25 PHP
thinkphp3查询mssql数据库乱码解决方法分享
Feb 11 PHP
php环境无法上传文件的解决方法
Apr 30 PHP
PHP+Memcache实现wordpress访问总数统计(非插件)
Jul 04 PHP
PHP简单实现断点续传下载的方法
Sep 25 PHP
php抓取并保存网站图片的实现代码
Oct 28 PHP
php ucwords() 函数将字符串中每个单词的首字符转换为大写(实现代码)
May 12 PHP
php使用PDO获取结果集的方法
Feb 16 PHP
php实现遍历文件夹的方法汇总
Mar 02 PHP
PHP异常类及异常处理操作实例详解
Dec 19 PHP
PHP asXML()函数讲解
Feb 03 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面向对象全攻略 (五) 封装性
2009/09/30 PHP
一组PHP加密解密函数分享
2014/06/05 PHP
PHP实现防盗链的方法分析
2017/07/25 PHP
Javascript下判断是否为闰年的Datetime包
2010/10/26 Javascript
jsTree 基于JQuery的排序节点 Bug
2011/07/26 Javascript
疯狂Jquery第一天(Jquery学习笔记)
2012/05/11 Javascript
解决火狐浏览器下JS setTimeout函数不兼容失效不执行的方法
2012/11/14 Javascript
jQuery 快速结束当前正在执行的动画
2013/11/20 Javascript
鼠标移到div,浮层显示明细,弹出层与div的上边距左边距重合(示例代码)
2013/12/14 Javascript
NodeJS学习笔记之网络编程
2014/08/03 NodeJs
如何让你的Lightbox支持滚轮缩放及Base64图片
2014/12/04 Javascript
基于jQuery实现带动画效果超炫酷的弹出对话框(附源码下载)
2016/02/22 Javascript
jQuery EasyUI菜单与按钮详解
2016/07/13 Javascript
AngularJS基础 ng-options 指令详解
2016/08/02 Javascript
jQuery实现的右下角广告窗体跟随效果示例
2016/09/16 Javascript
AngularJS中一般函数参数传递用法分析
2016/11/22 Javascript
jQuery实现二维码扫描功能
2017/01/09 Javascript
Jquery根据浏览器窗口改变调整大小的方法
2017/02/07 Javascript
VueJS组件之间通过props交互及验证的方式
2017/09/04 Javascript
node.js 基于cheerio的爬虫工具的实现(需要登录权限的爬虫工具)
2019/04/10 Javascript
Easyui 关闭jquery-easui tab标签页前触发事件的解决方法
2019/04/28 jQuery
javascript数组常见操作方法实例总结【连接、添加、删除、去重、排序等】
2019/06/13 Javascript
JS实现滚动条触底加载更多
2019/09/19 Javascript
解决Vue项目打包后打开index.html页面显示空白以及图片路径错误的问题
2019/10/25 Javascript
Python探索之创建二叉树
2017/10/25 Python
浅谈Pandas中map, applymap and apply的区别
2018/04/10 Python
Python实现点阵字体读取与转换的方法
2019/01/29 Python
python中逻辑与或(and、or)和按位与或异或(&amp;、|、^)区别
2020/08/05 Python
英国家喻户晓的折扣商场:TK Maxx
2017/05/26 全球购物
幼儿园教师奖惩制度
2014/02/01 职场文书
上课看小说检讨书
2014/02/22 职场文书
乡镇干部先进性教育活动个人整改措施
2014/09/16 职场文书
个人借条范本
2015/05/25 职场文书
趣味运动会赞词
2015/07/22 职场文书
react中props 的使用及进行限制的方法
2021/04/28 Javascript
python模板入门教程之flask Jinja
2022/04/11 Python