所以我有一个C ++代码,可以找到方形矩阵的逆矩阵。逆是完整的,将它全部保存在内存中是不好的,因为我正在使用数十万列。我的代码逐个生成列。找到反向后,我的其余代码逐个需要行。理想情况下,我想按照以下步骤进行:
重复: 1)找到一列 2)将其存储在磁盘上 3)从内存中删除列。
重复: 1)从磁盘中读取一行 2)处理它(它基本上是线性程序的目标函数) 3)从内存中删除行。
这样做的一种方法是将矩阵写入文件中。意思是,我将第一列写为"实际"在文件中的列,然后我写下它旁边的第二个(效率会低一点),依此类推。如果我没有弄错的话,最后一列将需要写入O(n ^ 2)。这样做可以很容易地读取行。另一种方法是将列写为行,然后稍后读取列。但同样,最后一列将采用O(n ^ 2)来读取。第三种方法是使用n个文件,但打开和关闭n个文件效率很低。
有关如何处理此类问题的任何想法?也许我必须使用数据库(可能是SQL)来为每个条目读取和写入O(1)?
谢谢。
答案 0 :(得分:1)
如果它是方阵,则很容易编写随机访问文件。例如,如果按行存储矩阵,如...
FILE * f = fopen( FileName, "w+b" );
for(int i = 0; i < MaxRows; ++i) {
for(int j = 0; j < MaxColumns; ++i) {
fwrite( &v[ i ][ j ], 1, sizeof( double ), f );
}
}
现在你可以去任何你想去的地方。只要考虑到每次都必须应用公式:
pos = ( MaxColumns * rowNumber ) + colNumber;
为了将自己定位在文件中,您必须使用fseek()
,它以字节为单位,而不是以元素为单位。
假设您要转到第三列的第一个元素。这个职位将是......
int pos = ( MaxColumns * 2 ) + 0;
所以现在你可以找到那个位置:
fseek( f, pos * sizeof( double ), SEEK_SET );
并且,比方说,读取值:
double value;
fread( &value, 1, sizeof( double ), f );
所以我的答案是:一旦你将矩阵保存在磁盘中,你可以无限制地操纵它,而不用担心它占用多少。
不要忘记关闭文件:
fclose( f );
希望这有帮助。
答案 1 :(得分:0)
提及fseek
的解决方案很好。然而,对于大型矩阵来说它可能非常慢(因为磁盘不像随机访问,特别是很远)。为了加快速度,你应该使用阻止。
我会展示一个基本概念,如果需要,可以进一步解释。
首先,将矩阵拆分为相同大小的块,如下所示:
块大小的计算方式应使 块 的列或行能够适合RAM。
接下来,将块列保留在内存中,并在此处复制首先生成的blocksize
列。黄色部分是你保留在内存中的颜色,橙色是你下一个生成的列:
完成第一个blocksize
列后,将它们转储到单独的文件中(对于我的图像,您可以命名此类文件&#34; A1&#34;,&#34; A7&#34;和& #34; A13&#34;),然后从下一列的块开始。
如果稍后需要此矩阵,请反转此过程。从准备好的文件中读取(例如,&#34; A1&#34;,&#34; E1&#34;,&#34; I1&#34;和&#34; M1&#34;)第一行块,以及逐行处理: