我正在尝试按希尔伯特顺序对 d 维数据向量进行排序,以批量加载空间索引。
但是,我不想明确计算每个点的希尔伯特值,这尤其需要设置特定的精度。在高维数据中,这涉及到诸如32*d
位之类的精度,要有效地执行它会变得相当混乱。当数据分布不均匀时,其中一些计算是不必要的,并且需要对部分数据集进行额外的精度。
相反,我正在尝试使用分区方法。当您查看二维一阶希尔伯特曲线时
1 4
| |
2---3
我首先沿 x 轴拆分数据,这样第一部分(不一定包含一半的对象!)将由 1 和 2(尚未排序)组成,第二部分将包含来自 3 和 4 的对象只要。接下来,我将在 Y 轴上再次拆分每一半,但将顺序颠倒 3-4。
所以本质上,我想执行一个分而治之的策略(与快速排序密切相关 - 在均匀分布的数据上,这甚至应该是最佳的!),并且只根据需要计算希尔伯特索引的必要“位”。所以假设“1”中只有一个对象,那么就不需要计算它的完整表示;如果对象分布均匀,分区大小将迅速下降。
我确实知道转换为长、灰色编码、维度交错的常用教科书方法。这不是我要找的(有很多可用的例子)。我明确地只想要一个懒惰的分治法排序。另外,我需要的不仅仅是 2D。
有谁知道以这种方式工作的文章或希尔伯特排序算法?或者一个关键的想法如何正确地“旋转”,为此选择哪种表示?特别是在更高维度中……在 2D 中它是微不足道的;1 旋转 +y,+x,而 4 是 -y,-x(旋转和翻转)。但我猜,在更高维度上,这会变得更加棘手。
(结果当然应该与立即以足够大的精度按希尔伯特顺序对对象进行排序时相同;我只是想节省在不需要时计算完整表示的时间,并且必须对其进行管理。很多人们保留一个相当昂贵的哈希图“对象到希尔伯特数”。)
Peano 曲线和 Z 曲线应该有类似的方法,并且可能更容易实现......我可能应该先尝试这些(Z 曲线已经在工作 - 它确实归结为类似于 QuickSort 的东西,使用适当的平均值/网格值作为虚拟枢轴并在每次迭代的维度中循环)。
编辑:见下文,了解我如何解决 Z 曲线和皮亚诺曲线。它也适用于 2D Hilbert 曲线。但是我还没有希尔伯特曲线的旋转和反转。