public void assignClusterClass(Cluster cluster) {
    List<String> classString = cluster.getColumnAtString(cluster.getAttributes().size() - 1);

    Set<String> set = new TreeSet<>();

    for (String str : classString) {
      set.add(str);
    }

    String name = null;
    try {
      name = set.toArray(new String[0])[0];
    } catch (ArrayIndexOutOfBoundsException ae) {
      TrainingLog.mainLogs.info("Array index out of bounds excepiton");
      cluster.setClassName(Notations.DEFAULT_CLASS);
      return;
    }
    int count = CommonLogics.numberOfInstance(classString, name);

    Iterator<String> iter = set.iterator();

    while (iter.hasNext()) {
      String temp = iter.next();
      int cct = CommonLogics.numberOfInstance(classString, temp);

      if (cct > count) {
        name = temp;
        count = cct;
      }
    }

    cluster.setClassName(name);
  }
  public List<String[]> findPoints(Cluster data, List<AttributeCluster> attrbs) {
    List<String[]> list = new ArrayList<String[]>();
    for (int i = 0; i < data.size(); i++) {
      list.add(getPoints(attrbs, data.getRecords().get(i)));
    }

    return list;
  }
  public double findEucleideanDistance(String[] p1, Cluster cluster) {
    double sum = 0.0;
    for (int i = 0; i < cluster.size(); i++) {
      sum += findEucleideanDistance(p1, cluster.getRecordPointsAt(i));
    }

    return sum;
  }
 /**
  * Finds all the pairs of eucleidean distances between cluster 1 and cluster 2
  *
  * @param cluster 1
  * @param cluster 2
  * @return list of all distances
  */
 public List<Double> findAllEucleideanDistances(Cluster cl1, Cluster cl2) {
   List<Double> values = new ArrayList<Double>();
   for (int i = 0; i < cl1.size(); i++) {
     for (int j = 0; j < cl2.size(); j++) {
       values.add(findEucleideanDistance(cl1.getRecordPointsAt(i), cl2.getRecordPointsAt(j)));
     }
   }
   return values;
 }
  private void alterCentroid(Cluster cluster, List<AttributeCluster> attrb) {
    if (cluster.size() > 0) {
      List<Double> attr = new ArrayList<>();
      for (int i = 0; i < attrb.size(); i++) {
        if (attrb.get(i).getType() == TypeAttribute.continuous) {
          List<Double> mean = cluster.getColumnAt(i);
          attr.add(new CommonLogics().mean(mean));
        }
      }

      cluster.setCentroid(new Centroid(attr));
    }
  }
  /**
   * Calculates SSE
   *
   * @param cluster
   */
  public void calculateSSEForCluster(Cluster cluster) {
    double SSE = 0.0;

    for (int i = 0; i < cluster.size(); i++) {
      double temp =
          findEucleideanDistance(
              cluster.getCentroid().getAttrList(),
              getPoints(cluster.getAttributes(), cluster.getRecords().get(i)));

      SSE += temp * temp;
    }

    cluster.setSSE(SSE);
  }
  public void recomputingCentroids(BisectCluster bisect, Cluster data) {
    CluseterList list = new CluseterList();
    list.addCluster(bisect.getC1());
    list.addCluster(bisect.getC2());

    for (int i = 0; i < list.size(); i++) {
      alterCentroid(list.getClusterAt(i), data.getAttributes());
    }
  }
  /**
   * Add points from cluster to Bisect Cluster data model
   *
   * @param bisect
   * @param data
   */
  public void addClusterPoints(BisectCluster bisect, Cluster data) {
    CluseterList list = new CluseterList();
    list.addCluster(bisect.getC1());
    list.addCluster(bisect.getC2());

    list.clearsClusterPoints();

    for (int i = 0; i < data.size(); i++) {
      int temp =
          findClosestClusterAndAddPoint(
              list, getPoints(data.getAttributes(), data.getRecords().get(i)));

      list.getClusterAt(temp).addPoints(data.getRecords().get(i));
    }

    calculateSSEForCluster(bisect.getC1());
    //	System.out.println(bisect.getC1().getSSE());
    calculateSSEForCluster(bisect.getC2());

    bisect.setTotalSSE(bisect.getC1().getSSE() + bisect.getC2().getSSE());
  }
  /**
   * Bisects a cluster to give two cluster in a list
   *
   * @param cluster
   * @return
   * @throws CloneNotSupportedException
   */
  public List<Cluster> bisectCluster(Cluster cluster) throws CloneNotSupportedException {
    Cluster c1 =
        new Cluster(new CommonLogics().generateRandomNumbers(1, cluster.numberOfPoints()), 0);

    Cluster c2 =
        new Cluster(new CommonLogics().generateRandomNumbers(1, cluster.numberOfPoints()), 0);

    c1.setAttributes(cluster.getAttributes());
    c2.setAttributes(cluster.getAttributes());

    BisectClusterList blist = new BisectClusterList();

    BisectCluster bisect = new BisectCluster(c1.clone(), c2.clone());

    addClusterPoints(bisect, cluster);
    blist.addBisectCluster(bisect);

    for (int i = 0; i < ValueConstants.TRIALS; i++) {
      Cluster cc1 = bisect.getC1().clone();
      Cluster cc2 = bisect.getC2().clone();

      BisectCluster bisectt = new BisectCluster(cc1, cc2);

      recomputingCentroids(bisectt, cluster);

      addClusterPoints(bisectt, cluster);
      blist.addBisectCluster(bisectt);
      //	blist.getBisectList().get(i).setTotalSSE(bisectt.getC1().getSSE()+bisectt.getC2().getSSE());

    }

    int lowest = 0;

    for (int i = 0; i < blist.size(); i++) {
      if (blist.SSEat(i) < blist.SSEat(lowest)) {
        lowest = i;
      }
    }

    CluseterList clist = new CluseterList();
    clist.addCluster(blist.getBisectList().get(lowest).getC1());
    clist.addCluster(blist.getBisectList().get(lowest).getC2());

    return clist.getClusters();
  }