-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
068cd42
commit 62b5726
Showing
2 changed files
with
96 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
local BFS = require "algo.BFS" | ||
local Graph = require "algo.Graph" | ||
|
||
local function load_input(input) | ||
local G = Graph:new() | ||
for _, edge in ipairs(input) do | ||
local from, to, cost = edge:match('(%w-)%-(%w+)=(%d+)') | ||
G:add(from, to, cost) | ||
end | ||
return G | ||
end | ||
|
||
local function tim_test() | ||
print("BFS tim_test...") | ||
local input<const> = {'s-v=1', 's-w=4', 'v-w=2', 'v-t=6', 'w-t=3'} | ||
local src<const> = 's' | ||
local G = load_input(input) | ||
local level_counts = {} | ||
for from, to, weight, level in BFS:new(G, src):iterate() do | ||
level_counts[level] = level_counts[level] or 0 | ||
level_counts[level] = level_counts[level] + 1 | ||
print(string.format("%d: %s-%s=%d", level, from, to, weight)) | ||
end | ||
assert(level_counts[1] == 2) | ||
assert(level_counts[2] == 3) | ||
assert(level_counts[3] == 1) | ||
end | ||
|
||
local function scott_moura_test() | ||
print("BFS scott_moura_test ... ") | ||
local input<const> = {'A-B=2', 'A-C=4', 'A-D=4', 'B-F=6', 'C-F=5', 'C-E=7', 'C-D=1', 'D-E=5', 'D-H=11', 'E-G=3', | ||
'E-H=4', 'F-H=5', 'F-G=2', 'F-E=1', 'G-H=2'} | ||
local src<const> = 'A' | ||
local level_counts = {} | ||
local G = load_input(input) | ||
for from, to, weight, level in BFS:new(G, src):iterate() do | ||
level_counts[level] = level_counts[level] or 0 | ||
level_counts[level] = level_counts[level] + 1 | ||
print(string.format("%d: %s-%s=%d", level, from, to, weight)) | ||
end | ||
assert(level_counts[1] == 3) | ||
assert(level_counts[2] == 6) | ||
assert(level_counts[3] == 12) | ||
assert(level_counts[4] == 10) | ||
assert(level_counts[5] == 3) | ||
end | ||
|
||
tim_test() | ||
scott_moura_test() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
local Graph = require "algo.Graph" | ||
local Queue = require "algo.Queue" | ||
local BFS = {} | ||
local E = {} | ||
|
||
local function _iterate(bfs) | ||
local q = Queue:new() | ||
local level = 0 | ||
local from = bfs.src_vertex | ||
repeat | ||
local vertex = bfs.graph:vertex(from) | ||
level = level + 1 | ||
for to, weight in vertex:outgoings() do | ||
coroutine.yield(from, to, weight, level) | ||
q:enqueue{to, weight, level, from} | ||
end | ||
local item = (q:dequeue() or E) | ||
from, level = item[1], item[3] | ||
until not from or from == bfs.src_vertex | ||
end | ||
|
||
function BFS:iterate() | ||
return coroutine.wrap(function() | ||
_iterate(self) | ||
end) | ||
end | ||
|
||
function BFS:class(o) | ||
setmetatable(o, BFS) | ||
BFS.__index = BFS | ||
return o | ||
end | ||
|
||
---@param G (table) graph | ||
---@param src (any) source vertex | ||
function BFS:new(G, src) | ||
assert(G, "Missing Graph") | ||
assert(Graph.isGraph(G), "G must be a graph object") | ||
assert(src, "Missing source vertex") | ||
assert(G:vertex(src), "Source vertex not found in graph") | ||
return BFS:class{ | ||
graph = G, | ||
src_vertex = src | ||
} | ||
end | ||
|
||
return BFS |