Wir versuchen derzeit, den Kmeans-Algorithmus in Java zu implementieren. Unser Problem ist das:Nach einer while-Schleife: Warum ist ein Array, das gerade leer geschrieben wurde?
Wir verwenden die getData()
Methode, um ein zweidimensionales Array mit Daten aus einer Datei zu füllen. Innerhalb der While-Schleife in der getData()
Methode haben wir eine println()
und wir haben eine andere direkt vor dem Rückkehr-Befehl.
Die erste println()
gibt uns die richtigen Werte, die wir gerade von der Datei erhalten haben.
Die zweite println()
gibt uns nur 0.0
für jedes Feld in diesem Array, mit Ausnahme von arrayList[299][0]
.
Warum ist das?
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];
}
}
}
'pointArray = neue Doppel [i] [4];' - was versuchst du hier zu tun? Sie setzen die Array-Variable in jeder Iteration zurück. – Eran
Die Idee ist, die Größe des Arrays abhängig von der Größe der Daten, die wir aus der Datei erhalten, dynamisch zu skalieren. – user2765654
Das funktioniert nicht so. Besser eine Liste verwenden. – Fildor