做一個醫學項目,其中在病例評分時會用到單源最短路徑的演算法。單源最短路徑的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=,源點為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.'
';}}
其中例子為圖:
運行結果為:
0=>0:0
0=>4:10
0=>3:60
0=>2:30
0=>1:70
轉自: 康瑞的部落 » 單源最短路徑php實現