Class: IPXACT::Tools::GraphPathFinder
- Inherits:
-
Object
- Object
- IPXACT::Tools::GraphPathFinder
- Defined in:
- lib/ipxact_tools/graph_pathfinder.rb
Overview
GraphPathFinder instances handle graph-based pathfinding requests within a given IPXACT architecture. It is responsible for translating the IPXACT architecture into a list of connections and transition weights, which may then be queried for optimal paths between two nodes from the connection graph. As such, even though the path finder is pretty generic, it should not be used directly for IPXACT-related work.
Instance Method Summary collapse
-
#initialize(hash) ⇒ GraphPathFinder
constructor
The initializer is essentially used for passing a structured connection Hash.
-
#resolve(start, _end) ⇒ Array<Integer>
Searches an optimal path between the start and _end elements, which should be defined in the Hash structured used for instanciating the GraphPathFinder instance.
Constructor Details
#initialize(hash) ⇒ GraphPathFinder
The initializer is essentially used for passing a structured connection Hash.
58 59 60 |
# File 'lib/ipxact_tools/graph_pathfinder.rb', line 58 def initialize(hash) @hash = hash end |
Instance Method Details
#resolve(start, _end) ⇒ Array<Integer>
Searches an optimal path between the start and _end elements, which should be defined in the Hash structured used for instanciating the GraphPathFinder instance. Optimal should be understood as “the cheapest path given the cost of each connection”. Additionally, validates the latter Hash structure before executing the search algorithm.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/ipxact_tools/graph_pathfinder.rb', line 85 def resolve(start, _end) raise "Empty connection table!" if @hash.empty? return [] if start == _end raise "Duplicate connection node found!" if @hash[:nodes].uniq.size != @hash[:nodes].size raise "The source or target node does not exist!" unless @hash[:nodes].include?(start) && @hash[:nodes].include?(_end) @interconnect_table = (0..@hash[:nodes].size - 1).collect do |i| (0..@hash[:nodes].size - 1).collect do |j| result_hash = { :connection => @hash[:connections].any?{|connection| connection[:link] == [j,i]}, :total => Float::INFINITY, :previous => nil } if @hash[:connections].any?{|connection| connection[:link] == [j,i]} result = @hash[:connections].select{|connection| connection[:link] == [j,i]}.first[:cost] || 1 result_hash.merge!({:cost => result}) end result_hash end end start_index = @hash[:nodes].index(start) end_index = @hash[:nodes].index(_end) @interconnect_table[start_index][start_index][:total] = 0 rec_resolve([start_index, start_index], end_index, 0) last_writer_index = nil @interconnect_table[end_index].each_with_index do |el, i| last_writer_index = i if el[:total] < Float::INFINITY end raise "Destination could not be reached!" if last_writer_index.nil? dump_trajectory(end_index).reverse end |