眠くなくなったから続き
ちょっとはマトモになったかね。微妙。あんまり良くない。オブジェクト指向が簡単に使いやすいRubyの方が頭がすっきりするんじゃないかという気分になってきた。Ruby使ったことないけど。オブジェクト指向プログラミングしたことないけど。
use strict; use warnings; use Data::Dumper; $Data::Dumper::Indent=1; my $route = { bos => { 'こんばんは' => 20, 'こんにちは' => 10, }, 'こんにちは' => { 'こんばんは' => 5, }, 'こんばんは' => { eos => 5, }, }; sub dijkstra{ my ($bos, $eos, $route) = @_; $route->{$bos}{cost} = 0; $route->{$bos}{route} = ''; $route->{decision} = [$bos]; while(!grep/$eos/,@{$route->{decision}}){ my ($minnode, $mynode, $mycost, $pos); for $pos(@{$route->{decision}}){ for $mynode(keys %{$route->{$pos}}){ next if($mynode eq 'cost'||$mynode eq 'route'||grep/$mynode/,@{$route->{decision}}); $mycost = $route->{$pos}{cost} + $route->{$pos}{$mynode}; if(!defined($route->{$mynode}{cost}) || $route->{$mynode}{cost}>$mycost){ $route->{$mynode}{cost} = $mycost; $route->{$mynode}{route} = $route->{$pos}{route} . (($bos ne $pos)&&$pos); } $mycost = $route->{$mynode}{cost}; push @{$route->{decretal}}, $mynode; $minnode = $mynode if(!defined$minnode || $route->{$minnode}{cost} > $mycost); } } @{$route->{decretal}} = grep/!$minnode/, @{$route->{decretal}}; push @{$route->{decision}}, $minnode; } } dijkstra('bos', 'eos', $route); print Dumper($route);
$VAR1 = { 'eos' => { 'cost' => 20, 'route' => 'こんにちはこんばんは' }, 'こんにちは' => { 'cost' => 10, 'route' => '', 'こんばんは' => 5 }, 'decretal' => [], 'decision' => [ 'bos', 'こんにちは', 'こんばんは', 'eos' ], 'こんばんは' => { 'cost' => 15, 'eos' => 5, 'route' => 'こんにちは' }, 'bos' => { 'cost' => 0, 'こんにちは' => 10, 'route' => '', 'こんばんは' => 20 } };
decretal orderこと仮決定ノードというものも記録させておいてるけど、別にいらないかな。decisionじゃないのは全部仮決定なんだから。undefは無限大値を示すとする。あとこれ道が全部一方通行に定義してるけど、会話プログラムの場合、特定の単語では両方向通行可能になるな。
そういえば何故か末尾再帰にしていた関数をループにした。終了条件をwhile()の中に入れてブラケットで囲むだけで書き換えれた。