临近图系列

临近图
一系列的具有临近关系的图
DT是他们的超图
可以先计算出DT然后在计算出这些重要的图
整体关系
DT >= GG >= RNG >= EMST >= NNG
0、Delaunay Triangulation(DT)
定义
德劳内三角剖分

			唯一生成的
				任意相邻两点构成的直线,定是某空圆的弦
				同样是三角剖分,得老内剖分的结果:是一种使最小角达到最大的三角剖分
		算法
			//德劳内三角剖分 RIC算法

#include
using namespace std;

// 代表一个点
struct Point {
int X;
int Y;
};

// 代表一个三角形
struct Trangle {
Point a, Point b, Point c;
};

// 返回德劳内图形DT中某点P所在的三角形 (会用到DCEL结构)
T TriangleContaining (Polyline DT, Point P) {
//这里用一个桶来存储其中所有的点,每个桶的外边界就是一个已经剖分过的三角形
}

//找到与abc构成三角形的右边的三角形中ab边对应的点x
Point RightSite(Point a, Point b) {
//使用DCEL 既b\a边所在三角形中的另一个顶点
//没有返回null
}

//查看x是否在p、a、b三点构成的内接圆中
int InCircle(Point p, Point a, Point b, Point x) {
//一个行列式 关于 a\b\x\p的四阶行列式
//优点:没有除法,速度O(1)
return f(pabx); //大于0表示在圆内,小于表示在圆形外
}

//用ab替换px
void FlipEdge(Point a, Point b, Point p, Point x) {
//这里面要操作的结构是要改变上面的存储桶三角形所包含点的位置
//原本四边形p a x b可分割为T(p, a, b)&T(a, b, x),现在分割为T(p, a, x) & T(p, b, x)
}

//测试固定a、b两点,与p构成的外接圆是否为空圆(圆内不存在任何点)
//如果不为空圆,则修改为最优(使用了递归)
void STest(Point p, Point a, Point b) {
//获取从a到b直线右边的那个点(利用DCEL的双向结构)
//(与a、b所在线段构成三角形(会有左右两个)右边的那个顶点)
Point x = RightSite(a, b);
//如果不存在点x在ab右侧,即ab为多边形的边界,最简单的情况,不用处理
if(!x) return;
//查看x是否在p、a、b三点构成的内接圆中
if(InCircle(p, a, b, x) > 0) {
//用ab替换px
FlipEdge(a, b, p, x);
//测试新增加的值得怀疑的两条线
STest(p, a, x);
STest(p, x, b);
}
}

//德劳内三角形的递归做法
//测试并修复图中可疑的pa、pb、pc线(因为可能破坏结构不符合空圆要求)
void SwapTest(Point p, Point a, Point b, Point c) {
STest(p, a, b);
STest(p, b, c);
STest(p, c, a);
}
//德劳内三角剖分的递推做法
//只需改变递归做法中的反转测试
SwapTest(p, a, b, c) {
queue q = {(a, b), (b, c), (c, a)};
wahile(!q.empty()) {
(a, b) = q.dequeue();
Point x = RightSite(a, b);//find t(a,x,b) on opposite side(using DCEL)
if(!x) connect; //in case x doesnot exist
if(InCircle(p, a, b, x)) { //if x voilates in-circle condition
FlipEdge(a, b, p, x);//replace ab with px and
Q.enqueue((a, x), (x, b));//insert the 2 new triangles
}
}
}

//在已经正确的德劳内图形中插入点P
void Insert (Point p) {
//首先找到包含P这个点的三角形(P在哪个三角形内部)
Trangle T(a, b, c) = TriangleContaining(DT, p);

//链接pa、pb、pc三条线 并插入到德劳内三角剖分图形中
connect(p, a);
connect(p, b);
connect(p, c);

//测试并修复图中可疑的pa、pb、pc线(因为可能破坏结构不符合空圆要求)
SwapTest(p, a, b, c);

}

int main() {
Point a, Point b, Point c;
//假设原本是一个超巨大的三角形
Polyline DT(a, b, c);
//不断地加入点构成更多的三角形。
//类似于建堆
for(int i = 2; i < points.size(); ++i) {
Insert(points[i]);
}
return 0;
}

	关系
		DT是维诺图互为对偶图
0.5、Convex Hull
	定义
		凸包
	关系
		凸包会包含所有的点
		CH是DT的子图
1、Gabriel Graph(GG)
	定义
		任意两相连点构成的直线为直径,这个圆是空圆
	关系
		GG是DT的子图
		GG是连通图
2、Relative Neighborhood Graph(RNG)
	定义
		相对邻居图
		任意两相连点P、Q,p为圆心半径到q的圆,以及q为圆心同样半径的圆,相交部分是空的(不含有其他点)
	关系
		RNG是GG子图
		RNG是连通图
3、Euclidean Minimum Spanning Tree (EMST)
	定义
		欧式最小生成树
		Euclidean
			所有点都应当属于一个欧氏空间
			任意两点之间的权重就是其欧氏距离
		使所有点 连通且最权重最小的生成树
		如果直接去求,那么点之间两两都有距离,就是一个完全图(N^2条边),可以通过DT使边减少为N的常数倍
			然后依旧是正常的最小生成树算法
				克鲁斯卡尔O(n * n * logn)
				普利姆O(n * n)
	关系
		EMST是RNG的子图
			反证法
		EMST是连通图
		EMST没有环路
4、Nearest Neighbour Graph(NNG)
	定义
		最近邻图
		每个点指向离它最近的那个点
	关系
		NNG是EMST的子图
		NNG可能不连通(Forest)
		NNG有向
5、拓展
	Minimum Weighted Triangulation(MWT)
		定义
			最小权重三角划分
			每个三角形三边之和尽可能的小
		关系
			此算法和德劳内三角划分区分开来
			这个问题是NP-complete的
	Euclidean Traveling Salesman Problem
		定义
			欧式旅行商问题
			是一种NP—Hard问题
		关系
			但是可以快速获得一个次优的解,这个次优近似解最差也是最优解的两倍以内
				算法
					首先生成EMST,利用DCEL遍历EMST并生成环路,遇到见过的就跳过
			ps:有一种1.5倍次优解,但是算法难度较大
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值