1.高逸涵《与圆有关的离散化方法》【信息技术】.docVIP

1.高逸涵《与圆有关的离散化方法》【信息技术】.doc

  1. 1、本文档共12页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
与圆有关的离散化方法 清华附中 高逸涵 (gaoyihan@) 【摘要】在计算几何问题中,离散化方法是一种较为通用的算法,在解决一些与矩形等直线型有关的题目时,能大大降低算法的时空复杂度。但当问题与圆相关时,直接离散化法有较大困难。本文讨论了离散化法在这类问题中的方法,然后通过几道例题说明如何利用离散化法解决与圆有关的计算几何问题。 【关键字】 计算几何 圆 离散化 【正文】 引言 对于绝大多数算法来说,连续的数据并不是一个合适的,必须将其离散化高效的离散化算法离散化 图1 我们利用离散化将连续平面纵轴划分为5个区间:(1—2)、(2—3)、(3—4)、(4—5)、(5—6)。可以看到,在同一区间内的属性一致,即横轴上被矩形所覆盖的区域是相同的,于是每一区域的面积可以通过乘法很快求出,然后再把所有区间的面积求和即可。由此可以看出离散化可以降低复杂性的优势。 方法 当计算的对象不是矩形而是圆时,例如求3个圆的合并面积,由于圆的边界是一条曲线,不存在固定的矩形区域,似乎不可能利用上述离散化方法来分成类似的各个区域。但是如下图,当我们把纵轴分成如下四个区间时,整个图形被我们分成了6部分,并且每一部分都由简单的弓形和梯形组成,构成复合属性的离散区域,同样可以使问题简化。这提示我们,可以把图形切成若干相对简单的块,使得每一部分的面积都很容易求出。这便是离散化在与圆有关的计算几何中最基础的应用。 图2 算法的一般步骤: 根据问题将平面中的圆分割成若干区域,使每个区域具有一定简单的粗粒属性。一般可以用直线分割。 根据属性确定区域内圆的具体算法,计算每个区域中结果。 综合每个区域的结果,给出问题的最终答案。 应用实例及结果 这里我们通过两个例题具体分析来讨论算法的具体应用形式。 例一、dolphin pool 题目大意: 平面中有n个圆,任意两圆不相切,没有一个圆的圆心在另一个圆内。求有多少闭合的区域没有被任何圆覆盖。 输入: 第一行包含一个数n(0n≤20),表示圆的个数。 接下来n行分别输入三个整数圆心坐标x、y和半径r。 (1≤x、y≤1000,1≤r≤100) 输出: 输出一个整数,表示闭合区域的个数。 初步分析: 虽然题目中已经对圆的位置有了一定的约束,但实际上可能的情况还是很多的,我们希望能找到一种简单而通用的算法。 由于数据都是整数,我们的初步想法是这道题的精度要求不高,因此可以采用一种基于floodfill的算法: 在平面内每隔一定距离取一个点形成点阵,删除所有在圆内的点,然后在剩下的点中floodfill求连通块,最后减1就是答案。算法复杂度为O(k2n),k为1000长度中取点的个数。 图3 我们知道,这个算法的正确性或精度取决于k的大小,而对于这道题目的时限来说,这个算法远远不能达到要求,因此我们需要改进算法。 第一步离散化: 考虑点集的每一横行,我们发现每一个圆在其上覆盖的点一定是连续的。 图4 于是我们想到在每一横行中不必枚举每一个点,转而计算每一个圆在其上的覆盖区间,这一步可以用数学算法在常数时间内算出。 然后合并相交的区间。在预处理时,可以将圆按横坐标排好序,这样在合并区间时会变得更简单。 最后根据被覆盖的区间求出未被圆覆盖的区间。 仿照方法1,我们将所有的区间记录下来,并在相邻两行有公共部分的区间连一条边,然后求连通块数,最后减1即为答案。 由于区间个数太多,无论DFS还是BFS都消耗了太多内存,因此我们可以利用图的特殊性,创造一种效率较高的顺序扫描求连通块数法: 初始化第一横行(仅有一个区间),这一区间从属于1个集合。 给下一横行的每一区间初始化一个新的集合仅包含他。 如果两行中某两个区间有交集,合并他们所从属的集合。 如果某一集合中的所有区间在下一行都没有继承者,答案加1。 重复2~4,直到扫描至最后一行。 可以看到,这个算法的复杂度为O(nk),在时限内可以得到较高的精度。 但是,由于题目中存在某些精度要求非常高的数据,并且此算法本身的精度不够,最终这个算法得到了Wrong Answer。所以,我们仍需要进一步改进。 第二步离散化: 仔细观察程序,我们发现,似乎有很多无用的工作。如下例: 图5 在绿色区域中,我们直观的感觉到,这肯定是同一片区域,因为在其中根本就没有其他的圆,而我们的程序却在其中辛苦的一步步跟踪,直到最后确认最下一行确实是最上一行的后继。 于是我们有了另一种想法——省略多余的操作。我们发现,区间之间的继承关系在大多数时候都没有改变,只在仅有的少数几个时刻才会发生改变: 一个圆新出现时,将一个区间分成两半。 两圆相交,一个区间逐渐减小并被吞噬。 两圆相交,一个新的区间生成。 一个圆的最下端,两个区间合并为一个区间。 这样,我们仅需记录所有

文档评论(0)

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档