在流中查找非连续的重复模式

时间:2013-09-23 10:18:00

标签: algorithm data-structures pattern-matching bigdata

我正试图找出一种方法来检测数字流中某些模式的重现。问题是 - 图案元素不一定相邻。

例如,请使用以下流(此处的每个字母表示唯一编号):

A  C  B  D  A  E  B  F  G  A  H  B  I  A  J  B ...

明显的模式是A _ B。自然AB本身也是模式,所以假设我们希望所有模式都高于某个阈值长度 - 在这种情况下为2,或者所有不属于较长模式的模式 - 要么定义适合我。还要注意,它不会以任何固定的速率重复出现(即 - 模式的2个实例可以通过任意数量的元素在它们之间间隔开)。您可能还会注意到'B _ A'和'A _ B _ A _ B'也是重复出现的模式 - 这些也可以作为输出。

顺便说一句,这简化了事情,实际上我可以让A和B也出现在那个模式之外,也许将来我甚至会认识到A _ _ B(或某些距离内部的距离)阈值),但现在我已经解决了上述更简单的问题。

还有一个限制 - 可能的值有限,抱歉。这真的削弱了我能想到的大部分解决方案。然而,从好的方面来说,我对复杂性有点松懈,我会解决几乎没有任何进攻性指数的问题(尽管我的糟糕计算机将不得不提供有效的解决方案:))

有两个想法可以解决这个问题 -

  1. 保留值的“矩阵”,填充距离,识别重复的delta并标记它们。由于该区域没有界限,因此该矩阵必须是整个值空间的区块(从最低到最高的值)。为了空间优化,我想的可能是多个矩阵,每个“组”值一个,并以另一种方式处理交叉矩阵增量。

  2. 某种卷积/类似FFT的方法 - 将流的一部分与自身匹配,改变偏移,一次查看多少匹配。我不知道我们怎么能适应这里。

  3. 如果有人有更好的方法来解决这个问题,知道一个现有的算法,怀疑问题是不可解决的,或者可以帮助我在建议的两个选项之间做出选择(或者发现它们的问题),我会非常感激有义务的。如果某些事情不清楚约束或示例 - 留下评论,我会添加它。

    提前致谢!


    编辑:添加基于后缀树的解决方案选项。刚刚发现了Ukkonen的算法(Ukkonen's suffix tree algorithm in plain English?),试图确定它是否有用......

1 个答案:

答案 0 :(得分:0)

我认为您可以使用类似优先级队列的结构。这是我能想到的:

While (your input stream has more elements)
    Check if it is 'A'

    if it is 'A':
        insert it in the queue

    // Now you have to look for 'B'
    if current element is NOT 'B'
        insert it in the queue

    // As soon as you get 'B'
    you can empty the queue and you have the pattern

    // If you find 'A' while looking for 'B'
    whatever you have in queue, just discard it, because in a pattern like A..A...B, A..A is not of your interst I believe

您可以添加其他约束,例如最小长度。 您也可以使用LinkedList。