Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在列表列表中查找最长递增子序列的最有效方法_Python_Algorithm_Signal Processing - Fatal编程技术网

Python 在列表列表中查找最长递增子序列的最有效方法

Python 在列表列表中查找最长递增子序列的最有效方法,python,algorithm,signal-processing,Python,Algorithm,Signal Processing,我正在做一些信号分析,其中的一部分是找到最长的子序列 我的字典如下: sequenceDict = { 0: [168, 360, 470], 1: [279, 361, 471, 633, 729, 817], 2: [32, 168, 170, 350, 634, 730, 818], 3: [33, 155, 171, 363, 635, 731, 765, 819], 4: [352, 364, 732, 766, 822], 5: [15

我正在做一些信号分析,其中的一部分是找到最长的子序列

我的字典如下:

sequenceDict = {
    0: [168, 360, 470],
    1: [279, 361, 471, 633, 729, 817],
    2: [32, 168, 170, 350, 634, 730, 818],
    3: [33, 155, 171, 363, 635, 731, 765, 819],
    4: [352, 364, 732, 766, 822],
    5: [157, 173, 353, 577, 637, 733, 823, 969],
    6: [158, 174, 578, 638, 706, 734, 824],
    7: [159, 175, 579, 707, 735],
    8: [160, 464, 640, 708, 826],
    9: [173, 709, 757, 827],
    10: [174, 540, 642, 666, 710],
    11: [253, 667, 711],
    12: [254, 304, 668],
    13: [181, 255, 831],
    14: [256, 340, 646, 832],
    16: [184, 416], 
    17: [417], 
    18: [418], 
    19: [875], 
    20: [876], 
    23: [217], 
    24: [168, 218, 880], 
    25: [219, 765, 881], 
    26: [220, 766], 
    27: [221], 
    28: [768], 
    29: [3, 769], 
    30: [344, 476, 706]}
这些基本上都是另一个数组的排序索引,我想找到最长的递增序列(就像a),只从每个键中按顺序选取一个数字(键2紧跟在键1之后,依此类推),例如, 根据键0和键1,[360361]是一个序列,[470471]是另一个序列。 我称之为递增序列,因为这些数字应该严格地增加1

我已经研究过诸如此类的问题,但由于这个问题略有不同,而且也有一个序列树,除了从这个dict生成所有可能的序列,然后运行耐心排序之外,是否有任何已知的python实现,或者其他有效的方法来实现这一点?

我只想实现一个“蛮力”解决方案

  • 保留“当前序列”列表,最初为空
  • 对于每个键,检查是否有任何当前序列可以扩展一步。增加序列更新也是目前为止最好的解决方案
  • 对于未用于扩展序列的任何数字,请启动长度为1的新序列
  • Python提供了
    set
    ,这可能是一个合理的选择。。。这是一个示例实现:

    best = None
    current_sequences = set()
    last_key = None
    for key in sorted(sequenceDict.keys()):
        data = set(sequenceDict[key])
        new_sequences = set()
        if last_key == key-1:
            # no gap in key value, may be some sequence got extended
            for val, count in current_sequences:
                if val+1 in data:
                    # found a continuation, keep this sequence
                    new_sequences.add((val+1, count+1))
                    data.remove(val+1)
                    if best is None or count+1 > best[0]:
                        # we've got a new champion
                        best = count+1, val+1, key
        # add new sequences starting here
        for v in data:
            new_sequences.add((v, 1))
            if best is None:
                best = 1, v, key
        current_sequences = new_sequences
        last_key = key
    
    一个棘手的部分是,如果键中有间隙,则无法扩展序列,这就是
    last_键
    的用途

    复杂性应该是
    O(输入\u大小×序列的平均\u数量)
    。我的感觉只是直觉,但我的猜测是,你不能再低了。我很想使用
    value-key
    将常量值与每个序列关联起来。。。但是,这不会检测到“间隙”(即键1中的值100和键3中的值102,但键2中的没有101)


    输入问题后,解决方案是
    (7,735,7)
    ,意思是一个7元素序列,在键7处以值735结尾。

    与@6502的解决方案相比,这个解决方案不仅保留了最佳解决方案,而且还跟踪了每个递增的子序列,如果这更有帮助的话。

    这个想法类似于滑动窗口方法。从第一个列表开始,更新
    currentHotItems
    globalHotItems
    词典,然后查看第二个列表并再次更新词典,以此类推

    # fill missing indexes in the dictionary:
    for i in range(min(sequenceDict), max(sequenceDict)):
        if i not in sequenceDict:
            sequenceDict[i] = []
    
    # get only lists, ordered:
    sortedItems = map(lambda x:x[1], sorted(sequenceDict.items(), key=lambda x:x[0]))    
    globalHotItems = {} # (value, startIndex): length
    currentHotItems = {} # value: length
    
    for i in range(len(sortedItems)):
        updatedHotItems = {} # updated value: length
        for item in sortedItems[i]:
            if (item - 1) in currentHotItems:
                updatedHotItems[item] = currentHotItems[item-1] + 1
            else:
                updatedHotItems[item] = 1
    
        deadSet = set(currentHotItems.keys()) - \
                set(updatedHotItems.keys() + [key - 1 for key in updatedHotItems.keys()])
    
        for item in deadSet:
            globalHotItems[ (item-currentHotItems[item]+1, i-currentHotItems[item]) ] = currentHotItems[item]
    
        currentHotItems = updatedHotItems
    
    print sorted(globalHotItems.items(), key=lambda x:x[1])[-1]
    
    globalHotItems
    是包含结果的字典。键是(value,startIndex),值是长度

    例如,
    globalHotItems
    中的最后4项:

    print sorted(globalHotItems.items(), key=lambda x:x[1])[-4:]
    
    是:

    这意味着最佳解决方案的长度为7,从
    index=1
    列表中的729开始。最好的第二个解决方案是长度6,从
    index=6
    列表706开始,以此类推

    复杂性:


    我认为复杂性应该是:
    O(输入\u大小×平均\u序列数)

    您能否减少示例中的数据量。我们真的不需要太多来理解问题以及您期望的解决方案。你真的需要发布你尝试过的内容。dict中的每个数组似乎都已排序。这是一个给定的,还是仅仅是巧合?@haraldkl:这是一个给定的,相应地编辑了这个问题。@PeterWood:减少了问题中的数据。正如我提到的,我唯一的想法就是暴力方法。实现的链接已发布,唯一的其他内容将是for循环。@haraldkl该序列需要在一个键序列中“按顺序从每个键中仅选取一个数字(键2紧跟在键1之后,依此类推)”,如果不清楚,请提出建议,我将更新该问题。谢谢,这很好,和+1用于通过心灵感应知道可能有空钥匙,这实际上是一个真实的场景。然而,如果能看到相互竞争的解决方案,那就太好了。你能用这个来修改你的答案吗?@SahilM:你可以在每个主循环迭代中(即每个键一次)打印当前的序列。这是一组
    (当前值,长度)
    整数对…+1,用于增加竞争解决方案的功能。但是,你能重新检查一下你的代码吗?当我对整个数据集运行此操作时,值和长度是正确的,但索引不是正确的。@SahilM,问题是由于给定字典中缺少索引。我一开始不知道你缺少索引。。。但是,我现在修复了它并更新了我的答案,它应该可以工作。如果你能提供一个具体的例子,说明这个解决方案失败,我可能会尽力帮助你。
    [((157, 5), 4), ((217, 23), 5), ((706, 6), 6), ((729, 1), 7)]