IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Voronoi图(一):塞尔达背后的计算几何 -> 正文阅读

[数据结构与算法]Voronoi图(一):塞尔达背后的计算几何

1. 林克的难题

玩过塞尔达传说:荒野之息的朋友,应该都会赞叹海拉鲁风景的美丽。我们的林克时不时一人独自在战后废墟中探索一座座神庙,有时武器库告急,也会偶尔探望一下亲爱的人马们。现在林克一个人游荡在海拉鲁大地上,遇到了一个难题:他突然想回到河畔驿站修整一下,恢复心心,但是他究竟需要传送哪个传送塔,才能离驿站最近呢?下图给出了河畔驿站的位置,以及三个比较近的传送塔:平原之塔,双子山之塔和初始之塔:

在这里插入图片描述

为了简化问题,这里我们限制传送点只能是传送塔,神庙等的传送点无效;“离驿站最近”是指传送塔距离驿站的直线距离,当然实际赶路可能不能走直线,不过可以用风弹逃课啦哒~

那么,林克究竟应该选择传送到哪个传送塔呢?我们能用什么方法帮助林克解决这个难题呢?其实这个问题可以转换成计算几何中的Voronoi Diagrams(Voronoi图)问题,只要使用传送塔作为输入点,并计算相应的Voronoi图,我们就能得到想要的答案!

2. 巧用Voronoi图

针对这个问题,可能有童鞋会说直接比较驿站到传送点的直线距离,距离最短就是我们想要的结果。通过上面的图例,我们一眼就能知道双子山之塔最近。但是这个方法的效率如何呢?假设我们有n个传送点,那计算所有距离我们需要O(n)的时间,接近线性时间,似乎好像还挺不错的嘛。注意这里是查询一次的效率,假设我们查询了k次,那么总的时间为:O( n ) * k;如果k = n,那么总的时间为:O( n ^ 2 ),查询效率将会大大地降低。

那有没有更加高效的查询方法呢?或者说,我们是否能先建立一个高效的查询数据结构,让我们每次查询效率更高,即使查询次数够多,也能保证查询的整体效率。其实这就是Offline Algorithm 和 Online Algorithm 的区别,这点我们在 线段树(二):RMQ 也提到过呢。

这里我们会把传送塔看成输入点,对点集计算对应的Voronoi图,然后结合点定位算法,就能高效进行空间点的查询。接下来,我们就来看看如何巧用Voronoi图的性质来解决林克的难题吧。

首先,我们用传送塔作为输入点,计算相应的Voronoi图:
在这里插入图片描述
大家可以看到,被蓝线围成的一块块区域,就是Voronoi Cell,每个Cell都会包含一个输入点(传送点),我们也称输入点为SIte。在得到Voronoi图之后,我们也得到了一个非常有用的性质:

每个Cell里面的任一点,到这个Cell包含的SIte的直线距离是最短的。

运用这个性质,我们来看看之前三个候选的传送塔所在的Cell,以及湖畔驿站所在的Cell:
在这里插入图片描述
我们可以看到,只有双子山之塔和河畔驿站处在同一个Cell里面,平原之塔和初始之塔分别在两个不同的Cell里面,所以我们应该让林克传送到双子山之塔,距离河畔驿站最近:
在这里插入图片描述

有了Voronoi图,我们无论进行多少次查询,每次查询的时间都是:O( logn )。建立Voronoi图和与之对应的梯形图(Trapezoidal Map)需要O( nlogn ),假如一共查询了k(k = n)次,整体的时间复杂度为:

2 * O( n logn ) + k * O( logn ) = 2 * O( n logn ) + n * O( logn ) = O( n logn );

现在时间复杂度比之前的O( n ^ 2 )好了不少,从这里大家也能感受到Voronoi图对空间查询效率的提升。好啦,我们帮助林克解决了难度,他也能继续在海拉鲁的冒险,最后拯救塞尔达公主!那接下来我们就来看看Voronoi图一些重要的性质,以及讲解搭建Voronoi图的算法。

3. 个人项目招募

号外哒,号外哒~ 现在想做一个以Voronoi图算法的塞尔达野炊网页项目哒。想法就是用上面提到的算法去做一个演示网站:比如用户随意输入一个目标点,网页能呈现Voronoi图和相应最近的传送点(包括神庙,神兽等等)。具体的效果交互还没有想好哒,正在构思中,也在倒腾个人网站的搭建~ 如果你对该项目有兴趣,长期招募下面的小伙伴哒:

  1. 开发人员(主要是Web前后端,项目主要算法我已经实现了,直接当API调用就行。但使用的技术越新越好,比如不兼容任何旧版浏览器);
  2. UI设计(比如网页外观如何设计才能即美观又简约哦);
  3. 产品人员(比如如何交互和什么功能才能让用户感受Voronoi图的作用);
  4. 塞尔达资深玩家(对塞尔达野炊,包括今年待发售续作无所不知,可以对项目提出相关建议,比如添加其他功能,比如人马,素材或任务位置查询等等);

有兴趣的童鞋可以联系我的邮箱:402951678@qq.com 或 fengkeyleaf@gmail.com;水平不限哒,敢于挑战就行啦哒,网页开发笔者现在也在自学哒,也是一窍不通哦~


上一节:点定位(五):处理退化情况·续

下一节:Voronoi图(二):基本概念和性质

系列汇总:塞尔达和计算几何 | Voronoi图详解文章汇总(含代码)

4. 参考资料

  1. 塞尔达原地图素材来自NS之家

5. 免责声明

※ 本文之中如有错误和不准确的地方,欢迎大家指正哒~
※ 此项目仅用于学习交流,请不要用于任何形式的商用用途,谢谢呢;


在这里插入图片描述

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-24 00:48:42  更:2022-03-24 00:52:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 11:35:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码