局部序列略微乱序的最长公共序列
Longest Common Sequence with Sequences Slightly Out of order Locally
我需要解决两个序列之间的最长公共序列问题,当它们稍微乱序并且乱序的节点彼此靠近时。换句话说,假设其中一个序列是 s1 s2 s3 ... s_n。它可能与 s1 和 s2 交换,或 s1 和 s3 交换,或 s_{n-1} 和 s_n 交换,但 s1 和 s_n 不太可能交换顺序。
当观察到的序列是许多同时生成的序列的混合时,就会出现这种情况。例如,如果我有两个并发源生成 (a1, a2, ..., a100) 和 (b1, b2, ..., b100)。许多节点几乎在同一时间生成,因此我们用于匹配的组合序列最终可能变成 (a1, a2, b1, b2, ... ), 或 (a1, b1, a2, b2 );因为节点 a1、a2、a3、b1、b2、b3 可能在同一纳秒内生成,并且任何顺序都是可能的。但是a1和b100不可能交换订单,因为它们是相隔几秒生成的。
假设有两个这样的序列,它们在全局上是有序的,但在局部可能会有小的重新排列。这种情况下如何应用最长公共序列算法?
很抱歉没有回答。
想法是从每个序列中读入一个暂存池,然后当池中的内容即将到期时,尝试将它们与另一个序列配对。池越大,允许的重排就越大。
class CurrentPool:
def __init__ (self, items):
self.items = items
self.index = -1
self.pool = {}
self.empty = False
def read_into_pool(self):
self.index += 1
if self.index < len(self.items):
self.pool[self.index] = self.items[self.index]
elif 0 == len(self.pool):
self.empty = True
return self.pool
def compare_lists (items1, items2, max_offset=1):
pool1 = CurrentPool(items1)
pool2 = CurrentPool(items2)
trailing_index = -max_offset
lcs = []
while not pool1.empty and not pool2.empty:
temp_pool1 = pool1.read_into_pool()
temp_pool2 = pool2.read_into_pool()
# We are forced to take keys if they are at the trailing_index.
if trailing_index in temp_pool1:
# Look for a match.
min_index = None
for i, val in temp_pool2.items():
if val == temp_pool1[trailing_index]:
if min_index is None or i < min_index:
min_index = i
del temp_pool1[trailing_index]
if min_index is not None:
lcs.append(temp_pool2[min_index])
del temp_pool2[min_index]
if trailing_index in temp_pool2:
# Look for a match the other way
min_index = None
for i, val in temp_pool1.items():
if val == temp_pool2[trailing_index]:
if min_index is None or i < min_index:
min_index = i
del temp_pool2[trailing_index]
if min_index is not None:
lcs.append(temp_pool1[min_index])
del temp_pool1[min_index]
else:
# We only drain if we find a good match.
pass
trailing_index += 1
return lcs
print(compare_lists([1, 2, 3, 4, 5, 6], [2, 1, 4, 5, 7], 2))
我需要解决两个序列之间的最长公共序列问题,当它们稍微乱序并且乱序的节点彼此靠近时。换句话说,假设其中一个序列是 s1 s2 s3 ... s_n。它可能与 s1 和 s2 交换,或 s1 和 s3 交换,或 s_{n-1} 和 s_n 交换,但 s1 和 s_n 不太可能交换顺序。
当观察到的序列是许多同时生成的序列的混合时,就会出现这种情况。例如,如果我有两个并发源生成 (a1, a2, ..., a100) 和 (b1, b2, ..., b100)。许多节点几乎在同一时间生成,因此我们用于匹配的组合序列最终可能变成 (a1, a2, b1, b2, ... ), 或 (a1, b1, a2, b2 );因为节点 a1、a2、a3、b1、b2、b3 可能在同一纳秒内生成,并且任何顺序都是可能的。但是a1和b100不可能交换订单,因为它们是相隔几秒生成的。
假设有两个这样的序列,它们在全局上是有序的,但在局部可能会有小的重新排列。这种情况下如何应用最长公共序列算法?
很抱歉没有回答。
想法是从每个序列中读入一个暂存池,然后当池中的内容即将到期时,尝试将它们与另一个序列配对。池越大,允许的重排就越大。
class CurrentPool:
def __init__ (self, items):
self.items = items
self.index = -1
self.pool = {}
self.empty = False
def read_into_pool(self):
self.index += 1
if self.index < len(self.items):
self.pool[self.index] = self.items[self.index]
elif 0 == len(self.pool):
self.empty = True
return self.pool
def compare_lists (items1, items2, max_offset=1):
pool1 = CurrentPool(items1)
pool2 = CurrentPool(items2)
trailing_index = -max_offset
lcs = []
while not pool1.empty and not pool2.empty:
temp_pool1 = pool1.read_into_pool()
temp_pool2 = pool2.read_into_pool()
# We are forced to take keys if they are at the trailing_index.
if trailing_index in temp_pool1:
# Look for a match.
min_index = None
for i, val in temp_pool2.items():
if val == temp_pool1[trailing_index]:
if min_index is None or i < min_index:
min_index = i
del temp_pool1[trailing_index]
if min_index is not None:
lcs.append(temp_pool2[min_index])
del temp_pool2[min_index]
if trailing_index in temp_pool2:
# Look for a match the other way
min_index = None
for i, val in temp_pool1.items():
if val == temp_pool2[trailing_index]:
if min_index is None or i < min_index:
min_index = i
del temp_pool2[trailing_index]
if min_index is not None:
lcs.append(temp_pool1[min_index])
del temp_pool1[min_index]
else:
# We only drain if we find a good match.
pass
trailing_index += 1
return lcs
print(compare_lists([1, 2, 3, 4, 5, 6], [2, 1, 4, 5, 7], 2))