计算2D点的几何中值

时间:2012-04-15 13:04:47

标签: java median

我正在计算java中某些(x,y)点的Geometric median。要计算Geometric median,首先我计算所有点的centroid,然后使用此centroid来计算Geometric median。我的代码运行正常,但有时会进入无限循环(我认为)。我的while条件存在问题。这个while条件应根据输入点进行更改,但我不知道如何。下面我将提供完整的代码。

import java.util.ArrayList;

public class GeometricMedian {

    private static ArrayList<Point> points = new ArrayList<Point>();

    private class Point {
        private double x;
        private double y;

        Point(double a, double b) {
            x = a;
            y = b;
        }
    }

    public static void main(String[] args) {
        GeometricMedian gm = new GeometricMedian();
        gm.addPoints();
        Point centroid = gm.getCentroid();
        Point geoMedian = gm.getGeoMedian(centroid);
        System.out.println("GeometricMedian= {" + (float) geoMedian.x + ", "
                + (float) geoMedian.y + "}");
    }

    public void addPoints() {
        points.add(new Point(0, 1));
        points.add(new Point(2, 5));
        points.add(new Point(3, 1));
        points.add(new Point(4, 0));
    }

    public Point getCentroid() {
        double cx = 0.0D;
        double cy = 0.0D;
        for (int i = 0; i < points.size(); i++) {
            Point pt = points.get(i);
            cx += pt.x;
            cy += pt.y;
        }
        return new Point(cx / points.size(), cy / points.size());
    }

    public Point getGeoMedian(Point start) {
        double cx = 0;
        double cy = 0;

        double centroidx = start.x;
        double centroidy = start.y;
        do {
            double totalWeight = 0;
            for (int i = 0; i < points.size(); i++) {
                Point pt = points.get(i);
                double weight = 1 / distance(pt.x, pt.y, centroidx, centroidy);
                cx += pt.x * weight;
                cy += pt.y * weight;
                totalWeight += weight;
            }
            cx /= totalWeight;
            cy /= totalWeight;
        } while (Math.abs(cx - centroidx) > 0.5
                || Math.abs(cy - centroidy) > 0.5);// Probably this condition
                                                    // needs to change

        return new Point(cx, cy);
    }

    private static double distance(double x1, double y1, double x2, double y2) {
        x1 -= x2;
        y1 -= y2;
        return Math.sqrt(x1 * x1 + y1 * y1);
    }
}

请帮助我修复错误,如果有任何更好的方法来计算某些2D点的Geometric median,请写在这里。谢谢。

2 个答案:

答案 0 :(得分:0)

我不明白为什么你需要两个循环。你只需要在所有点上循环。在你看来,另一个原因是什么?

答案 1 :(得分:0)

解决此问题的一种方法是迭代一定次数。这类似于K-Means方法,它可以收敛到特定阈值,也可以在预定义的迭代次数后停止。