private void merge(Relation<V> relation,List<ORCLUSCluster> clusters,int k_new,int d_new,IndefiniteProgress cprogress){
  ArrayList<ProjectedEnergy> projectedEnergies=new ArrayList<>((clusters.size() * (clusters.size() - 1)) >>> 1);
  for (int i=0; i < clusters.size(); i++) {
    for (int j=i + 1; j < clusters.size(); j++) {
      ORCLUSCluster c_i=clusters.get(i);
      ORCLUSCluster c_j=clusters.get(j);
      projectedEnergies.add(projectedEnergy(relation,c_i,c_j,i,j,d_new));
    }
  }
  while (clusters.size() > k_new) {
    if (cprogress != null) {
      cprogress.setProcessed(clusters.size(),LOG);
    }
    ProjectedEnergy minPE=Collections.min(projectedEnergies);
    for (int c=0; c < clusters.size(); c++) {
      if (c == minPE.i) {
        clusters.remove(c);
        clusters.add(c,minPE.cluster);
      }
      if (c == minPE.j) {
        clusters.remove(c);
      }
    }
    int i=minPE.i, j=minPE.j;
    for (Iterator<ProjectedEnergy> it=projectedEnergies.iterator(); it.hasNext(); ) {
      ProjectedEnergy pe=it.next();
      if (pe.i == i || pe.i == j || pe.j == i || pe.j == j) {
        it.remove();
      }
 else {
        if (pe.i > j) {
          pe.i-=1;
        }
        if (pe.j > j) {
          pe.j-=1;
        }
      }
    }
    ORCLUSCluster c_ij=minPE.cluster;
    for (int c=0; c < clusters.size(); c++) {
      if (c < i) {
        projectedEnergies.add(projectedEnergy(relation,clusters.get(c),c_ij,c,i,d_new));
      }
 else       if (c > i) {
        projectedEnergies.add(projectedEnergy(relation,clusters.get(c),c_ij,i,c,d_new));
      }
    }
  }
}

private void merge ( Relation < V > relation , List < ORCLUSCluster > clusters , int k_new , int d_new , IndefiniteProgress cprogress ) { ArrayList < ProjectedEnergy > projectedEnergies = new ArrayList < > ( ( clusters . size ( ) * ( clusters . size ( ) - 1 ) ) > > > 1 ) ; for ( int i = 0 ; i < clusters . size ( ) ; i ++ ) { for ( int j = i + 1 ; j < clusters . size ( ) ; j ++ ) { ORCLUSCluster c_i = clusters . get ( i ) ; ORCLUSCluster c_j = clusters . get ( j ) ; projectedEnergies . add ( projectedEnergy ( relation , c_i , c_j , i , j , d_new ) ) ; } } while ( clusters . size ( ) > k_new ) { if ( cprogress != null ) { cprogress . setProcessed ( clusters . size ( ) , LOG ) ; } ProjectedEnergy minPE = Collections . min ( projectedEnergies ) ; for ( int c = 0 ; c < clusters . size ( ) ; c ++ ) { if ( c == minPE . i ) { clusters . remove ( c ) ; clusters . add ( c , minPE . cluster ) ; } if ( c == minPE . j ) { clusters . remove ( c ) ; } } int i = minPE . i , j = minPE . j ; for ( Iterator < ProjectedEnergy > it = projectedEnergies . iterator ( ) ; it . hasNext ( ) ; ) { ProjectedEnergy pe = it . next ( ) ; if ( pe . i == i || pe . i == j || pe . j == i || pe . j == j ) { it . remove ( ) ; } else { if ( pe . i > j ) { pe . i -= 1 ; } if ( pe . j > j ) { pe . j -= 1 ; } } } ORCLUSCluster c_ij = minPE . cluster ; for ( int c = 0 ; c < clusters . size ( ) ; c ++ ) { if ( c < i ) { projectedEnergies . add ( projectedEnergy ( relation , clusters . get ( c ) , c_ij , c , i , d_new ) ) ; } else if ( c > i ) { projectedEnergies . add ( projectedEnergy ( relation , clusters . get ( c ) , c_ij , i , c , d_new ) ) ; } } } }
reduces the number of seeds to k_new
