ダイクストラ法を実装しようとしたら、よくわからないものになった
30分プログラム、その518。ダイクスラ法を実装しようとしたら、よくわからないものになった。
変な点は、対象とするグラフがDAGのみになっている点と、たぶん計算量が増えてる点。もともと手続き的だったアルゴリズムを、再帰でキレイに書こうして失敗したのが原因だと思う。
使い方
let nodes = ["A";"B";"C"] let edges = [ {from="A"; to_="B";cost=3}; {from="B"; to_="C";cost=3}; {from="A"; to_="C";cost=4}; ] let graph = { nodes = nodes; edges = edges; } let main () = short_path graph "A" "C"
ソースコード
let (@@) f g = f g let (+>) f g = g f type node = string type edge = { from: node; to_: node; cost: int } type graph = { nodes: node list; edges: edge list } let from_edges {edges=edges} node = edges +> List.filter (fun {to_=to_} -> node = to_) let rec short_path graph start goal = if start = goal then 0 else let costs = List.map (fun {from=node; cost=cost} -> cost + short_path graph start node) @@ from_edges graph goal in match costs with | [] -> failwith "no route!" | x::xs -> List.fold_left min x xs let nodes = ["A";"B";"C"] let edges = [ {from="A"; to_="B";cost=3}; {from="B"; to_="C";cost=3}; {from="A"; to_="C";cost=4}; ] let graph = { nodes = nodes; edges = edges; } let f _ = short_path graph "A" "C"