Computer science 寻找一个非常非常大的矩阵的转置

Computer science 寻找一个非常非常大的矩阵的转置,computer-science,transpose,large-data,Computer Science,Transpose,Large Data,我有一个巨大的二维数据数组。它按行顺序存储: A(1,1)A(1,2)A(1,3)。。。。。A(n-2,n)A(n-1,n)A(n,n) 我想把它重新排列成列顺序 A(1,1)A(2,1)A(3,1)。。。。。A(n,n-2)A(n,n-1)A(n,n) 数据集相当大,超过了计算机RAM的容量。(n约为10000,但每个数据项占用约1K的空间。) 有人知道这样做的巧妙或高效的算法吗?您需要一个矩阵类,这样您的整个应用程序就可以通过该类的实例访问矩阵。然后,转置可以只是设置一个标志,在访问元素时反

我有一个巨大的二维数据数组。它按行顺序存储:

A(1,1)A(1,2)A(1,3)。。。。。A(n-2,n)A(n-1,n)A(n,n)

我想把它重新排列成列顺序

A(1,1)A(2,1)A(3,1)。。。。。A(n,n-2)A(n,n-1)A(n,n)

数据集相当大,超过了计算机RAM的容量。(n约为10000,但每个数据项占用约1K的空间。)


有人知道这样做的巧妙或高效的算法吗?

您需要一个矩阵类,这样您的整个应用程序就可以通过该类的实例访问矩阵。然后,转置可以只是设置一个标志,在访问元素时反转索引。即时转置

最简单的方法是将文件读取10000次,然后找到每行对应的列。这应该很容易实现,但我不知道运行该程序需要多少时间



在您的评论中,您提到输出另一个文件,然后应使用
sort
进行排序。这是一个坏主意,因为对这么大的文件进行排序需要花费很长时间。排序是一个复杂(或至少是资源密集)的问题,因此将转置概括为排序可能是错误的方法。

创建
n
空文件(如果可以,为
n
元素保留足够的空间)。遍历原始矩阵。将元素
(i,j)
附加到文件
j
。完成后,将刚刚编写的文件追加。

什么编程语言/应用程序?如果矩阵太大而无法存储在RAM中,那么矩阵存储在哪里?在执行过程中,数据存储在RAM中。n=10000表示10000x1000x1KB=100 GB。您是想就地转置,还是想在新文件中写入数据的转置版本?数据将存储在硬盘上的文件中。我想要一个程序来读取这个文件,并将数据的转置写入另一个文件。此外,我可能夸大了文件的大小规格。它可能比100GB更接近10GB。但是,我想在C++中编写这个程序。但是为了给出一些想法,我想做的一件事是写一个大数据文件,其中每行都是“i ja(j,i)”,然后在上面运行UNIX排序命令(i和j将包括前导零,以便它们具有与文本相同的长度)。我必须承认,我还没有试过。如果你可以的话,为什么
n*log(n)
?关于排序的想法-我已经用它做过实验,unix排序程序相当复杂。例如,如果文件大得令人难以置信,它会将其拆分为许多较小的文件,对每个文件进行排序,然后合并它们。我用比计算机上的RAM大得多的文件对它进行了测试,它的性能相当好。这就是所谓的分而治之的方法,基本上就是mergesort和quicksort所做的(虽然大多数时候你在内存中划分问题,而不是在磁盘上,但基本原理是一样的),我收回我所说的线性时间。遍历文件的时间是二次的(较长的文件乘以更多的迭代次数),因此我想排序方法似乎是一个可行的解决方案。关于快速排序算法——是的,我最初考虑编写一个分治算法来进行转置。但我开始意识到记账很难。然后我想——你知道,那些unix的家伙已经做了这项艰巨的工作——让我们不要重新发明轮子。我认为“n个空”文件不是一个好主意。您必须创建大约10000个文件。一些文件系统甚至不允许在一个目录中有那么多的文件,而另一些文件系统则使用简单的数据库技术列出目录中的文件。所以首先你需要使用一些非常智能的文件系统,它使用B树或者类似的东西来列出它的目录。(可能有些linux文件系统会这样做。)接下来,当您写入文件时,您将以循环方式写入硬盘上大约10000个不同的位置。这很可能会完全破坏操作系统或磁盘硬件使用的任何磁盘缓存方案。即使你有一个预保留了n个空插槽的文件,这个问题仍然会存在。另一方面,我的一个朋友给我发了一封电子邮件,他在邮件中实际尝试了这种方法,而且速度确实比我想象的要快。所以我收回我所说的——你的解决方案绝对值得一试。我自己还没有试过,因为你必须调整计算机上的设置,这样你就可以同时打开10000个文件。我只能通过重新启动计算机才能做到这一点。因此,我很抱歉批评这是一个很好的解决方案。