我已经为基于HMM的信号实现了一个朴素的维特比算法。解码器的执行时间似乎对我的要求来说太慢了。我现在正试图了解如何加快执行速度。当我要确定算法的计算复杂度时,我发现它被提到具有t * s^2的复杂性,其中t是观察数,s是状态数。我有大约3500个状态和100个观测值。每个州有729个排放概率。
我也看到在这个paper中提到过,维特比解码在本文中是指数的(2 ^ k,其中k是约束长度)。我不太了解这个解释。但是,我相信如果Viterbi与状态有关,那么即使我将它并行化,算法也会很慢。
我的问题是:
编辑:我正在用C ++实现它,希望将来修改它并将其并行化。
回答第一个问题:
如果你有t观察,s状态,并且每个州有e排放概率,那么格子将有t*s
节点,并且评估每个节点将花费e操作,因此天真实现的整体复杂性将是O(t*s*e)
。
维特比解码可用于解码比特序列。如果观察取决于先前的k个二进制位,那么k个比特的不同序列的数量是2 ^ k。这表示您需要进行流解码的状态数(每个状态代表先前位的一种配置)。但是,这不太可能与您相关。
您链接的文章描述了一种减少需要扩展的节点数量的方法。这不会改善最坏情况的复杂性,但根据您的具体问题的性质,可能会在典型使用中给出重大改进。
维特比算法的复杂性是O(t|S|^{n+1})
,其中n
是马尔可夫模型的阶数(在你的情况下是1),t
是观察序列的长度,而|S|
是隐藏状态的数量。所以在你的情况下,你有一个O(t)
,其恒定系数为3500 ^ 2 = 12 250 000.你最好建议你尝试减少模型中隐藏状态的数量,或者使用随机运算速度更快的算法进行调查但不保证始终返回绝对最佳的结果。