Program: 92540
Project: 92540
Buggy source:
/** 
 * Constructor. Clustering data with the number of clusters being automatically determined by X-Means algorithm.
 * @param data the input data of which each row is a sample.
 * @param kmax the maximum number of clusters.
 */
public XMeans(double[][] data,int kmax){
  if (kmax < 2) {
    throw new IllegalArgumentException("String_Node_Str" + kmax);
  }
  int n=data.length;
  int d=data[0].length;
  k=1;
  size=new int[k];
  size[0]=n;
  y=new int[n];
  centroids=new double[k][d];
  for (int i=0; i < n; i++) {
    for (int j=0; j < d; j++) {
      centroids[0][j]+=data[i][j];
    }
  }
  for (int j=0; j < d; j++) {
    centroids[0][j]/=n;
  }
  double[] wcss=new double[k];
  for (int i=0; i < n; i++) {
    wcss[0]+=Math.squaredDistance(data[i],centroids[0]);
  }
  distortion=wcss[0];
  logger.info(String.format("String_Node_Str",k,distortion));
  BBDTree bbd=new BBDTree(data);
  while (k < kmax) {
    ArrayList<double[]> centers=new ArrayList<>();
    double[] score=new double[k];
    KMeans[] kmeans=new KMeans[k];
    for (int i=0; i < k; i++) {
      if (size[i] < 25) {
        logger.info("String_Node_Str",i,size[i]);
        continue;
      }
      double[][] subset=new double[size[i]][];
      for (int j=0, l=0; j < n; j++) {
        if (y[j] == i) {
          subset[l++]=data[j];
        }
      }
      kmeans[i]=new KMeans(subset,2,100,4);
      double newBIC=bic(2,size[i],d,kmeans[i].distortion,kmeans[i].size);
      double oldBIC=bic(size[i],d,wcss[i]);
      score[i]=newBIC - oldBIC;
      logger.info(String.format("String_Node_Str",i,oldBIC,newBIC,score[i]));
    }
    int[] index=QuickSort.sort(score);
    for (int i=0; i < k; i++) {
      if (score[index[i]] <= 0.0) {
        centers.add(centroids[index[i]]);
      }
    }
    int m=centers.size();
    for (int i=k; --i >= 0; ) {
      if (score[i] > 0) {
        if (centers.size() + i - m + 1 < kmax) {
          logger.info("String_Node_Str",index[i]);
          centers.add(kmeans[index[i]].centroids[0]);
          centers.add(kmeans[index[i]].centroids[1]);
        }
 else {
          centers.add(centroids[index[i]]);
        }
      }
    }
    if (centers.size() == k) {
      break;
    }
    k=centers.size();
    double[][] sums=new double[k][d];
    size=new int[k];
    centroids=new double[k][];
    for (int i=0; i < k; i++) {
      centroids[i]=centers.get(i);
    }
    distortion=Double.MAX_VALUE;
    for (int iter=0; iter < 100; iter++) {
      double newDistortion=bbd.clustering(centroids,sums,size,y);
      for (int i=0; i < k; i++) {
        if (size[i] > 0) {
          for (int j=0; j < d; j++) {
            centroids[i][j]=sums[i][j] / size[i];
          }
        }
      }
      if (distortion <= newDistortion) {
        break;
      }
 else {
        distortion=newDistortion;
      }
    }
    wcss=new double[k];
    for (int i=0; i < n; i++) {
      wcss[y[i]]+=Math.squaredDistance(data[i],centroids[y[i]]);
    }
    logger.info(String.format("String_Node_Str",k,distortion));
  }
}

Fixed version (ground truth):
/** 
 * Constructor. Clustering data with the number of clusters being automatically determined by X-Means algorithm.
 * @param data the input data of which each row is a sample.
 * @param kmax the maximum number of clusters.
 */
public XMeans(double[][] data,int kmax){
  if (kmax < 2) {
    throw new IllegalArgumentException("String_Node_Str" + kmax);
  }
  int n=data.length;
  int d=data[0].length;
  k=1;
  size=new int[k];
  size[0]=n;
  y=new int[n];
  centroids=new double[k][d];
  for (int i=0; i < n; i++) {
    for (int j=0; j < d; j++) {
      centroids[0][j]+=data[i][j];
    }
  }
  for (int j=0; j < d; j++) {
    centroids[0][j]/=n;
  }
  double[] wcss=new double[k];
  for (int i=0; i < n; i++) {
    wcss[0]+=Math.squaredDistance(data[i],centroids[0]);
  }
  distortion=wcss[0];
  logger.info(String.format("String_Node_Str",k,distortion));
  BBDTree bbd=new BBDTree(data);
  while (k < kmax) {
    ArrayList<double[]> centers=new ArrayList<>();
    double[] score=new double[k];
    KMeans[] kmeans=new KMeans[k];
    for (int i=0; i < k; i++) {
      if (size[i] < 25) {
        logger.info("String_Node_Str",i,size[i]);
        continue;
      }
      double[][] subset=new double[size[i]][];
      for (int j=0, l=0; j < n; j++) {
        if (y[j] == i) {
          subset[l++]=data[j];
        }
      }
      kmeans[i]=new KMeans(subset,2,100,4);
      double newBIC=bic(2,size[i],d,kmeans[i].distortion,kmeans[i].size);
      double oldBIC=bic(size[i],d,wcss[i]);
      score[i]=newBIC - oldBIC;
      logger.info(String.format("String_Node_Str",i,oldBIC,newBIC,score[i]));
    }
    int[] index=QuickSort.sort(score);
    for (int i=0; i < k; i++) {
      if (score[i] <= 0.0) {
        centers.add(centroids[index[i]]);
      }
    }
    int m=centers.size();
    for (int i=k; --i >= 0; ) {
      if (score[i] > 0) {
        if (centers.size() + i - m + 1 < kmax) {
          logger.info("String_Node_Str",index[i]);
          centers.add(kmeans[index[i]].centroids[0]);
          centers.add(kmeans[index[i]].centroids[1]);
        }
 else {
          centers.add(centroids[index[i]]);
        }
      }
    }
    if (centers.size() == k) {
      break;
    }
    k=centers.size();
    double[][] sums=new double[k][d];
    size=new int[k];
    centroids=new double[k][];
    for (int i=0; i < k; i++) {
      centroids[i]=centers.get(i);
    }
    distortion=Double.MAX_VALUE;
    for (int iter=0; iter < 100; iter++) {
      double newDistortion=bbd.clustering(centroids,sums,size,y);
      for (int i=0; i < k; i++) {
        if (size[i] > 0) {
          for (int j=0; j < d; j++) {
            centroids[i][j]=sums[i][j] / size[i];
          }
        }
      }
      if (distortion <= newDistortion) {
        break;
      }
 else {
        distortion=newDistortion;
      }
    }
    wcss=new double[k];
    for (int i=0; i < n; i++) {
      wcss[y[i]]+=Math.squaredDistance(data[i],centroids[y[i]]);
    }
    logger.info(String.format("String_Node_Str",k,distortion));
  }
}