Skip to content

Commit 434fb62

Browse files
spadarjauhienegonSchiele
authored andcommitted
Add Elixir example for Dijkstra's algorithm
1 parent e8c1881 commit 434fb62

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
defmodule DijkstrasAlgorithm do
2+
def find_shortest_path(graph, costs, parents),
3+
do: do_find_shortest_path(graph, costs, parents, [])
4+
5+
defp do_find_shortest_path(graph, costs, parents, processed) do
6+
find_lowest_cost_node(costs, processed)
7+
|> process_node(processed, graph, costs, parents)
8+
end
9+
10+
defp process_node(nil, _, _, costs, parents), do: {costs, parents}
11+
12+
defp process_node(node, processed, graph, costs, parents) do
13+
node_cost = costs[node]
14+
neighbors = for(neighbor_node_cost <- graph[node], do: neighbor_node_cost)
15+
16+
{new_costs, new_parents} = process_node_neighbors(node, node_cost, neighbors, costs, parents)
17+
18+
do_find_shortest_path(graph, new_costs, new_parents, [node | processed])
19+
end
20+
21+
defp process_node_neighbors(node, node_cost, neighbors, costs, parents)
22+
23+
defp process_node_neighbors(_, _, [], costs, parents), do: {costs, parents}
24+
25+
defp process_node_neighbors(node, node_cost, [neighbor | tail], costs, parents) do
26+
{neighbor_node, neighbor_cost} = neighbor
27+
new_cost = node_cost + neighbor_cost
28+
29+
if costs[neighbor_node] > node_cost + neighbor_cost do
30+
new_costs = %{costs | neighbor_node => new_cost}
31+
new_parents = %{parents | neighbor_node => node}
32+
33+
process_node_neighbors(node, node_cost, tail, new_costs, new_parents)
34+
else
35+
process_node_neighbors(node, node_cost, tail, costs, parents)
36+
end
37+
end
38+
39+
defp find_lowest_cost_node(costs, processed) do
40+
{lowest_cost_node, _} =
41+
for({node, cost} <- costs, node not in processed, do: {node, cost})
42+
|> find_lowest_cost
43+
44+
lowest_cost_node
45+
end
46+
47+
defp find_lowest_cost([]), do: {nil, :infinity}
48+
49+
defp find_lowest_cost([node_cost | []]), do: node_cost
50+
51+
defp find_lowest_cost([node_cost = {_, cost} | tail]) do
52+
(min_node_cost = {_, min_cost}) = find_lowest_cost(tail)
53+
54+
if cost < min_cost,
55+
do: node_cost,
56+
else: min_node_cost
57+
end
58+
end
59+
60+
# the graph
61+
graph = %{
62+
"start" => %{"a" => 6, "b" => 2},
63+
"a" => %{"fin" => 1},
64+
"b" => %{"a" => 3, "fin" => 5},
65+
"fin" => %{}
66+
}
67+
68+
# the costs table
69+
costs = %{
70+
"a" => 6,
71+
"b" => 2,
72+
"fin" => :infinity
73+
}
74+
75+
# the parents table
76+
parents = %{
77+
"a" => "start",
78+
"b" => "start",
79+
"fin" => nil
80+
}
81+
82+
{costs, _} = DijkstrasAlgorithm.find_shortest_path(graph, costs, parents)
83+
IO.puts("Cost from the start to each node:")
84+
IO.inspect(costs)

0 commit comments

Comments
 (0)