Algorithm 用于大量按块可变长度数据的外部排序

Algorithm 用于大量按块可变长度数据的外部排序,algorithm,sorting,block,mergesort,ram,Algorithm,Sorting,Block,Mergesort,Ram,我需要对块变长数据应用一些排序算法。以下是限制条件: 数据长度不是固定的 块大小是固定的 一个块包含单个/多个数据 考虑到我需要外部排序。RAM无法保存整个数据集。数据集大小为20 GB。在这里我可以使用高达2GB的RAM 例如: 为了简单起见,在块中考虑每个元素是空间分隔的单词。 考虑块大小为26(包括空间),第一个块包含5个元素,而第二个块仅包含3个元素 由于块的大小是固定的,排序后的数据可能包含比分类后的块更多的块 块: [哈利·罗恩·德拉科黑魔王][赫敏·隆巴顿·伏地魔] 已排序的块:

我需要对块变长数据应用一些排序算法。以下是限制条件:

  • 数据长度不是固定的

  • 块大小是固定的

  • 一个块包含单个/多个数据

  • 考虑到我需要外部排序。RAM无法保存整个数据集。数据集大小为20 GB。在这里我可以使用高达2GB的RAM

  • 例如: 为了简单起见,在块中考虑每个元素是空间分隔的单词。 考虑块大小为26(包括空间),第一个块包含5个元素,而第二个块仅包含3个元素

    由于块的大小是固定的,排序后的数据可能包含比分类后的块更多的块

    块:

    [哈利·罗恩·德拉科黑魔王][赫敏·隆巴顿·伏地魔]

    已排序的块:

    [黑暗的德拉科·哈利·赫敏][隆巴顿·罗恩勋爵][伏地魔]


    对于这种情况,哪种算法/技术是有效的?

    我的第一个倾向是:

    编写一个脚本,读取输入文件,删除块并写入顺序文件。即,获取包含以下内容的文件:

    [Harry Ron Draco Dark Lord] [Hermione Longbottom Voldemort]
    
    并写入此文件:

    Harry
    Ron
    Draco
    Dark
    Lord
    Hermione
    Longbottom
    Voldemort
    
    然后,使用系统的排序实用程序(例如GNU
    sort
    )对文件进行排序,给出:

    Dark
    Draco
    Harry
    Hermione
    Lord
    Longbottom
    Ron
    Voldemort
    
    然后,编写一个脚本,读取该文件并构造块,将它们写入最终输出


    就运行时间而言,这几乎肯定不是最有效的,但它简单、可靠、易于编码,并且易于证明正确。您可能可以在一两个小时内编写代码并使用数据子集进行测试。然后将其设置为对整个数据集起作用。

    外部合并排序将起作用。语句“排序的数据可能包含比分类的更多的块”意味着数据记录不跨越块,因此在排序和合并过程中,由于块中未使用的空间,块的数量可能会有所不同。第一步是将一组块读入内存,对数据记录进行排序,然后将排序后的块写入文件,重复此过程,直到处理完所有原始数据。其余的过程合并文件,直到生成一个已排序的文件。这个过程可以使用k路合并,其中最简单的是2路合并。对于k>2,minheap将有助于查找k次运行中哪个具有“最小”的下一个元素。要减少I/O开销,请一次读取和写入多个块

    删除阻塞将删除问题中的一个约束。@rcgldr怎么会这样?在对数据进行排序后,您将重新添加它。看看OP的例子。他得到的结果正是您按照我的过程得到的结果。我对块大小约束的假设是,在排序期间,所有I/O必须是块大小的倍数(一个或多个),而不仅仅是排序前后,即使最终结果相同。我还想知道在Windows中编写脚本是否可以解除数据锁定。@rcgldr如果您对I/O的假设成立,那么显然我的方法不会很好地工作。在Windows中编写脚本?这不应该是个问题,尽管我已经有几年没有在Windows上工作了:事情本来可以改变的。但几年前,我可以用VBScript、JavaScript、Powershell(ugh)或。。。见鬼,不管是哪种语言。@MubashwirAlam我的算法不会占用太多内存。第一步一次读取一个块,对其进行解块,然后写入输出。排序步骤使用系统提供的排序实用程序,它知道如何对大于可用内存的文件进行排序。最后一步逐行读取已排序的文件,直到它可以填充一个块,输出该块,然后重复。此解决方案中的任何内容都不会使用超过2GB的内存。