void operator () (const tbb::blocked_range<int>& range) const {
    
    for(int i = range.begin(); i != range.end(); i++) {
      
      Cluster* nearest = in_clusters[i]->findNearest(in_clusters);

      if(nearest->findNearest(in_clusters) == in_clusters[i]) {
        
        Cluster* cluster = new Cluster(nearest, in_clusters[i]);
        (*out_clusters)[i] = cluster;
        
      } else {
        
        (*out_clusters)[i] = in_clusters[i];  
        
      }
      
    }
    
  }
Cluster* AgglomerativeClustering::openMPStart() {
  
    while (this->clusters.size() != 1) {

      vector<Cluster*> clusters_aux (0);
      
      #pragma omp parallel for shared(clusters_aux)
      for (int i = 0; i < this->clusters.size(); i++) {

        Cluster* nearest = this->clusters[i]->findNearest(this->clusters);

        if(nearest->findNearest(this->clusters) == this->clusters[i]) {

          Cluster* cluster = new Cluster(nearest, this->clusters[i]);
          #pragma omp critical(dataupdate)
          {
            clusters_aux.push_back(cluster);
          }
        } else {
          
          #pragma omp critical(dataupdate)
          {
            clusters_aux.push_back(this->clusters[i]);  
          }
        }
        
      }
      
      
      #pragma omp barrier
      
      this->clusters = clusters_aux;

      this->removeRepetitions();

    }
  
  return this->clusters[0];
}
Cluster* AgglomerativeClustering::start () {
  
  while (this->clusters.size() != 1) {

    vector<Cluster*> clusters_aux (0);
    int i = 0;

    while (i < this->clusters.size()) {
      Cluster* nearest = this->clusters[i]->findNearest(this->clusters);

      if(nearest->findNearest(this->clusters) == this->clusters[i]) {
        
        
        Cluster* cluster = new Cluster(nearest, this->clusters[i]);
        
        if(!cluster->isThere(clusters_aux)) {
          
          clusters_aux.push_back(cluster);
          
        }
        
        
      } else {
        
        clusters_aux.push_back(clusters[i]);  
        
      }

      i++;
    }

    this->clusters = clusters_aux;
    
  }

  return this->clusters[0];

}
Cluster* AgglomerativeClustering::cilkStart() {
  
    while (this->clusters.size() != 1) {
  
      vector<Cluster*> clusters_aux (0);
      
      cilk_for(int i = 0; i < this->clusters.size(); i++) {

        Cluster* nearest = this->clusters[i]->findNearest(this->clusters);

        if(nearest->findNearest(this->clusters) == this->clusters[i]) {

          Cluster* cluster = new Cluster(nearest, this->clusters[i]);
          
          mutex.lock();
          clusters_aux.push_back(cluster);
          mutex.unlock();
          
        } else {
          
          mutex.lock();
          clusters_aux.push_back(this->clusters[i]);  
          mutex.unlock();
      
        }
        
      }

      this->clusters = clusters_aux;

      this->removeRepetitions();

    }
  
  return this->clusters[0];
}