Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/402.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 计算O((n&x2B;s)对数n)中的圆交点_Java_Algorithm_Geometry_Complexity Theory_Intersection - Fatal编程技术网

Java 计算O((n&x2B;s)对数n)中的圆交点

Java 计算O((n&x2B;s)对数n)中的圆交点,java,algorithm,geometry,complexity-theory,intersection,Java,Algorithm,Geometry,Complexity Theory,Intersection,我正试图找出如何设计一种算法,能够以O((n+s)logn)的复杂度完成这项任务。是指交叉口的数量。我试着在互联网上搜索,但找不到真正的东西 无论如何,我意识到拥有一个好的数据结构是这里的关键。我正在使用java:TreeMap中的红黑树实现。我还使用著名的(?)扫描线算法来帮助我处理我的问题 让我先解释一下我的设置 我有一个时间表。这是一个优先队列,我的圆圈根据最左边的坐标排序(升序)scheduler.next()基本上轮询优先级队列,返回最左边的下一个圆圈 public Circle ne

我正试图找出如何设计一种算法,能够以O((n+s)logn)的复杂度完成这项任务。是指交叉口的数量。我试着在互联网上搜索,但找不到真正的东西

无论如何,我意识到拥有一个好的数据结构是这里的关键。我正在使用java:TreeMap中的红黑树实现。我还使用著名的(?)扫描线算法来帮助我处理我的问题

让我先解释一下我的设置

我有一个时间表。这是一个优先队列,我的圆圈根据最左边的坐标排序(升序)
scheduler.next()
基本上轮询优先级队列,返回最左边的下一个圆圈

public Circle next()
{ return this.pq.poll();    }
这里还有一个包含4n个事件点的数组。每个圆圈有2个事件点:最左x和最右x。调度程序有一个方法sweedline()来获取下一个事件点

public Double sweepline()
{ return this.schedule[pointer++];    }
我也有身份。扫描线状态将更加精确。根据这一理论,地位包括有资格相互比较的圈子。在整个故事中使用扫描线的意义在于,你可以排除很多候选对象,因为它们根本不在当前圆的半径范围内

我用一个
树映射实现了状态。Double是圆。getMostLeftCoord()。

此树映射保证插入/删除/查找的O(日志n)

算法本身的实现方式如下:

Double sweepLine = scheduler.sweepline();
Circle c = null;
while (notDone){
    while((!scheduler.isEmpty()) && (c = scheduler.next()).getMostLeftCoord() >= sweepLine)
        status.add(c);


    /*
     * Delete the oldest circles that the sweepline has left behind
     */
    while(status.oldestCircle().getMostRightCoord() < sweepLine)
        status.deleteOldest();

    Circle otherCircle;
    for(Map.Entry<Double, Circle> entry: status.keys()){
        otherCircle = entry.getValue();
        if(!c.equals(otherCircle)){
            Intersection[] is = Solver.findIntersection(c, otherCircle);
            if(is != null)
                for(Intersection intersection: is)
                    intersections.add(intersection);
        }
    }

    sweepLine = scheduler.sweepline();
}
我测试了我的程序,我显然有O(n^2)的复杂性。 我错过了什么?你们能提供的任何意见都是非常受欢迎的


提前谢谢

N个圆心和半径相同的圆将有N(N-1)/2对相交圆,而通过使用足够大的圆,使其边界几乎是直线,您可以绘制一个网格,其中N/2条线与N/2条线中的每一条线相交,即N^2。当你添加一个新的圆圈时,我会看看地图上通常有多少条目


您可以尝试为圆使用边界正方形,并在挂起的正方形上保留索引,以便只能找到y坐标与查询正方形相交的正方形(假设扫描线平行于y轴)。这意味着-如果你的数据是友好的,你可以持有大量待处理的方块,并且只检查其中一些方块内圆的可能交点。数据不够友好,导致实际N^2个交点始终是一个问题。

O(N log N)中,无法找到平面中
N
圆的所有交点
时间,因为每对圆最多可以有两个不同的交点,因此
n
圆最多可以有
n²-n
个不同的交点,因此它们不能在
O(n log n)
时间中枚举

获得最大数量的
n²-n
交点的一种方法是将等半径
r
n
圆的中心放置在长度
l<2r
直线上相互不同的点上


与整个区域相比,圆圈有多大?如果这个比率足够小,我会考虑把它们放入某种桶中。这将使复杂性比
O(n log n)
稍微复杂一点,但应该更快。

“我显然有O(n^2)复杂性”-运行程序时无法判断这一点,因为否则可以解决暂停问题。您希望平面中
n
圆的所有交点都在
O(n log n)中
时间,对吗?对圆没有限制?@G.Bach这在科学上是不准确的,但在判断一个算法是
O(n logn)
还是
O(n²)
O(2^n)
运行几个测试实例就足够了。@DanielBrückner这肯定不够好,因为这是一个正式的声明,一个正式的陈述需要正式的证明。运行测试足以告诉您预期的运行时间。这不是告诉复杂性的正确工具。@G.Bach我不需要任何形式的证明,但如果我设计一个O(nlogn)算法,我至少希望它在我所做的每一次运行的绘图上都能表现出它的行为。在这种情况下,我是在一个快速和肮脏的检查,以了解我是否做得很好。事实上,我所有的曲线图都显示出N翻倍的指数增长,对我来说,这肯定比O(N logn)更糟糕。参见mcdowella关于如何排列圆的直觉回答。这个问题仍然有效,但应该重新表述:计算O(nlogn+k)中的圆交点,其中N是圆的数量,k是交叉口的数量。我认为可以对圆的半径进行任何限制,因为建议的定位应该“缩放”。@GBach-我认为你是对的。这并不是一个关于圆的大小以及大小和相对位置的组合的问题。我只是觉得站在一个比我大得多的圆圈旁边很方便,我所能看到的都像一条直线。
public class BetterSweepLineStatus {

TreeMap<Double, Circle> status = new TreeMap<Double, Circle>();

public void add(Circle c)
{ this.status.put(c.getMostLeftCoord(), c);     }

public void deleteOldest()
{ this.status.remove(status.firstKey());    }

public TreeMap<Double, Circle> circles()
{ return this.status;       }

public Set<Entry<Double, Circle>> keys()
{ return this.status.entrySet();    }

public Circle oldestCircle()
{ return this.status.get(this.status.firstKey());   }