二维平面点集相似问题思考及优化

发布于:2025-05-31 ⋅ 阅读:(16) ⋅ 点赞:(0)

欢迎关注更多精彩
关注我,学习常用算法与数据结构,一题多解,降维打击。

问题描述

如果两个点集可以通过平移,X轴对称,Y轴对称,中心对称得到相同的点集,则移两个点集相似。

给定多个点集,将所有相似点集归为一组。

在这里插入图片描述
上图中所有矩形内的点集是相似的,每一个点集都可以通过平移对称得到其他的点集。

核心思路

  1. 先将把每一个点集的中心移动到原点
  2. 每个点集通过对称性复制出另外三份点集
  3. 对每个点集进行坐标排序
  4. 通过比对 坐标是否相等判断相似性,点集a与点集b的任一副本相同则为相似。

细节优化

当数据量很大的时候,以上思路会存在性能问题。

有2个优化点

减少复制

在步骤2,3 中,我们要得到三个已经排好序的副本。

但实际上只要对原点集(已经移动到中心)进行2次排序,分别是按照x从小到大(x相同时按照y从小到大)arrX,和按照x从小到大(x相同时按照y从大到小)arrX’

按照以下方法得到4个点集(有序)

  1. 顺序遍历arrX 可以得到原点集。
  2. 顺序遍历arrX’ 并令y=-y, 得到关于X轴对称的点集。
  3. 逆序遍历arrX’ 并令x=-x, 得到关于X轴对称的点集。
  4. 逆序遍历arrX 并令x=-x, y=-y 可以得到关于原点对称的点集。

减少比较

对于两个点集,如果相似,则两个点集分别产生出来的4个副本必然是一一对称相同的。

所以我们只要比较其中一个相同就可以。

那么我们就取字典序最小的一个来比较。

令arrX 为初始点集,

分别按照上述的2,3,4遍历步骤,并比较与arrX的字典序,如果更小则替换。

得到一个点集后,进行一个内存哈希,哈希会有碰撞概率,进行多重哈希解决冲突问题。

问题升级

有一个超大点集,n个点,给定一个边长l。

每一个点以该点为中心边长为l的正方形内所有点组成一个点集,则有n个这样的点集。

对这n个点集按照相似进行分组。

问题分析

这个的问题在于如何快速生成这n个有序点集(arrX, arrX’)。

之后的处理就和之前分析的一样。

很容易想到利用包围盒查询+排序的方式来实现。

但是,这里相当于排了n次序,是很耗时的。

另一种方式是

1 对超大点集进行排序

2 然后遍历点集每一个点A, 看A属于哪些点B的正方形内,并添加到B的集合中。

以上方法可以保证B有序。

耗时的大头就在第二步,另外B的集合是用数组表示,内存也是很大的挑战。

优化内存

上述方法只要解决内存问题,效率还是可以接受。

我们可以使用分批的形式来解决。

对所有点集进行分块,假设每块的长宽是L=10 * l。

对每一块向外扩展l。 然后对块进行两次排序。

然后遍历点集每一个点A, 看A属于哪些点B(B在当前块中)的正方形内,并添加到B的集合中。

这样B的集合数量不会太多。可以通过调整L大小来控制。


本人码农,希望通过自己的分享,让大家更容易学懂计算机知识。
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到