我正在使用一个需要在稀疏矩阵中访问和存储数据的程序。大约40-60%的矩阵将为非零,尺寸为14K至22K元素平方。
这是我的问题 - 我将进行很多的行和列操作。主要是添加,删除和交换。我已经查看了大多数现有的众所周知的稀疏矩阵格式(CRS,CCS,COO,块格式等),而且他们中的大多数似乎都不太愿意接受这些类型的操作。在您开始添加和删除整个行或列的那一刻,您需要将所有元素更新到被操纵的行/列的任一侧,并且这是我想尝试避免的情况,如果可能的话(我已经想到你可以管理元素,使得它们在矩阵中的坐标实际上存储为一对指向公共行或列索引的指针,并且通过简单地递增来避免手动更新数千个元素或递减该价值)。
那里有类似的东西吗?
答案 0 :(得分:0)
我会考虑一个间接层,它可以作为交换,插入和删除行和列的有效机制。
这类似于现代操作系统中虚拟内存的管理方式。这只是一个简短的说明:物理RAM地址由CPU的memory management unit映射到线性寻址空间。 MMU在主机O / S的帮助下,将实际的物理RAM地址映射到每个进程的虚拟地址空间。每个进程中指针和其他对象使用的地址不是真正的RAM地址,它们是虚拟的,并且由硬件MMU单元转换为实际的物理RAM地址。这就是为什么空闲进程可以被主机操作系统分页到交换文件或分区,当系统空间不足,然后再加载回到一些完全不同的物理RAM区域,甚至没有进程意识到发生了什么。
无论如何,回到主题,这将是一个类似的方法。
考虑一个简单的花园式二维std::map
。这是你的稀疏矩阵:
std::map<size_t, std::map<size_t, value_t>>
第一张地图的尺寸或键是行,它会为您提供第二张地图,其尺寸/键为列,最后包含您的值。
这非常简单。这里没什么惊天动地的。但正如您所理解的那样:移动,交换和插入行和列变得非常熊。
好的,让我们介绍一下你自己的个性化MMU:你的地图管理单元。它几乎可以像硬件MMU一样工作:
std::map<size_t, size_t> rows;
std::map<size_t, size_t> columns;
因此,在您的示例中,要查找虚拟行R
的值,列C
:
1)rows[R]
为您提供&#34;物理&#34;行号。
2)columns[C]
为您提供&#34;物理&#34;列号。
3)现在,你采取&#34;物理&#34;行和列号,然后转到二维std::map
,并根据物理行和列查找您的值。
那么,我们得到了什么?那么,移动整行或列现在需要对地图管理单元进行简单的更新。从rows
或columns
地图中删除一个值,然后使用另一个键,新的&#34;逻辑&#34;行或列。 &#34;物理&#34;,二维地图中的值保持不变。
那就是它。移动,交换或插入行将成为mmu对象的简单操作。
还有两个细节需要注意:
A)跟踪哪些物理行和列未被使用,并且可以在添加时分配给新的逻辑行和列。
B)根据您的使用情况,可能还需要将物理行和列映射回虚拟行和列号。
这些都是相当简单,直接的任务,可以作为你的家庭作业。