Module: Legion::Extensions::Agentic::Integration::Map::Helpers::GraphTraversal
- Defined in:
- lib/legion/extensions/agentic/integration/map/helpers/graph_traversal.rb
Class Method Summary collapse
- .bfs_component(locations, start, visited, component) ⇒ Object
- .bfs_reachable(locations, start, max_distance) ⇒ Object
- .build_path_result(_locations, prev, from, to, cost) ⇒ Object
- .connected_components(locations) ⇒ Object
- .dijkstra(locations, from, to) ⇒ Object
- .expand_neighbors(locations, current, dist, max_distance, visited, queue) ⇒ Object
- .reconstruct_path(prev, from, to) ⇒ Object
- .relax_edges(locations, node, dist, prev, queue) ⇒ Object
Class Method Details
.bfs_component(locations, start, visited, component) ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/legion/extensions/agentic/integration/map/helpers/graph_traversal.rb', line 105 def bfs_component(locations, start, visited, component) queue = [start] while (current = queue.shift) next if visited[current] visited[current] = true component << current loc = locations[current] next unless loc loc.neighbors.each_key { |nid| queue << nid unless visited[nid] } end end |
.bfs_reachable(locations, start, max_distance) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/legion/extensions/agentic/integration/map/helpers/graph_traversal.rb', line 30 def bfs_reachable(locations, start, max_distance) visited = { start => 0.0 } queue = [[0.0, start]] reachable = [] until queue.empty? dist, current = queue.min_by { |d, _| d } queue.delete([dist, current]) next if dist > max_distance reachable << { id: current, distance: dist.round(4) } unless current == start (locations, current, dist, max_distance, visited, queue) end reachable.sort_by { |r| r[:distance] } end |
.build_path_result(_locations, prev, from, to, cost) ⇒ Object
74 75 76 77 78 79 |
# File 'lib/legion/extensions/agentic/integration/map/helpers/graph_traversal.rb', line 74 def build_path_result(_locations, prev, from, to, cost) return { found: false, reason: :no_path } if cost == Float::INFINITY path = reconstruct_path(prev, from, to) path.empty? ? { found: false, reason: :no_path } : { found: true, path: path, distance: cost.round(4) } end |
.connected_components(locations) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/legion/extensions/agentic/integration/map/helpers/graph_traversal.rb', line 47 def connected_components(locations) visited = {} components = [] locations.each_key do |id| next if visited[id] component = [] bfs_component(locations, id, visited, component) components << component end components end |
.dijkstra(locations, from, to) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/legion/extensions/agentic/integration/map/helpers/graph_traversal.rb', line 12 def dijkstra(locations, from, to) dist = Hash.new(Float::INFINITY) prev = {} dist[from] = 0.0 queue = [[0.0, from]] until queue.empty? d, u = queue.min_by { |x, _| x } queue.delete([d, u]) break if u == to next if d > dist[u] relax_edges(locations, u, dist, prev, queue) end build_path_result(locations, prev, from, to, dist[to]) end |
.expand_neighbors(locations, current, dist, max_distance, visited, queue) ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/legion/extensions/agentic/integration/map/helpers/graph_traversal.rb', line 91 def (locations, current, dist, max_distance, visited, queue) loc = locations[current] return unless loc loc.neighbors.each do |nid, edge_dist| new_dist = dist + edge_dist next if new_dist > max_distance next if visited.key?(nid) && visited[nid] <= new_dist visited[nid] = new_dist queue << [new_dist, nid] end end |
.reconstruct_path(prev, from, to) ⇒ Object
81 82 83 84 85 86 87 88 89 |
# File 'lib/legion/extensions/agentic/integration/map/helpers/graph_traversal.rb', line 81 def reconstruct_path(prev, from, to) path = [] current = to while current path.unshift(current) current = prev[current] end path.first == from ? path : [] end |
.relax_edges(locations, node, dist, prev, queue) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/legion/extensions/agentic/integration/map/helpers/graph_traversal.rb', line 60 def relax_edges(locations, node, dist, prev, queue) loc = locations[node] return unless loc loc.neighbors.each do |v, weight| alt = dist[node] + weight next unless alt < dist[v] dist[v] = alt prev[v] = node queue << [alt, v] end end |