2016-04-12 11 views
-1

現在、javaでkmeansアルゴリズムを実装しようとしています。私たちの問題は次のとおりです。しばらくしてからループが書き込まれたばかりの理由は何ですか?

getData()メソッドを使用して、ファイルのデータで2次元配列を塗りつぶしています。 getData()メソッドのwhileループの内部には、println()があり、returnコマンドの直前にもう1つあります。

最初のprintln()は、ファイルから取得した正しい値を返します。

第2のprintln()は、arrayList[299][0]を除いて、その配列内のすべてのフィールドについてとなります。

なぜですか?

class KMeans { 

    // Number of clusters 
    int numberOfClusters = 4; 
    // Starting point for each cluster (these values should be better than completely random values for our given data set) 
    static double[] a = new double[]{-1.5, 2.0}; 
    static double[] b = new double[]{-1.5, 7.0}; 
    static double[] c = new double[]{1.5, 7.0}; 
    static double[] d = new double[]{1.5, 2.0}; 
    static double[][] pointArray; 

    // This calculates the distance between a given point from the data set and a centroid 
    public static double calculateDistance(double[] point, double[] centroid) { 
     // get difference for X coordinates 
     double maxX = Math.max(point[0], centroid[0]); 
     double minX = Math.min(point[0], centroid[0]); 
     double differenceX = maxX - minX; 
     double differenceXSquared = Math.pow(differenceX, 2); 

     // get difference for Y coordinates 
     double maxY = Math.max(point[1], centroid[1]); 
     double minY = Math.min(point[1], centroid[1]); 
     double differenceY = maxY - minY; 
     double differenceYSquared = Math.pow(differenceY, 2); 

     // The whole thing is nothing other than pythagoras 
     double zSquared = differenceXSquared + differenceYSquared; 
     double z = Math.sqrt(zSquared); 
     return z; 
    } 

    // This calculates which of the given distances is the lowest 
    public static double[] nearestCluster(double e, double f, double g, double h) { 
     double x = Math.min(e, f); 
     double y = Math.min(x, g); 
     double z = Math.min(y, h); 

     if (z == e) { 
      return a; 
     } 
     if (z == f) { 
      return b; 
     } 
     if (z == g) { 
      return c; 
     } else { 
      return d; 
     } 
    } 

    // Read the file 
    public static double[][] getData() { 
     try (BufferedReader br = new BufferedReader(new FileReader("/home/john/Downloads/data.txt"))) { 
      String line; 
      int i = 1; 
      int j = 0; 
      while ((line = br.readLine()) != null) { 
       // Create the array in which we store each value 
       pointArray = new double[i][4]; 
       //Splits each line a the space and writes it to an array 
       String[] split = line.split("\\s+"); 

       // Cast the strings to double and write them to our pointArray   
       pointArray[j][0] = Double.parseDouble(split[0]); 
       pointArray[j][1] = Double.parseDouble(split[1]); 
       System.out.println(pointArray[0][0]); 
       i++; 
       j++; 
      } 
     } catch (IOException e) { 
     } 
     System.out.println(pointArray[0][0]);   
     return pointArray; 
    } 

    public static void main(String[] args) throws FileNotFoundException, IOException { 
     pointArray = getData(); 
     for (double[] x : pointArray) { 
      double distanceA = calculateDistance(x, a); 
      double distanceB = calculateDistance(x, b); 
      double distanceC = calculateDistance(x, c); 
      double distanceD = calculateDistance(x, d); 

      // Assigns the closest cluster to each point (not too efficent because we call the function twice, but it works) 
      x[2] = nearestCluster(distanceA, distanceB, distanceC, distanceD)[0]; 
      x[3] = nearestCluster(distanceA, distanceB, distanceC, distanceD)[1]; 
     } 
    } 
} 
+6

'pointArray = new double [i] [4];'ここで何をしようとしていますか?各反復で配列変数をリセットします。 – Eran

+0

アイデアは、ファイルから取得するデータのサイズに応じて、配列のサイズを動的に拡大することです。 – user2765654

+3

そのようには動作しません。リストを使いましょう。 – Fildor

答えて

5

pointArray = new double[i][4]; 

線ループを介してアレイを毎回再初期化。実際には、あなたが読んだ最後の行を除くすべての値を放棄しています。

代わりに、ArrayListを使用して、それぞれの行を保持してください。このようなwhileループの前にそれを設定します。

List<Double[]> pointList = new ArrayList<>(); 

次に、あなたはこのような各ラインでそれに追加することができます。

Double[] points = new Double[4]; 
// ... 
points[0] = Double.parseDouble(split[0]); 
// etc. 
pointList.add(points); 

その後pointListを返すか、復帰のための配列に変換のいずれか。

関連する問題