解决多维空间点索引需要解决2个问题,第一,如何把多维降为低维或者一维?第二,一维的曲线如何分形?

填充曲线(Space-filling curve)

在数学分析中,有这样一个难题:能否用一条无限长的线,穿过任意维度空间里面的所有点? 常见的有: Z阶曲线(Z-order curve)、皮亚诺曲线(Peano curve)、希尔伯特曲线(Hilbert curve),之后还有很多变种的空间填充曲线,龙曲线(Dragon curve)、 高斯帕曲线(Gosper curve)、Koch曲线(Koch curve)、摩尔定律曲线(Moore curve)、谢尔宾斯基曲线(Sierpiński curve)、奥斯古德曲线(Osgood curve)等

在1890年,Giuseppe Peano 发现了一条连续曲线,现在称为皮亚诺曲线(Peano curve),它可以穿过单位正方形上的每个点。他的目的是构建一个可以从单位区间到单位正方形的连续映射。 Peano 受到 Georg Cantor 早期违反直觉的研究结果的启发,即单位区间中无限数量的点与任何有限维度集合中无限数量的点基数相同。 Peano 解决的问题实质就是,是否存在这样一个连续的映射,一条能填充满平面的曲线。如下图就是他找到的一条曲线。一般来说,一维的东西是不可能填满2维的方格的。但是皮亚诺曲线恰恰给出了反例。皮亚诺曲线是一条连续的但处处不可导的曲线。

皮亚诺曲线的构造方法如下:取一个正方形并且把它分出九个相等的小正方形,然后从左下角的正方形开始至右上角的正方形结束,依次把小正方形的中心用线段连接起来;下一步把每个小正方形分成九个相等的正方形,然后上述方式把其中中心连接起来……将这种操作手续无限进行下去,最终得到的极限情况的曲线就被称作皮亚诺曲线。

一年后,即1891年,希尔伯特就作出了这条曲线,叫希尔伯特曲线(Hilbert curve)。如下图就是1-6阶的希尔伯特曲线。

如下图,希尔伯特曲线填充满3维空间示意图。

在数学分析中,空间填充曲线是一个参数化的注入函数,它将单位区间映射到单位正方形,立方体,更广义的,n维超立方体等中的连续曲线,随着参数的增加,它可以任意接近单位立方体中的给定点。除了数学重要性之外,空间填充曲线也可用于降维,数学规划,稀疏多维数据库索引,电子学和生物学。空间填充曲线的现在被用在互联网地图中。

分形

皮亚诺曲线的出现,说明了人们对维数的认识是有缺陷的,有必要重新考察维数的定义。这就是分形几何考虑的问题。在分形几何中,维数可以是分数叫做分维。多维空间降维以后,如何分形,也是一个问题。分形的方式有很多种,这里有一个列表,可以查看如何分形,以及每个分形的分形维数,即豪斯多夫分形维(Hausdorff fractals dimension)和拓扑维数。

Z阶曲线(Z-order curve)

前几单介绍的 Genhash 是一种地理编码,由 Gustavo Niemeyer 发明的。它是一种分级的数据结构,把空间划分为网格。Genhash 属于空间填充曲线中的Z 阶曲线(Z-order curve)的实际应用。

何为 Z 阶曲线? 如下图,这个曲线比较简单,生成它也比较容易,只需要把每个 Z 首尾相连即可。

Z 阶曲线同样可以扩展到三维空间。只要 Z 形状足够小并且足够密,也能填满整个三维空间。

Geohash 能够提供任意精度的分段级别。一般分级从 1-12 级。利用 Geohash 的字符串长短来决定要划分区域的大小,一旦选定 cell 的宽和高,那么 Geohash 字符串的长度就确定下来了。

地图上虽然把区域划分好了,但是还有一个问题没有解决,那就是如何快速的查找一个点附近邻近的点和区域呢?

Geohash 有一个和 Z 阶曲线相关的性质,那就是一个点附近的地方(但不绝对) hash 字符串总是有公共前缀,并且公共前缀的长度越长,这两个点距离越近。由于这个特性,Geohash 就常常被用来作为唯一标识符。用在数据库里面可用 Geohash 来表示一个点。Geohash 这个公共前缀的特性就可以用来快速的进行邻近点的搜索。越接近的点通常和目标点的 Geohash 字符串公共前缀越长(特殊情况除外)

在前一章讲 Geohash 编码的时候,提到Geohash码生成规划: “偶数位放经度,奇数位放纬度”。这个规则就是 Z 阶曲线。看下图:

x 轴就是纬度,y轴就是经度。经度放偶数位,纬度放奇数位就是这样而来的。

Hilbert Curve 希尔伯特曲线

希尔伯特曲线一种能填充满一个平面正方形的分形曲线(空间填充曲线),由大卫·希尔伯特在1891年提出。由于它能填满平面,它的豪斯多夫维是2。取它填充的正方形的边长为1,第n步的希尔伯特曲线的长度是2^n - 2^(-n)。

一阶的希尔伯特曲线,生成方法就是把正方形四等分,从其中一个子正方形的中心开始,依次穿线,穿过其余3个正方形的中心。如下图:

二阶的希尔伯特曲线,生成方法就是把之前每个子正方形继续四等分,每4个小的正方形先生成一阶希尔伯特曲线。然后把4个一阶的希尔伯特曲线首尾相连。

三阶的希尔伯特曲线,生成方法就是与二阶类似,先生成二阶希尔伯特曲线。然后把4个二阶的希尔伯特曲线首尾相连。

n阶的希尔伯特曲线的生成方法也是递归的,先生成n-1阶的希尔伯特曲线,然后把4个n-1阶的希尔伯特曲线首尾相连。

为何要选希尔伯特曲线

这么多空间填充曲线,为何要选希尔伯特曲线?因为希尔伯特曲线有非常好的特性,如下:

(1) 降维: 首先,作为空间填充曲线,希尔伯特曲线可以对多维空间有效的降维。如下图就是希尔伯特曲线在填满一个平面以后,把平面上的点都展开成一维的线了。

上图里面的希尔伯特曲线只穿了16个点,怎么能代表一个平面呢?当然,当n趋近于无穷大的时候,n阶希尔伯特曲线就可以近似填满整个平面了。如下图

(2) 稳定: 当n阶希尔伯特曲线,n趋于无穷大的时候,曲线上的点的位置基本上趋于稳定。举个例子,如下图:

上图左边是希尔伯特曲线,右边是蛇形的曲线。当n趋于无穷大的时候,两者理论上都可以填满平面。但是为何希尔伯特曲线更加优秀呢?

在蛇形曲线上给定一个点,当n趋于无穷大的过程中,这个点在蛇形曲线上的位置是时刻变化的。

这就造成了点的相对位置始终不定。再看看希尔伯特曲线,同样是一个点,在n趋于无穷大的情况下:

从上图可以看到,点的位置几乎没有怎么变化。所以希尔伯特曲线更加优秀。

(3) 连续

希尔伯特曲线是连续的,所以能保证一定可以填满空间。

参考资料

皮亚诺曲线java,多维空间点索引算法概述相关推荐

  1. 2020年第十一届蓝桥杯决赛JAVA B G题“皮亚诺曲线距离“

    2020年第十一届蓝桥杯决赛JAVA B G题"皮亚诺曲线距离" 2020国赛 JAVA B组 个人题解目录 [问题描述] 皮亚诺曲线是一条平面内的曲线. 下图给出了皮亚诺曲线的 ...

  2. 高效的多维空间点索引算法 — Geohash 和 Google S2(转)

    转自:https://mp.weixin.qq.com/s?__biz=MjM5OTM0MzIwMQ==&mid=2652551603&idx=1&sn=f45f06d6a56 ...

  3. 高效的多维空间点索引算法 — Geohash 和 Google S2—绝对好文

    引子 每天我们晚上加班回家,可能都会用到滴滴或者共享单车.打开 app 会看到如下的界面: app 界面上会显示出自己附近一个范围内可用的出租车或者共享单车.假设地图上会显示以自己为圆心,5公里为半径 ...

  4. 试题 历届真题 皮亚诺曲线距离【第十一届】【决赛】【C组】

    试题 历届真题 皮亚诺曲线距离[第十一届][决赛][C组] 提交此题   评测记录 资源限制 内存限制:256.0MB   C/C++时间限制:1.0s   Java时间限制:3.0s   Pytho ...

  5. 蓝桥杯决赛题目分析之皮亚诺曲线

    原题链接 感谢作者 https://blog.csdn.net/qq_43449564/article/details/124584232 皮亚诺曲线介绍 皮亚诺曲线是一条平面内的曲线. 下图给出了皮 ...

  6. matlab画皮亚诺曲线,2020年第十一届蓝桥杯大赛软件类决赛(国赛) C/C++ 大学A组【题面】...

    记录一下国赛的题面,真的和省赛完全不是一个难度的.这次估计国三都混不到,还是太菜了QAQ,之后如果能补题解就补吧. 题面的pdf文件我也上传到CSDN下载区了,内容和本篇文章相同. (题面真长,我复制 ...

  7. 皮亚诺曲线 matlab动画,大家听过皮亚诺曲线吗?是怎么画的?

    原标题:大家听过皮亚诺曲线吗?是怎么画的? 1890年,意大利数学家皮亚诺(Peano G)发明能填满一个正方形的曲线,叫做皮亚诺曲线.后来,由希尔伯特作出了这条曲线,又名希尔伯特曲线. Hilber ...

  8. 蓝桥杯第十一届决赛真题之皮亚诺曲线距离

    蓝桥杯第十一届决赛真题之皮亚诺曲线距离python 借鉴了https://www.cnblogs.com/EchoZQN/p/14829144.html的做法 然而同样的想法,python代码提交之后 ...

  9. 蓝桥-皮亚诺曲线距离

    求解皮亚诺曲线距离 [问题描述]  皮亚诺曲线是一条平面内的曲线.  下图给出了皮亚诺曲线的 1 阶情形,它是从左下角出发,经过一个 3 × 3 的方格中的每一个格子,最终到达右上角的一条曲线.  下 ...

最新文章

  1. 使用BCH提供的Cryptonize创建自己的加密代币
  2. ping 代理_Happy专访:Ping太高不是问题 换我不会像120一样比赛
  3. DevExpress的TreeList实现显示本地文件目录并自定义右键实现删除与重命名文件
  4. 为什么要在沙河中设置小堤坝?
  5. spring-kafka整合:KafkaTemplate-kafka模板类介绍
  6. Intellij IDEA的java环境与安卓sdk配置实例教程
  7. python中小数_比较python中的小数
  8. 被“薅羊毛”损失200多万!元气森林:系运营事故
  9. 【BZOJ1563】【NOI2009】—诗人小G(决策二分栈优化dp)
  10. 产品经理应聘之感受漫谈
  11. AOP 基本术语及其在 Spring 中的实现
  12. 基于斥力-张力模型的网络拓扑布局算法(php代码)
  13. 页面指令JSP常见的指令有哪些?(面试必备)
  14. jQuery做的自定义选项卡
  15. android关联发送程序,Android Handler机制之Message的发送与取出
  16. 数字光栅投影技术——相移轮廓术(PSP)
  17. 深度解析名企项目研发管理成功之路
  18. 解决:谷歌浏览器下载链接时一闪一闪的问题
  19. USACO2013 island travels
  20. android Wifi连接及检测信号强度

热门文章

  1. CSS : Cascading Style Sheets
  2. redhat linux启动mysql_redhatlinux下mysql启动不了
  3. python常用排序_python中的各种排序
  4. java rowmapper 通用实现_必经之路!各大网站力推Java代码优化:77案例+28技巧
  5. diff算法_Virtual Dom和Diff算法
  6. python list 元素位置_Python将list中某个元素移至末尾
  7. prim算法_历时两月,终拿字节跳动offer,算法面试题分享「带答案」
  8. 除夕年味年夜饭海报PSD素材,盛了一年的思念
  9. UI设计干货素材|轻松搞定页面分页符(指示器)的设计
  10. git查看两次提交之间的差异_如何在同一分支的两个不同提交之间区分同一文件?...