您的位置:首页 > 编程语言 > Go语言

《Algorithms算法》笔记:元素排序(4)——凸包问题

2016-04-06 23:27 686 查看

《Algorithms算法》笔记:元素排序(4)——凸包问题

Algorithms算法笔记元素排序4凸包问题

凸包问题

凸包问题的应用

凸包的几何性质

Graham 扫描算法

代码

凸包问题


凸包问题就是说,找到一个最小的凸多边形能圈住所有的点。





凸包问题的应用

运动规划:找到从s到t的最短路径,最短路径肯定在凸包上



最远的一对:相隔最远的点对肯定在凸包上



凸包的几何性质

可以通过逆时针遍历所有凸包顶点

凸包的顶点是关于p的极角的递增序列,而p有最小的y坐标。



Graham 扫描算法

选择y坐标最小的p

如何确定最小y坐标?

循环一遍

对所有的点按关于p的 极角排序

如何对点进行极角排序?

如何效率的排序?

用MergeSort

按顺序连接每个点,如果发现打破pi−2→pi−1→pi 打破了逆时针的原则,则舍弃pi−1,pi。

如何判断是否打破了逆时针原则ccw?

如何解决退化问题(多个点在一条直线上)

通过计算(b-a)和(c-a)的叉乘就行了。

如果area > 0 则是逆时针,

如果area < 0 则是顺时针

如果area = 0 则是共线



代码

由于每次要判断最后的2个点是否是逆时针,毫无疑问使用栈结构是比较合适的

public class Point2D
{
private final double x;
private final double y;
public Point2D(double x, double y)
{
this.x = x;
this.y = y;
}
...
public static int ccw(Point2D a, Point2D b, Point2D c)
{
double area2 = (b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x);
if      (area2 < 0) return -1;
// clockwise
else if (area2 > 0) return +1;
// counter-clockwise
else                return  0;
// collinear
}
}
stack<Point2D> hull = new Stack<Point>();
Array.sort(p,Point2D.Y_ORDER);//find p
Array.sort(p,p[0],BY_POLAR_ORDER)//

hull.push(p[0]);
hull.push(p[1]);

for(i = 2;i < N;i++)
{
Point2D top = hull.pop();
while(Point2D.ccw(hull.peek(),top,p[i]) <= 0)
top = hull.pop();
hull.push(top);
hull.push(p[i]);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: