2012-04-15 19 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

*もう一度*あなたのプログラムをデバッグする必要があります。私はあなたが最初にデューデリジェンスをしなければならないという点で、早すぎてスタックオーバーフローに来ていると思います。 –

答えて

0

2つのループが必要な理由はわかりません。すべてのポイントにループが必要です。あなたの見解では、もう一方の理由は何ですか?

+0

'do-while'である外側のループを削除すると、すべての入力点に対して' centroid'が 'Geometric median'になります。しかし、「幾何学的中央値」は「重心」に等しい必要はない。しかし、 'do-while'ループを入れると、' while'ループを止める正しい条件を設定することができません。これが私の外側のdo-whileループが無限に行く理由です。 –

0

これを解決する1つの方法は、特定の回数だけ繰り返すことです。これは、特定のしきい値に収束するか、あらかじめ定義された回数だけ反復するK-Means法と同様です。

関連する問題