dijkstra(迪杰斯特拉)单源最短路径算法php解决方案

    <?php
    /**
     *
     * @param int $start_id 起点节点id
     * @param int $end_id 终点节点id
     * @param array $node_arr 所有节点信息数据
     * @author 
     * 迪杰斯特拉 单源最短路劲计算
     *
     */
    function dijkstar($start_id, $end_id, $node_arr)
    {
       $start_node_id = $start_id;//设置开始节点
       //点位数据格式处理
       foreach ($node_arr as $node_info) {
          foreach ($node_info['next_node'] as $key => $next_node) {
             $i_cost[$node_info['node_id']][$next_node]['distance'] = $node_info['distance'][$key];
          }
          $i_dist[$node_info['node_id']]['distance'] = 'INF'; // 初始化为无穷大
          $i_dist[$node_info['node_id']]['road'] = $start_node_id; // 初始化为起点
          $b_mark[$node_info['node_id']] = false; // 初始化未加入
       }
       /*var_dump($i_cost);
       var_dump($i_dist);
       var_dump($b_mark);*/
       $i_dist[$start_node_id]['distance'] = 0; // 初始点到其本身的距离为0
       $b_mark[$start_node_id] = true; // 初始点加入集合
       $current_node_id = $start_node_id; // 最近加入的节点id
       $node_count = count($node_arr);//需要循环的次数
       /*var_dump($i_dist);
       var_dump($b_mark);
       var_dump($node_count);*/
       for ($i = 0; $i < $node_count; $i++) {
          $min = 'INF';
          // 当前节点的最近距离
          if (isset($i_cost[$current_node_id])&&is_array($i_cost[$current_node_id])) {
             foreach ($i_cost[$current_node_id] as $key => $val) {
                if ($i_dist[$key]['distance'] == 'INF' || $i_dist[$key]['distance'] > $i_dist[$current_node_id]['distance'] + $val['distance']) {
                   $i_dist[$key]['distance'] = $i_dist[$current_node_id]['distance'] + $val['distance'];
                   $i_dist[$key]['road'] = $i_dist[$current_node_id]['road'] . '#' . $key;
                }
             }
          }
          foreach ($i_dist as $key => $val) {
             if (!$b_mark[$key]) {
                if ($val['distance'] != 'INF' && ($min == 'INF' || $min > $val['distance'])) {
                   $min = $val['distance'];
                   $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['distance'] . '<br />';
       }*/
       //获取最短路径
       $arr = $i_dist[$end_id]['road'];
       echo '最短路径:'.str_replace('#','=>',$arr);
       echo '<br />';
       echo '距离为:'.$i_dist[$end_id]['distance'];
       var_dump($i_dist);
    }
    //所有节点信息
    $node_arr = [
       [
          'node_id' => 1,//当前节点id
          'next_node' => [
             2,
             4,
          ],//可通往的节点
          'distance' => [
             10,
             5,
          ],//相对应的节点距离
       ],
       [
          'node_id' => 2,
          'next_node' => [
             1,
             5
          ],
          'distance' => [
             10,
             5
          ],
       ],
       [
          'node_id' => 3,
          'next_node' => [
             6
          ],
          'distance' => [
             5
          ],
       ],
       [
          'node_id' => 4,
          'next_node' => [
             1,
             6,
             7,
             8,
             5,
             11
          ],
          'distance' => [
             5,
             15,
             5,
             8,
             10,
             5
          ],
       ],
       [
          'node_id' => 5,
          'next_node' => [
             2,
             4,
             8,
             7,
             6,
             12
          ],
          'distance' => [
             5,
             10,
             8,
             5,
             15,
             5
          ],
       ],
       [
          'node_id' => 6,
          'next_node' => [
             3,
             4,
             5,
             7,
             8
          ],
          'distance' => [
             5,
             15,
             15,
             11,
             11
          ],
       ],
       [
          'node_id' => 7,
          'next_node' => [
             4,
             8,
             5,
             6,
             9
          ],
          'distance' => [
             5,
             3,
             8,
             11,
             5
          ],
       ],
       [
          'node_id' => 8,
          'next_node' => [
             5,
             7,
             4,
             6
          ],
          'distance' => [
             5,
             3,
             8,
             11
          ],
       ],
       [
          'node_id' => 9,
          'next_node' => [
             10,
             11,
             12
          ],
          'distance' => [
             3,
             15,
             18
          ],
       ],
       [
          'node_id' => 10,
          'next_node' => [
             8,
             9,
             11,
             12
          ],
          'distance' => [
             5,
             3,
             18,
             15
          ],
       ],
       [
          'node_id' => 11,
          'next_node' => [
             12,
             4,
             9,
             10
          ],
          'distance' => [
             10,
             5,
             15,
             18
          ],
       ],
       [
          'node_id' => 12,
          'next_node' => [
             11,
             10,
             9,
             5
          ],
          'distance' => [
             10,
             15,
             18,
             5
          ],
       ],
    ];
    dijkstar(2, 8, $node_arr);
    ?>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值