perlでダイクストラ法

なんとなくダイクストラ法を使う機会がありそうなので、勉強がてらに。
ダイクストラ法は、2点間の最短距離を求めるアルゴリズムです。
カーナビとかにも使われているらしいです。

以下、さんぷるこーど。

#!/usr/bin/perl

use strict;
use Dumpvalue;

my @nodes = (
  {
    id       => 0,
    point    => [0,0],
    edges    => {1=>5,3=>6,4=>9},
    distance => 0,
    done     => 1,
    from     => undef,
  },
  {
    id       => 1,
    point    => [2,0],
    edges    => {0=>5,2=>5,3=>2,4=>2,5=>6},
    distance => 0,
    done     => undef,
    from     => undef,
  },
  {
    id       => 2,
    point    => [4,0],
    edges    => {1=>5,4=>1,5=>8},
    distance => 0,
    done     => undef,
    from     => undef,
  },
  {
    id       => 3,
    point    => [0,2],
    edges    => {0=>6,1=>2,4=>8},
    distance => 0,
    done     => undef,
    from     => undef,
  },
  {
    id       => 4,
    point    => [2,2],
    edges    => {0=>9,1=>2,2=>1,3=>8,5=>10},
    distance => 0,
    done     => undef,
    from     => undef,
  },
  {
    id       => 5,
    point    => [2,4],
    edges    => {1=>6,2=>8,4=>10},
    distance => 0,
    done     => undef,
    from     => undef,
  },
);

# 最短経路リスト
my $roots = {};

# スタートノード
my $done_node = $nodes[0];

while (1) {
  my $next_node = undef;
  my $distance = 0;
  
  # 次に伸びているノードの中で最小のものを調査
  while (my($edge,$cost) = each(%{$done_node->{edges}})) {
    # 既に通った道か?
    if ($nodes[$edge]->{done}) {
      next;
    }
    
    # 距離計算
    if (!$roots->{$edge} || $done_node->{distance} + $cost < $roots->{$edge}) {
      $nodes[$edge]->{distance} = $done_node->{distance} + $cost;
      $nodes[$edge]->{from}     = $done_node->{id};
      
      # 最短経路登録
      $roots->{$edge} = $nodes[$edge]->{distance};
    }
    
    # 比較
    if (!$next_node || $nodes[$edge]->{distance} < $next_node->{distance}) {
      $next_node = $nodes[$edge];
    }
  }
  
  # 次のノードが決まらなかった場合
  if (!$next_node) {
    last;
  }
  
  # 既に通った道として登録
  $next_node->{done} = 1;
  
  $done_node = $next_node;
}

# dump data
Dumpvalue->new->dumpValue(\$roots);

※追記
ダイクストラ法は、色々ある道の中で最短の経路を見出すもので、
全部の道を通っていく最短のルートを計算するのはワーシャルフロイド法ってヤツで計算するみたい。
若干勘違いしてたのでメモ。