我有大约400.000“项目”。 每个“项目”由16个双重值组成。
在运行时,我需要相互比较项目。因此我正在重复他们的双重价值观。这非常耗时。
我做了一些测试,我发现只有40,000个可能的返回值,无论我相互比较哪些项目。
我想将这些值存储在查找表中,以便我可以轻松地检索它们,而无需在运行时进行任何实际计算。
我的问题是如何有效地将数据存储在查找表中。
问题在于,如果我创建一个查找表,它会变得非常庞大,例如:
item-id, item-id, compare return value
1 1 499483,49834
1 2 -0.0928
1 3 499483,49834
(...)
总计约1.2亿种组合。 对于现实世界的应用来说,这看起来太大了。
但我不确定如何避免这种情况。
有人可以分享一些很酷的想法吗?
非常感谢!
答案 0 :(得分:0)
假设我理解正确,你有两个400K可能性的输入,所以400K * 400K = 160B条目...假设你按顺序索引它们,并且你以允许每个2个八位字节的方式存储你的40K可能性,你正在看一个大约300GB的表大小...非常确定这超出了当前的日常计算。因此,您可能会研究400K“项目”之间是否存在任何关联,如果是这样,您是否可以为该关联指定某种函数,以便为您提供关于40K中的哪一个的线索(读取:哈希函数)结果可能/可能/应该结果。显然,您的哈希函数和查找需要比首先进行乘法更短。或者也许您可以通过某种智能缩减来缩短比较时间,例如在某些情况下了解结果。或者也许可以使用整数数学或布尔比较来优化您的一些数学运算。只是一些想法...
答案 1 :(得分:0)
为了加快速度,您应该计算所有可能的答案,并将输入存储到每个答案中。
然后,我建议制作某种使用答案作为关键字的查找表(因为答案都是唯一的),然后存储获得该结果的所有可能输入。
帮助可视化:
假设你有桌子'Table'。在Table Table中你有键,并且与这些键相关联的是值。你所做的就是让钥匙具有你的答案所处的任何格式(钥匙将是你的所有答案)。现在,给每个400k输入一个唯一的标识符。然后,将乘法的唯一标识符存储为与该特定键关联的一个值。当您再次计算相同的答案时,只需将其添加为另一组可以计算该键的输入。
示例:
Table<AnswerType, vector<Input>>
定义输入,如:
struct Input {IDType one, IDType two}
其中一个'输入'可能有ID的12384,128,这意味着12384和128标识的对象在乘以时会给出答案。
因此,在您的查找中,您将看到类似的内容:
AnswerType lookup(IDType first, IDType second)
{
foreach(AnswerType k in table)
{
if table[k].Contains(first, second)
return k;
}
}
// Defined elsewhere
bool Contains(IDType first, IDType second)
{
foreach(Input i in [the vector])
{
if( (i.one == first && i.two == second ) ||
(i.two == first && i.one == second )
return true;
}
}
我知道这不是真正的C ++代码,它仅仅意味着伪代码,它是一个粗略的原样,但它可能是一个开始的地方。
虽然foreach可能仅限于线性搜索,但您可以通过对输入的存储方式进行排序来使'Contains'方法运行二进制搜索。
总而言之,您正在查看将在O(n ^ 2)时间内运行的一次运行应用程序,以及将在nlog(n)中运行的查找。尽管如此,我并不完全确定记忆将如何照顾所有这些。当然,我对它背后的数学知之甚少,所以如果你能以某种方式对键进行排序,你也许可以加快线性搜索。