我在python中实现了一个声学特征提取系统,我需要实现一个makefile式算法,以确保特征提取系统中的所有块都以正确的顺序运行,而不重复任何特征提取阶段。
此特征提取系统的输入将是一个详细说明特征提取块之间链接的图形,我想根据图形计算出要运行的函数。
此类系统的一个示例如下:
,-> [B] -> [D] ----+
input --> [A] ^ v
`-> [C] ----+---> [E] --> output
和函数调用(假设每个块X
是output = X(inputs)
形式的函数可能是这样的:
a = A(input)
b = B(a)
c = C(a)
d = D(b,c) # can't call D until both b and c are ready
output = E(d,c) # can't call E until both c and d are ready
我已经以字典的形式加载了函数图,其中每个字典条目(inputs, function)
都是这样的:
blocks = {'A' : (('input'), A),
'B' : (('A'), B),
'C' : (('A'), C),
'D' : (('B','C'), D),
'output' : (('D','C'), E)}
我目前正在弄清楚makefile算法究竟做了什么,以及如何实现它。我的google-fu似乎也不是很有帮助。如果有人至少可以给我一个指向良好讨论makefile算法的指针,这可能是一个好的开始。
答案 0 :(得分:5)
答案 1 :(得分:0)
blocks
基本上是(非循环)依赖图的邻接列表表示。因此,要获得处理块的正确顺序,可以执行拓扑排序。
答案 2 :(得分:0)
正如其他有用的回答者已经指出的那样,我所追求的是topological sort,但我认为我的具体情况稍微简单一点,因为函数图必须始终从input
开始,在output
结束。
所以,这就是我最终做的事情(我稍微编辑了一下,删除了一些依赖于上下文的东西,所以它可能不完全正确):
def extract(func_graph):
def _getsignal(block,signals):
if block in signals:
return signals[block]
else:
inblocks, fn = func_graph[block]
inputs = [_getsignal(i,signals) for i in inblocks]
signals[block] = fn(inputs)
return signals[block]
def extract_func (input):
signals = dict(input=input)
return _getsignal('output',signals)
return extract_func
所以现在我可以用
设置功能fn = extract(blocks)
并且根据我的喜好使用它多次:
list_of_outputs = [fn(i) for i in list_of_inputs]
我可能还应该对循环进行一些检查,但这是另一天的问题。
答案 3 :(得分:0)
对于许多语言的代码,包括Python,请尝试使用以下Rosetta代码链接:Topological sort和Topological sort/Extracted top item。