我尝试用20000点计算一个问题,所以有一个20000 * 20000个元素的距离矩阵,如何在C ++中存储这个矩阵?我在具有4 GB RAM的计算机上使用Visual Studio 2008。任何建议将不胜感激。
答案 0 :(得分:11)
稀疏矩阵可能就是你要找的东西。许多问题在矩阵的每个单元格中都没有值。 SparseLib++是一个允许有效矩阵运算的库。
答案 1 :(得分:8)
避免使用您正在考虑的brute force方法,并尝试设想一个涉及填充单个20000元素列表的解决方案,而不是涵盖所有可能排列的数组。
对于初学者,考虑到问题的具体情况,请考虑以下简单的方法,您可以改进这些方法:
int bestResult = -1; // some invalid value
int bestInner;
int bestOuter;
for ( int outer = 0; outer < MAX; outer++ )
{
for ( int inner = 0; inner < MAX; inner++ )
{
int candidateResult = SomeFunction( list[ inner ], list[ outer ] );
if ( candidateResult > bestResult )
{
bestResult = candidateResult;
bestInner = inner;
bestOuter = outer;
}
}
}
答案 2 :(得分:6)
你可以将矩阵表示为单个大型数组。这样做是否是一个好主意是由你决定的。
如果每个单元需要四个字节,则矩阵仅为4 * 20000 * 20000,即1.6GB。任何平台都应该为单个进程提供大量内存。 Windows默认为32位进程提供2GiB - 如果需要更多,您可以使用链接器选项。我试过的所有32位unices都给你超过2.5GiB。
答案 3 :(得分:5)
你是否有理由在内存中使用矩阵?
根据您需要执行的计算的复杂程度,您可以简单地使用计算距离的函数。如果您只使用其中一些距离值,这甚至可能比预先计算单个距离值更快。
答案 4 :(得分:3)
如果没有更多关于手头问题的参考(以及矩阵的使用),你会得到很多答案......所以放纵我。
这里的经典方法是使用稀疏矩阵,但默认值可能类似于“未计算”,这需要特殊处理。
也许您可以使用缓存方法。
显然我会说你想避免重新计算距离,所以你想把它们放在这个庞大的矩阵中。但请注意,您始终可以重新计算它们。一般来说,我会说,尝试存储可以重新计算速度的值,实际上就是缓存。
所以我建议使用一个为你抽象缓存的距离类。
基本思路很简单:
当然,这种做法有点复杂,特别是对于效率而言,由于尺寸有限,需要使用算法来选择这些元素等...
因此,在我们深入研究技术实施之前,请告诉我这是否是您正在寻找的。 p>
答案 5 :(得分:1)
您的计算机应该能够处理1.6 GB的数据(假设为32位)
size_t n = 20000;
typedef long dist_type; // 32 bit
std::vector <dist_type> matrix(n*n);
然后使用:
dist_type value = matrix[n * y + x];
答案 6 :(得分:1)
您可以(通过使用小型数据类型),但您可能不想这样做。
最好使用四叉树(如果需要找到最近的N个匹配项)或列表网格(如果要查找R中的所有点)。
在物理学中,你可以用一个场或一个有代表性的点合并来近似遥远的点。
总有一个解决方案。你的问题是什么?
答案 7 :(得分:1)
你应该避免n²问题......
将您的20 000点放入体素网格中。
找到最接近的一对点应该是n log n。
答案 8 :(得分:1)
正如其他答案所述,你应该努力使用稀疏矩阵或者提出一种不需要在矩阵中同时拥有所有数据的不同算法。
如果您确实需要它,可能像stxxl这样的库可能会有用,因为它特别针对大型数据集设计 。它几乎透明地处理你的交换。
答案 9 :(得分:0)
非常感谢您的回答。我正在做的是解决约20000个节点的车辆路径问题。我需要一个距离矩阵,一个矩阵用于邻居列表(对于每个节点,根据距离列出所有其他节点)。该列表将经常用于查找谁可以成为一些候选人。我猜有时距离矩阵可以省略,如果我们可以计算我们需要的时间。但是每次创建邻居列表都不方便。列表数据类型可以是int。
到mgb:
64位Windows系统可以帮助这种情况多少?