我有一个数据结构,其中包含24位宽的值。我有很多这些对象。
为了最大限度地降低存储成本,我计算了2 ^ 24个可能值中的2 ^ 7个最重要的值,并将它们存储在静态数组中。因此,我只需要在我的数据结构中为该数组保存一个7位索引。
问题是:我得到这些24位值,我必须动态地将它们转换为我的7位索引(不能进行预处理)。计算基本上是搜索,其中2 ^ 7个值中的一个最适合。显然,这需要一些时间来处理大量对象。
一个明显的解决方案是创建一个长度为2 ^ 24的简单字节映射数组。但这需要16 MB的RAM。太多了。
16 MB阵列的一个观察结果:平均31个连续值是相同的。不幸的是,还有许多不同的连续值。
如何实现从24位值到7位索引的转换,尽可能节省CPU和内存?
答案 0 :(得分:1)
很难说不知道“最适合”的定义是什么。也许kd-tree允许基于某个度量或其他度量的接近度进行合适的搜索,以便您快速排除大多数候选者,并且只需要实际测试2 ^ 7中的一些以查看哪个是最佳的?< / p>
这听起来类似于图像处理器在缩小到较小调色板时所具有的问题。我实际上并不知道使用了哪些算法/结构,但我确信它们是可查找的,并且可能有所帮助。
答案 1 :(得分:1)
作为一个想法...... 将索引表上升到8位,然后将24位字的所有3个字节xor放入其中。 那么你的表将包含这个8位哈希值,加上索引回到原来的24位值。
由于您的数据类似于RGB,因此可能需要更复杂的散列方法。
bit24var & 0x000f gives you the right hand most char.
(bit24var >> 8) & 0x000f gives you the one beside it.
(bit24var >> 16) & 0x000f gives you the one beside that.
是的,你正在思考。由于pigeon hole principal,24位值中的一个或多个很可能会散列到同一个索引。
解决哈希冲突的一种方法是使用某种链接。
答案 2 :(得分:0)
你有多少2 ^ 24个有多少?您可以对这些值进行排序并通过计算连续值的数量来计算它们。
答案 3 :(得分:0)
由于您已经知道需要保留2 ^ 24个值中的哪一个(即您确定重要的2 ^ 7个值),我们只需过滤输入数据并分配一个值,从0开始向上到2 ^ 7-1,我们遇到它们时的这些值。当然,我们需要一些方法来跟踪我们已经看到的哪些重要值,并在[0,2 ^ 7]中分配了一个标签。为此,我们可以使用某种基于树或哈希表的字典实现(例如,在C ++中为std::map
,在Java中为HashMap
或TreeMap
,在Python中为dict
。
代码可能看起来像这样(我使用的范围要小得多):
import random
def make_mapping(data, important):
mapping=dict() # dictionary to hold the final mapping
next_index=0 # the next free label that can be assigned to an incoming value
for elem in data:
if elem in important: #check that the element is important
if elem not in mapping: # check that this element hasn't been assigned a label yet
mapping[elem]=next_index
next_index+=1 # this label is assigned, the next new important value will get the next label
return mapping
if __name__=='__main__':
important_values=[1,5,200000,6,24,33]
data=range(0,300000)
random.shuffle(data)
answer=make_mapping(data,important_values)
print answer
通过对重要值集使用基于散列/树的集数据结构,可以更快地进行搜索。这将使整个过程O(n*log(k))
(或O(n)
,如果它是一个哈希表),其中n是输入的大小,k是重要值的集合。
答案 4 :(得分:0)
另一个想法是将您的重要值放在不同的数组中,然后先搜索它。如果你在那里找不到可接受的答案,那么你可以颤抖,搜索更大的数组。
答案 5 :(得分:0)
另一个想法是在位图中表示24BitValue数组。一个好的无符号字符可以容纳8位,因此需要2 ^ 16个数组元素。那是65536.如果设置了相应的位,那么您就知道数组中存在特定的24BitValue,需要进行检查。
需要一个迭代器,遍历数组并找到下一个设置位。有些机器实际上在其指令集中提供“查找第一位”操作。
祝你好运。 让我们知道事情的结果。
恶