这是一个与优化相关的问题,我找不到答案。
我编写了一些代码来计算给定随机点集的凸包。为了比较目的,我使用一些旧的OpenGL工具编写了自己的慢速O(n³)算法来可视化它。由于慢凸包算法的性质,点根本没有排序。因此,排序发生在计算CH之后。
我的问题是,对于最多1000个点,我可以在一秒钟内获得视觉效果。但是对于10000个点,需要15-20分钟以上(我没有等超过那个时间)。但是如果跳过排序代码,让opengl显示未排序的凸包顶点,则只需不到一分钟。所以这就是吃掉所有时间的ClockWise排序的原因。请检查代码(某些名称因在其他地方被定义而不合理):
// This code actually compares every pair iteratively with respect to the center point
// Consider a given vector "convex", which contains all the convex hull points unsorted
.
..
...
....
int avgx,avgy,sumx=0,sumy=0;
for (int i=0;i<convex.size();i++){
sumx+=convex.at(i).at(0);
sumy+=convex.at(i).at(1);
}
avgx=sumx/(convex.size()/2.0); //something like an internal point
avgy=sumy/(convex.size()/2.0);
sort(convex.begin(),convex.end()); //x-sort
int det,tempx,tempy;
for (int i=0;i<convex.size()-1;i++){
x1=convex.at(i).at(0);
y1=convex.at(i).at(1);
x2=convex.at(i+1).at(0);
y2=convex.at(i+1).at(1);
det=(x1-avgx)*(y2-avgy)-(x2-avgx)*(y1-avgy);
if (det<0){ //on which side of O-X1 lies X2?
tempx=convex.at(i).at(0); //swapping points
tempy=convex.at(i).at(1);
convex.at(i).at(0)=convex.at(i+1).at(0);
convex.at(i).at(1)=convex.at(i+1).at(1);
convex.at(i+1).at(0)=tempx;
convex.at(i+1).at(1)=tempy;
i=-1; //check again the new vector from the beginning
}
}
return convex;
显示部分:
glColor3f(0.8, 0.2, 0.2);
glPointSize(3);
glBegin(GL_LINE_LOOP);
for (int i=0;i<count;i++){
glVertex2f(convexHull.at(i).at(0),convexHull.at(i).at(1));
}
glEnd();
根据我所见,通过比较叉积的方法是最有效的。不过,在这之前,我写了一些很糟糕的代码,实际上速度更快,因为它可以在8分钟内给出视觉结果。但我不想保留它,因为它太乱且太长了。这个更干净但非常慢(如果它真的能工作的话...)。那么,我必须等待这么久才能对10000个凸点进行CW排序,还是有什么我不知道的东西?如有需要,请告诉我其他方面的想法或需求。