RPCFN: Short Circuit (#3)やってみた
チャレンジしました
AからGまでの最短経路を探した上で、不要な経路を出力するというものです
RPCFN: Short Circuit (#3)
ダイクストラ法を参考にしました。正面衝突ブチ当たり
ダイクストラ法(最短経路問題)
コード
paths = [ {:from => "A", :to => "B", :len => 50}, {:from => "A", :to => "D", :len => 150}, {:from => "B", :to => "C", :len => 250}, {:from => "B", :to => "E", :len => 250}, {:from => "C", :to => "E", :len => 350}, {:from => "D", :to => "C", :len => 50}, {:from => "C", :to => "F", :len => 100}, {:from => "D", :to => "F", :len => 400}, {:from => "E", :to => "G", :len => 200}, {:from => "F", :to => "G", :len => 100}, ] done_node = "A" min_paths = [] def search_min_path(available_paths, done_node, min_len=0, searched_path=[]) available_paths -= searched_path done_undone_path = available_paths.select{|path| path[:from] == done_node}.min{|a,b| a[:len] <=> b[:len]} return searched_path.pop unless done_undone_path undone_node = done_undone_path[:to] return done_undone_path if undone_node == "G" undone_undone_next_path = available_paths.select{|path| path[:from] == undone_node}.min{|a,b| a[:len] <=> b[:len]} undone_next_node = undone_undone_next_path[:to] done_undone_next_path = available_paths.detect{|path| path[:from] == done_node && path[:to] == undone_next_node} if done_undone_next_path && done_undone_next_path[:len] <= done_undone_path[:len] + undone_undone_next_path[:len] return done_undone_next_path else if done_undone_path[:len] + undone_undone_next_path[:len] < min_len || min_len == 0 min_len = done_undone_path[:len] + undone_undone_next_path[:len] searched_path.push done_undone_path else searched_path.unshift done_undone_path end min_path = search_min_path(available_paths, done_node, min_len, searched_path) end min_path end while(done_node != "G") path = search_min_path(paths, done_node) done_node = path[:to] min_paths.push path end require 'pp' pp paths - min_paths
実行結果
# ruby short_circuit.rb [{:from=>"A", :to=>"B", :len=>50}, {:from=>"B", :to=>"C", :len=>250}, {:from=>"B", :to=>"E", :len=>250}, {:from=>"C", :to=>"E", :len=>350}, {:from=>"D", :to=>"F", :len=>400}, {:from=>"E", :to=>"G", :len=>200}]