43 lines
1.2 KiB
Ruby
43 lines
1.2 KiB
Ruby
#!/usr/bin/env ruby
|
|
|
|
# BFS method
|
|
def ao_bfs(net, cur_layer, seen=nil, order=nil)
|
|
# setup some state for this recursion
|
|
seen ||= Hash.new
|
|
order ||= Array.new
|
|
|
|
# mark current nodes as seen
|
|
cur_layer.each { |n| seen[n] = true }
|
|
|
|
# prepend current layer to final order
|
|
order = [cur_layer.sort] + order
|
|
|
|
# get next layer
|
|
next_layer = cur_layer.collect { |n| net[n] }
|
|
next_layer = next_layer.flatten.select { |n| not seen[n] }
|
|
|
|
if not next_layer.empty?
|
|
# recurse into next layer if it exists
|
|
ao_bfs(net, next_layer, seen, order)
|
|
else
|
|
# finished
|
|
order
|
|
end
|
|
end
|
|
|
|
# network format is a reverse digraph, so if node 0 feeds into node 1, you'd have 1 => [0]
|
|
# ... in other words, node 1 directly depends upon node 0
|
|
|
|
# 0,1,2 = inputs; 7,8,9 = outputs
|
|
net = { 0 => [], 1 => [4], 2 => [], 3 => [0,4,5], 4 => [2,6], 5 => [1], 6 => [5], 7 => [3], 8 => [5], 9 => [6] }
|
|
|
|
# call ao_bfs with output layer (or last layer)
|
|
puts ao_bfs(net, [7,8,9]).inspect
|
|
|
|
|
|
# DFS method
|
|
# use DFS to find terminal nodes
|
|
# as each terminal node is encountered, push it on the end of the order
|
|
# and as each node becomes terminal node (i.e. all leaves explored), push it on
|
|
|