2012-04-15 6 views
0

Geometric median 나는 java에서 일부 (x,y) 점을 계산 중입니다. Geometric median을 계산하려면 먼저 모든 포인트의 centroid을 계산하고 Geometric median을 계산하려면이 centroid이 사용됩니다. 내 코드는 잘 동작하지만 때로는 무한 루프로 진행된다. 문제는 내 while 상태입니다. 이 while 조건은 입력 지점에 따라 변경해야하지만 어떻게해야할지 모르겠다. 아래에서는 전체 코드를 작성합니다.2D 점의 기하학적 중간 값을 계산하십시오

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을 계산하는 더 좋은 방법이 exitis 경우 나 또한 버그를 해결하기 위해 도와주세요. 고맙습니다.

+0

가장 좋은 점은 처음에 문제의 정확한 지점과 그 당시의 프로그램 상태를 찾는 것입니다. 디버거를 사용하거나 println 문에 코드를 뿌리면 주요 지점에서 변수의 상태를 확인할 수 있습니다. –

+0

@HovercraftFullOfEels : 포인트'(0,1), (2,5), (3,1), (4,0)'에 대해, 내 프로그램은'GeometricMedian = {2.4373634, 1.3966105}'를 출력합니다. 이 점들에 대해서는 작동하지만, 다른 점'(-3,0), (-1,5), (0,10), (10,0), (50,0)'을 가지고 있다고하자. 무한 루프. 문제는 'while'조건입니다. 이 조건은 입력 점에 따라 업데이트해야합니다. 하지만 어떻게해야할지 모르겠다! –

+0

* 다시 * 먼저 프로그램을 디버깅해야합니다. 나는 당신이 먼저 실사해야한다는 점에서 조만간 stackoverflow에 올 것이라고 생각한다. –

답변

0

두 개의 루프가 필요한 이유가 표시되지 않습니다. 모든 점에 대해서만 루프가 필요합니다. 당신이보기에 다른 하나의 이유는 무엇입니까?

+0

'do-while'인 외부 루프를 제거하면 모든 중심점에 대해 '중심'이 'Geometric median'이됩니다. 그러나 '기하학적 중앙값'은 '중심'과 같을 필요는 없습니다. 하지만 'do-while' 루프를 넣으면 올바른 조건을 넣어'while '루프를 멈출 수 없습니다. 이것이 내 외부 do-while 루프가 무한하게가는 이유입니다. –

0

이 문제를 해결하는 한 가지 방법은 특정 횟수만큼 반복하는 것입니다. 이것은 K-Means 방법과 유사합니다.이 방법은 특정 임계 값으로 수렴되거나 사전 정의 된 반복 횟수 후에 중지됩니다.

관련 문제