做一个医学项目,当中在病例评分时会用到单源最短路径的算法。单源最短路径的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数据源解决方案

    http://blog.163.com/qqabc20082006@126/blog/static/22928525201041944847653/

  2. shell中if做比较

    比较两个字符串是否相等的办法是: if [ "$test"x = "test"x ]; then 这里的关键有几点: 1 使用单个等号 2 注意到等号两边各有一 ...

  3. java第一天的疑问

    1字节 的 byte 2字节 的 char 精度 byte<short<char<int<long<float<double 随便打个整数默认为int 随便打个小数 ...

  4. Android中通过Java获取Webview加载内容

    有时候我们需要在加载webview时,获取加载完成的内容,当然,WebView也是有可能包含javascript.通过以下操作,我们是可以获取到WebView加载的内容. 1.自定义一个内部类,获取W ...

  5. AIDL Service

    开发AIDL服务的步骤 AIDL(Android Interface Definition Language)是Service的一种重要应用,允许一个应用程序访问另一个应用程序中的对象. 建立AIDL ...

  6. css3动画和jquery动画使用中要注意的问题

    前一阵子写demo的时候遇到这样一个问题,就是给元素添加css3或者jquery动画时,在动画结束前不能准确取到元素的css属性. 1. css3动画讨论 先看代码: html: <div id ...

  7. Phpcms V9全站伪静态设置方法

    为什么要伪静态?具体在这里就不说了,你懂的!一方面更新修改后不需要生成静态文件,另一方面为了SEO! 访问规则如下 1 2 list-{$catid}-{$page}.html content-{$c ...

  8. asp.net 防止页面刷新或后退引起重复提交

     项目中经常遇到刷新后重复的向数据库增加一条相同的记录,造成数据重复,如何规避这些问题呢?下面我们就一起讨论一下在asp.net怎样防止页面刷新或后退引起重复提交数据的问题: 其实asp.net防止刷 ...

  9. C语言刷新缓冲区(转载)

    C语言中有几个基本输入函数: //获取字符系列 int fgetc(FILE *stream); int getc(FILE *stream); int getchar(void); //获取行系列 ...

  10. Spark学习笔记--Graphx

    浅谈Graphx: http://blog.csdn.net/shangwen_/article/details/38645601 Pregel: http://blog.csdn.net/shang ...