如何针对 C、C++ 或 Fortran 中的另一个多维数组快速对多维数组进行十亿点排序?

Posted

技术标签:

【中文标题】如何针对 C、C++ 或 Fortran 中的另一个多维数组快速对多维数组进行十亿点排序?【英文标题】:How to sort a multidimesional array with respect to another multidimensional array in C, C++ or Fortran for billion points quickly? 【发布时间】:2021-12-31 21:49:41 【问题描述】:

我有一个数据集 A 为:

cx1, cy1,cz1
cx2, cy2,cz2
cx3, cy3,cz3
cx4, cy4,cz4
cx5, cy5,cz5
cx6, cy6,cz6
cx7, cy7,cz7
cx8, cy8,cz8
.................

这里c代表坐标,(x,y,z)代表方向,数字代表点索引。

让我们有另一个数据集为 B 为:

cx7, cy7,cz7,vx7, vy7, vz7
cx3, cy3,cz3,vx3, vy3, vz3
cx8, cy8,cz8,vx8, vy8, vz8
cx2, cy2,cz2,vx2, vy2, vz2
cx5, cy5,cz5,vx5, vy5, vz5
cx4, cy4,cz4,vx4, vy4, vz4
cx1, cy1,cz1,vx1, vy1, vz1
cx6, cy6,cz6,vx6, vy6, vz6
.......................................

这里,v 是一个量,比方说速度,我们看到顺序是随机的。

如何以最快的方式根据 A 数据对 B 数据进行排序,以保持数据集 B 中的坐标和速度的对应关系与数据点的数量以十亿为单位相同?

【问题讨论】:

你能把问题说得更具体一点吗?有哪些类型?是整数吗?多大?或者他们是浮动的?它会在 cpu 或 gpu 上运行吗? 我更好奇他是否想要 C 或 Fortran 中的解决方案。 你的意思是说第二个数组中设置的每一个cx,cy,cz都出现在第一个数组的某处,这就是第二个数组排序的依据吗? 内存有问题吗?仅将数据集放在内存中似乎需要超过 40G,具体取决于数据类型。你的内存预算是多少? 顺便说一句:这些集合基于什么数据类型? (a) A 中的每个元素在 B 中是否只出现一次?如果没有,它会出现不止一次吗?它可以出现少于一次吗? (b) B 中的每个元素(用“cxn, cyn,czn”表示某些)是否在 A 中只出现一次?如果没有,它会出现不止一次吗?它可以出现少于一次吗? (c) “根据 A 数据对 B 数据进行排序”是什么意思?是不是说,如果B中的某个元素用“cxn, cyn, czn”标识,那么就按n的值排序,即“cxn, cyn, czn”在A中的位置? 【参考方案1】:

TLDR:哈希表。

如果这是 C++,这将很容易。但是,您只能靠自己在纯 C 或 Fortran 中实现哈希表。

创建一个哈希表,从“Point”映射到集合 A 中的数组索引。即 cx1, cy1, cz1 将映射到索引 0,而 cx8, cy8, cz8 将映射到索引 7。你'将需要实现一个自定义哈希函数,它可以像cx XOR cy XOR cz 一样简单。

使用任何排序算法(例如 C 中的内置 qsort 或 C++ 中的 std::sort),对 B 中的项目进行排序。在您的比较器函数中,它决定一个特定项目是大于还是小于另一个,在您根据 A 中的项目创建的哈希表中查找 cx,cy,cz 点,以获得两个点的原始索引位置。

【讨论】:

我不明白qsort 的必要性。如果哈希表查找可以给出索引,那么传统排序似乎是额外的工作 @4386427: 给定 B 中的某个元素,我们可能会确定它对应于 A 中位置 n 的元素,但这并不意味着它将进入排序后的 B 中的位置 n,因为 B 可能不包含 A 的所有元素或可能多次包含某些元素。虽然问题中显示的例子有A和B之间的1-1对应关系,但这并没有说明。 @EricPostpischil 确实,没有明确说明 A 和 B 之间存在 1-1 对应关系,但该示例强烈表明这一点。此外,如果 B 中的特定 x,y,z 不存在于 A 中,它应该放在哪里(也就是比较函数应该返回什么)。如果 x,y,z 出现不止一次,也会出现类似的问题。所以在我看来,具有独特元素的 1-1 似乎是必须的。但是再次......确实,OP从未明确说明过这一点。就像问题中许多其他不清楚的事情一样。 如果“集合 B”中的点与“集合 A”中的点不是 1:1,并且目标是按与 A 中点的接近程度对 B 进行排序 - 那么正确的数据结构是kd树。鉴于 OP 缺乏细节和低代表分数,我并不急于草拟解决方案。

以上是关于如何针对 C、C++ 或 Fortran 中的另一个多维数组快速对多维数组进行十亿点排序?的主要内容,如果未能解决你的问题,请参考以下文章

C、C++ 或 Fortran 的代码抛光器/重新格式化器 [关闭]

如何使用算法将一种类型的列表映射到现代 C++ 中的另一种类型的列表

如何检查向量的所有元素是不是在 Eigen c++ 中的另一个向量中?

如何用 c 或 c++ 读取 FORTRAN 二进制文件?

使用 Fortran 中的内存数据调用 C 代码

如何将一个点附加到opencv c中的另一个点