使用Java中的扫描线算法的最近点

时间:2015-01-09 11:13:29

标签: java algorithm closest-points

首先关闭;我这样做是为了学校的任务,这就是我使用扫描线算法的原因。我是基于我老师给出的伪代码。

我已经使用TreeMap而不是平衡的二进制搜索树完成了我自己的实现,我被告知会提供相同的功能。 (不知道这是否属实?)

但是我没有得到正确的最终结果,我真的不知道为什么。我一直盯着自己。

以下是执行实际计算的代码部分。我省略了创建点列表和其他不重要的东西。

            count = 0;

            TreeMap<Double, Point> tree = new TreeMap<Double, Point>();

            double dist = Double.POSITIVE_INFINITY;

            // Sorts points on x-axis
            Collections.sort(points); 

            // Gets left-most point
            Point q = points.get(count++);

            for (Point p : points) {

                while (q.getX() < p.getX() - dist) {
                    tree.remove(q.getY());
                    q = points.get(count++);
                }

                NavigableSet<Double> keys = tree.navigableKeySet();

                // Look at the 4 points above 'p'
                int i = 1;
                Iterator<Double> iterHi = keys.tailSet(p.getY()).iterator();

                while (i <= 4 && iterHi.hasNext()) {
                    double tmp = p.distanceTo(tree.get(iterHi.next()));
                    if (tmp < dist) {
                        dist = tmp;
                        pClosest = p;
                        qClosest = q;
                    }
                    i++;
                }

                // Look at the 4 points below 'p'
                i = 1;
                Iterator<Double> iterLo = keys.headSet(p.getY()).iterator();

                while (i <= 4 && iterLo.hasNext()) {
                    double tmp = q.distanceTo(tree.get(iterLo.next()));
                    if (tmp < dist) {
                        dist = tmp;
                        pClosest = p;
                        qClosest = q;
                    }
                    i++;
                }

                tree.put(p.getY(), p);
            }

            double finalDist = pClosest.distanceTo(qClosest);

编辑:可以在此处找到伪代码:http://pastebin.com/i0XbPp1a。它基于我老师在白板上写的笔记。

关于结果: 使用以下几点(X,Y): (0,2) - (6,67) - (43,71) - (39,107) - (189,140)

我应该得到~36,但我得到~65。

1 个答案:

答案 0 :(得分:2)

我已经在您的代码中发现了几个错误(我不确定没有其他错误):

  1. 如果多个点具有相同的y坐标怎么办? TreeMap每个y值只能保留一个点。这就是你想要的吗?

  2. 当您查看当前点之上和之上的点时,您计算到iterHi.next()double tmp = p.distanceTo(tree.get(iterHi.next()));的距离,然后将qClosest指定给q 。这是不正确的(显然,iterHi.next()q不是同一点。)

  3. 在第二个内循环中,您计算​​从q到集合元素的距离:double tmp = q.distanceTo(tree.get(iterLo.next()));。它应该是p

  4. 我还建议维护TreeSet Point而不是使用TreeMap(当然,它们应该用y坐标进行比较)。