【发布时间】:2012-10-18 09:33:42
【问题描述】:
我正在尝试做一个函数,它接受一个圆圈列表,并且只返回一个完全重叠的圆圈列表(一个在另一个里面)。问题在于该算法至少为 O(n²),这是由于 getConcentricCircles 函数中嵌套了 for,并且对于大型数据集需要很长时间。有什么办法可以优化吗?
编辑:我不知道这是否有帮助,但我使用该算法来检测虹膜和瞳孔检测中的误报。如果一个圆圈完全在另一个圆圈内,那很可能是瞳孔,而外面是虹膜。它们应该是同心的,这会简化很多,但是人眼中的瞳孔恰好不在虹膜的中心,这就是我这样做的原因。
编辑 2:我已将 isCircleInCircle 替换为 Peter Lawrey 的解决方案,在某些情况下我的解决方案不正确
检查圆是否在圆内的功能:
private static boolean isCircleInCircle(Circle a, Circle b) {
// the circle is inside if the distance between the centre is less than the difference in the radius
double dx = a.getX() - b.getX();
double dy = a.getY() - b.getY();
double radiusDifference = a.getRadius() - b.getRadius();
double centreDistanceSquared = dx*dx + dy*dy; // edited
return radiusDifference * radiusDifference > centreDistanceSquared;
}
然后我检查列表中的每个元素,并只保存重叠的圆圈(和重叠的圆圈):
public HashSet<Circle> getConcentricCircles(List<Circle> circleList) {
HashSet<Circle> toReturn = new HashSet<Circle>();
for (Circle circle : circleList) {
for (Circle toCheck : circleList) {
// if the circles are not the same and one is inside another,
if (!toCheck.equals(circle) && isCircleInCircle(circle, toCheck)) {
// add both to the hashset
toReturn.add(circle);
toReturn.add(toCheck);
}
}
}
return toReturn;
}
【问题讨论】:
-
-
@PeterLawrey 你完全正确,我只是逐字翻译了公式。但是,我不知道它可能是乘数的 10 倍!
-
要执行 pow,它会有效地执行
Math.exp(math.log(x) * 2) -
这并没有提高 O(n^2) 复杂度。
-
如果c1在c2里面,也在c1里面,但是c1和c2重叠,算法应该返回什么?
标签: java algorithm optimization