Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.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
Sorting 排序/优化值数组以在子数组中启用16位索引_Sorting_Optimization_Heuristics - Fatal编程技术网

Sorting 排序/优化值数组以在子数组中启用16位索引

Sorting 排序/优化值数组以在子数组中启用16位索引,sorting,optimization,heuristics,Sorting,Optimization,Heuristics,我有许多小阵列,它们组合起来可以容纳数百万个项目(其中许多是重复的)。为了节省空间,我将所有项目移动到一个主阵列中,没有重复项。原始数组现在保存主数组中值的索引 问题是我想使用16位索引而不是32位索引来节省额外的空间。每个阵列可以容纳几百到几千件物品(所有物品都低于65535件)。每个具有16位索引的数组都定义了偏移量值,因此32位索引的计算方式为offset+16bitIndex 是否有任何算法可以使用偏移量和16位索引的数组对主数组进行排序?并非所有阵列都需要16位,尽可能多。主阵列中也可

我有许多小阵列,它们组合起来可以容纳数百万个项目(其中许多是重复的)。为了节省空间,我将所有项目移动到一个主阵列中,没有重复项。原始数组现在保存主数组中值的索引

问题是我想使用16位索引而不是32位索引来节省额外的空间。每个阵列可以容纳几百到几千件物品(所有物品都低于65535件)。每个具有16位索引的数组都定义了偏移量值,因此32位索引的计算方式为
offset+16bitIndex

是否有任何算法可以使用偏移量和16位索引的数组对主数组进行排序?并非所有阵列都需要16位,尽可能多。主阵列中也可能存在重复项。(添加少量副本,将附加数组转换为16位仍然会减少所用空间。)


附言:我想不出一个好的,描述性的标题。欢迎提出建议

让我们看看我是否正确理解了这一点:

您的原始数据是一大堆数组(我使用字符串来说明这个概念,但是数组可以包含任何类型的项):

每个阵列的项目数不到65536项,它们总共包含数百万项,其中有许多重复项

因此,您可以创建包含唯一项的主阵列:

master = [Joe, Bob, Sam, Cindy, Susie, Pamela]
您对数组进行了重新编码,以包含引用主数组中的项的索引:

newArray1 = [0, 1, 2, 3]
newArray2 = [4, 5, 3, 0]
newArray3 = [3, 1, 4, 2]
由于
master
数组包含数百万项,因此新数组中的索引必须为32位

如果删除重复字符串所节省的内存大于新数组中32位索引所使用的内存,则这是一个胜利。要获取以前存储在
array1[1]
中的项目,请编写:

item = master[newArray1[1]]
您已经注意到,通过使值偏离基值16位,可以在某些数组中节省空间。如果
newArray1
中的索引都在65536或更小的值范围内,则可以将索引编码为16位,并提供一个基数。因此,如果
newArray1
包含5000个索引,所有索引都在[874947568]的范围内,那么
base
将是8749,索引8749将变为0,47568将是38819。引用主数组的表达式是
item=master[base+newArray1[1]]

低垂的果实 我要做的第一件事是检查集群的主列表。例如,可能有一组100个数组,它们一起使用主列表中的25000项。这些项不被任何其他数组使用,这些数组只使用这25000项。很可能有许多这样的集群。然后,我们将各个集群项放在主数组中。所有使用这些集群的索引列表都可以使用base+offset方法进行编码

找到集群不仅仅是困难的,而且是复杂的。总体思路:

构建反向索引:主项到索引数组的映射。假设您有三个索引数组:

array1: [joe, bob, cindy, susie]
array2: [cindy, pamela, sam]
array3: [bill, peter, mike, cordelia]
那么,您的反向索引是:

joe: [array1]
bob: [array1]
cindy: [array1, array2]
susie: [array1]
pamela: [array2]
sam: [array2]
bill: [array3]
peter: [array3]
mike: [array3]
cordelia: [array3]
要查找群集,请使用。从
array1
开始,将其包含的所有主项添加到队列中。然后,对于队列中的每个项目,查找该项目并将与该项目关联的数组中的所有项目添加到集群中。并将它们添加到队列中(如果它们还不在队列中)。代码:

queue = [joe, bob, cindy, susie]  // items from array1
cluster = [joe, bob, cindy, susie]
cluster_lists = []

while queue has items
    item = queue.dequeue
    list_of_arrays = inverted_index[item]
    for each index_array in list_of_arrays
        if cluster_list does not contain array
            add array to cluster list
            for each array_item in index_array
                if cluster does not contain array_item
                    add array_item to cluster
                    add array_item to queue
                end
            end
        end
    end
end
当该循环结束时,您将识别出一个集群。该集群是包含“joe”的所有列表,以及包含“joe”的列表中的任何其他项,并且递归地一直向下

现在,如果
cluster
包含的项目少于65536个,您可以将所有这些项目按顺序放入主列表中,在
cluster\u列表中对所有数组进行编码,以使用基本+偏移索引方案

继续从其余项目创建集群,直到每个项目都位于集群中

我认为最坏情况下的运行时间类似于O(n*m*a),其中n是主列表中的项目数,m是索引列表的数量,a是索引列表的平均长度。这需要花费一些时间处理数百万个项目、数千个索引列表以及每个列表平均几千个项目。一旦你让它工作起来,你会想在一些逐渐增大的子集上尝试它

其他想法 如果集群大于65536个项目,则可以使用当前技术在该集群中查找数组。另外,正如您所提到的,可能有一种方法可以将重复项添加到更大的集群中,这可能会将其分为两个或更多更小的集群。我得考虑一下


还可以在大型集群中重新排列项目,以便将更多数组编码为base+offset。我对此有一点想法,但还不能确定。

item=master[newArray1[1]]
之前,你的解释是完美的。每个新数组还具有与其关联的32位偏移量。要获取项目,我写
item=master[offset1+newArray1[1]]
。偏移量是这样计算的。在构建具有32位索引的newArray1之后,我在newArray1中搜索最小和最大索引值。如果最小和最大索引值之间的差异小于65535,则可以将新阵列1转换为具有16位索引的阵列。为此,将第一偏移量1设置为最小值。然后用offset1减去所有索引
newArray1Small[0..n]=newArray1[0..n]-offset1
Small%的数组已经可以转换为16位(只是碰巧,在向主数组添加项目时没有任何特殊顺序)。我正在搜索是否有办法在主阵列中重新排序项目和/或添加几个战略性放置的副本,以将更高比例的阵列转换为16位?我知道了。例如,我们知道第一个数组可以有16位偏移量,因为它的所有项都是由definiti定义的
queue = [joe, bob, cindy, susie]  // items from array1
cluster = [joe, bob, cindy, susie]
cluster_lists = []

while queue has items
    item = queue.dequeue
    list_of_arrays = inverted_index[item]
    for each index_array in list_of_arrays
        if cluster_list does not contain array
            add array to cluster list
            for each array_item in index_array
                if cluster does not contain array_item
                    add array_item to cluster
                    add array_item to queue
                end
            end
        end
    end
end