2016-04-12 20 views
-1

Şu anda java'da kmeans algoritmasını uygulamaya çalışıyoruz. Bizim sorunumuz:Bir süre döngüsünden sonra: Neden sadece boş olarak yazılmış bir dizi var?

İki boyutlu bir diziyi bir dosyadaki verilerle doldurmak için getData() yöntemini kullanıyoruz. getData() yöntemindeki while döngüsünde, bir println() var ve dönüş komutundan hemen önce bir tane daha var.

İlk println(), dosyadan yeni edindiğimiz doğru değerleri verir.

İkinci println(), arrayList[299][0] hariç, bu dizinin içindeki her alan için bize 0.0 verir.

Neden?

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 = yeni çift [i] [4];' - burada ne yapmaya çalışıyorsunuz? Her yinelemede dizi değişkenini sıfırlarsınız. – Eran

+0

Fikir, dosyadan aldığımız verilerin boyutuna bağlı olarak dizinin boyutunu dinamik olarak ölçeklendirmektir. – user2765654

+3

Bu şekilde çalışmıyor. Bir Listeyi daha iyi kullan. – Fildor

cevap

5

hattı

pointArray = new double[i][4]; 

dizi döngü içinde, her zaman yeniden başlatır. Aslında, okuduğunuz son satır dışındaki her değeri atıyorsunuz. Her bir satırı tutmak için ArrayList kullanın. Sonra

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

ya pointList iade veya iade için bir diziye dönüştürmek:

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

Sonra böyle her satırında kendisine ekleyebilirsiniz: Böyle while döngü önce ayarlayın.

İlgili konular