做一个医学项目,当中在病例评分时会用到单源最短路径的算法。单源最短路径的dijkstra算法的思路例如以下:

如果存在一条从i到j的最短路径(Vi.....Vk,Vj),Vk是Vj前面的一顶点。那么(Vi...Vk)也必然是从i到k的最短路径。Dijkstra是以最短路径长度递增,逐次生成最短路径的算法。比如:对于源顶点V0,首先选择其直接相邻的顶点中长度最短的顶点Vi,那么当前已知可得从V0到达Vj顶点的最短距离dist[j]=min{dist[j],dist[i]+cost[i][j]}。如果G=<V, E>,源点为V0,U={V0}表示已经标记过的顶点集合,dist[i]记录V0到i的最短距离,cost[i][j]表示边i到j的开销。
  

1.从V-U中选择使dist[i]值最小的顶点i,将i增加到U中;

2.更新与i直接相邻顶点的dist值。(dist[j]=min{dist[j],dist[i]+cost[i][j]})

3.知道U=V,停止。

利用php特有的性质,其代码例如以下:

function dijkstra(){
$node_info_arr=array( //结点的邻接表结构
array(
'node_id'=>0, //某个结点的id
'next_node'=>array(4,2,1),
'node_type'=>0,
'cost'=>array(10,30,100)
),
array(
'node_id'=>4, //某个结点的id
'next_node'=>array(3),
'node_type'=>1,
'cost'=>array(50)
),
array(
'node_id'=>3, //某个结点的id
'next_node'=>array(1),
'node_type'=>1,
'cost'=>array(10)
),
array(
'node_id'=>2, //某个结点的id
'next_node'=>array(3,1),
'node_type'=>1,
'cost'=>array(60,60)
),
array(
'node_id'=>1, //某个结点的id
'next_node'=>array(),
'node_type'=>2,
'cost'=>array()
)
); $start_node_id=false; //起始结点id
$i_cost=array(array()); //两个节点之间的开销
$i_dist=array(); //起始点到各点的最短距离
$b_mark=array(); //是否增加了
foreach($node_info_arr as &$node_info){
if($node_info['node_type']==0){
$start_node_id=$node_info['node_id']; //找到初始节点
}
foreach($node_info['next_node'] as $key=>$next_node){
$i_cost[$node_info['node_id']][$next_node]=$node_info['cost'][$key];
}
$i_dist[$node_info['node_id']]='INF'; //初始化为无穷大
$b_mark[$node_info['node_id']]=false; //初始化未增加
}
if($start_node_id===false){
return '302';
}
//计算初始结点到各节点的最短路径
$i_dist[$start_node_id]=0; //初始点到其本身的距离为0
$b_mark[$start_node_id]=true; //初始点增加集合 $current_node_id=$start_node_id; //近期增加的节点id
$node_count=count($node_info_arr);
for($i=0;$i<$node_count;$i++){
$min='INF'; //当前节点的近期距离
if(is_array($i_cost[$current_node_id])){
foreach($i_cost[$current_node_id] as $key=>$val){
if($i_dist[$key]=='INF'||$i_dist[$key]>$i_dist[$current_node_id]+$val){
$i_dist[$key]=$i_dist[$current_node_id]+$val;
}
}
}
foreach($i_dist as $key=>$val){
if(!$b_mark[$key]){
if($val!='INF'&&($min=='INF'||$min>$val)){
$min=$val;
$candidate_node_id=$key; //候选近期结点id
}
}
}
if($min=='INF'){
break;
}
$current_node_id=$candidate_node_id;
$b_mark[$current_node_id]=true;
}
foreach($i_dist as $key=>$val){
echo $start_node_id.'=>'.$key.':'.$val.'<br />';
}
}

 当中样例为图:

    

执行结果为:

    0=>0:0

    0=>4:10

    0=>3:60

    0=>2:30

    0=>1:70

单源最短路径(dijkstra算法)php实现的更多相关文章

  1. 单源最短路径Dijkstra算法,多源最短路径Floyd算法

    1.单源最短路径 (1)无权图的单源最短路径 /*无权单源最短路径*/ void UnWeighted(LGraph Graph, Vertex S) { std::queue<Vertex&g ...

  2. 单源最短路径——dijkstra算法

    dijkstra算法与prim算法的区别   1.先说说prim算法的思想: 众所周知,prim算法是一个最小生成树算法,它运用的是贪心原理(在这里不再证明),设置两个点集合,一个集合为要求的生成树的 ...

  3. 单源最短路径 dijkstra算法实现

    本文记录一下dijkstra算法的实现,图用邻接矩阵表示,假设图为无向图.而且连通,有向图,不连通图的做法相似. 算法简述: 首先确定"单源"的源.假设是第0个顶点. 维护三个数组 ...

  4. 单源最短路径——Dijkstra算法学习

    每次都以为自己理解了Dijkstra这个算法,但是过没多久又忘记了,这应该是第4.5次重温这个算法了. 这次是看的胡鹏的<地理信息系统>,看完之后突然意识到用数学公式表示算法流程是如此的好 ...

  5. 单源最短路径-Dijkstra算法

    1.算法标签 贪心 2.算法描述 具体的算法描述网上有好多,我觉得莫过于直接wiki,只说明一些我之前比较迷惑的. 对于Dijkstra算法,最重要的是维护以下几个数据结构: 顶点集合S : 表示已经 ...

  6. [数据结构与算法-15]单源最短路径(Dijkstra+SPFA)

    单源最短路径 问题描述 分别求出从起点到其他所有点的最短路径,这次主要介绍两种算法,Dijkstra和SPFA.若无负权优先Dijkstra算法,存在负权选择SPFA算法. Dijkstra算法 非负 ...

  7. matlab练习程序(单源最短路径Dijkstra)

    图的相关算法也算是自己的一个软肋了,当年没选修图论也是一大遗憾. 图像处理中,也有使用图论算法作为基础的相关算法,比如图割,这个算法就需要求最大流.最小割.所以熟悉一下图论算法对于图像处理还是很有帮助 ...

  8. 单源最短路径---Bellman-Ford算法

    传送门: Dijkstra Bellman-Ford SPFA Floyd 1.Dijkstra算法的局限性 像上图,如果用dijkstra算法的话就会出错,因为如果从1开始,第一步dist[2] = ...

  9. 洛谷P3371单源最短路径Dijkstra版(链式前向星处理)

    首先讲解一下链式前向星是什么.简单的来说就是用一个数组(用结构体来表示多个量)来存一张图,每一条边的出结点的编号都指向这条边同一出结点的另一个编号(怎么这么的绕) 如下面的程序就是存链式前向星.(不用 ...

  10. 单源最短路径Dijkstra和优先级算法

    百度百科:迪杰斯特拉算法. 代码实现如下: import java.util.Comparator; import java.util.PriorityQueue; import java.util. ...

随机推荐

  1. java 格式判断

    public class FormatChecker { /** * 判断是否含有汉字 * @param string */ public static boolean containChinese( ...

  2. 排序算法之奇偶排序 JAVA奇偶排序算法

    奇偶排序法的思路是在数组中重复两趟扫描.第一趟扫描选择所有的数据项对,a[j]和a[j+1],j是奇数(j=1, 3, 5……).如果它们的关键字的值次序颠倒,就交换它们.第二趟扫描对所有的偶数数据项 ...

  3. 秒味课堂Angular js笔记------指令

    1.属性指令 angularjs样式相关指令: ng-class ng-style ng-href ng-src ng-attr-(suffix) ng-bind ng-cloak  没解析完之前标签 ...

  4. java多线程心得

    多并发的时候,在什么情况下必须加锁?如果不加锁会产生什么样的后果. 加锁的场景跟java的new thread和Runnable的关系是什么? 看看java的concurrentMap源码. 还有sp ...

  5. JNI类型与C/C++映射关系

    Java 类型 本地类型 描述 boolean jboolean C/C++8位整型 byte jbyte C/C++带符号的8位整型 char jchar C/C++无符号的16位整型 short ...

  6. web项目环境搭建(1):建立一个maven项目

    一.maven简介以及常用概念 1.Maven是一个项目管理和整合的工具.Maven为开发者提供了一套完整的构建生命周期框架.开发团队基本不用花多少时间就能自动完成工程的基础构建配置,因为Maven使 ...

  7. java事件处理4(焦点,键盘

    FocusEvent焦点事件 接口 addFocusListener(FocusListener listener) 有两个方法 public void focusGains(FocusEvent e ...

  8. DOM动态添加表格

    var table=document.createElement("table"); table.border=1; var b=document.createElement(&q ...

  9. Secure CRT 如何连接虚拟机里面的CentOS系统——当主机使用无线网的时候 作者原创 欢迎转载

    第一步:设置自己的无线网,并且分享给VM8这个虚拟网卡 第二步:查看VM8网卡的IP地址,如图是192.168.137.1 第三步:设置虚拟机的配置:选择VM8网卡并且是NAT的 第四步:设置虚拟机里 ...

  10. 【学习笔记】【Foundation】字典

    字典NSDictionary: 用于保存具有映射关系的数据:key-value: 创建NSDictionary的常用方法: dictionary: dictionaryWithContentsOfFi ...