int 
Clusters::
reclusterNeyEssen()
{
  cerr << "Calculating MLE for prior probabilities" << endl;
  vector<double> prior(numberClasses,0.0l);
  double xxx = 1.0l/(double)numberTypes;
  for (int i = 0; i < numberTypes; i++){
    int c = classVector[i];
    prior[c] += xxx;
  }
  for (int i = 0; i < numberClasses;i++)
    cerr << i << " " << prior[i] << endl;
  if (numberStates > 0){
    cerr << "Training all the HMMs" << endl;
    for (int c = 0; c < numberClasses; c++){
      //      cerr << "Training HMM " << c << endl;
      HMM* hmmPtr = hmms[c];
      HMM* newHmmPtr = new HMM(numberStates, alphabetSize);
      for (int i = 0; i < numberTypes; i++){
	if (classVector[i] == c){
	  // then this word is in the right class
	  // so train it on word i
	  const string & word = *(corpus.wordArray[i]);
	  vector<int> v;
	  hmmPtr->convertString(word,v);
	  // FIXME 
	  double weight = 1.0l;
	  if (USE_TRUE_WEIGHT){
	    weight = corpus.countArray[i];
	  }
	  hmmPtr->emSingle(*newHmmPtr, weight, v);
	}
      }
      newHmmPtr->normalise();
      hmms[c] = newHmmPtr;
      delete hmmPtr;
    }
  }
  int something = 0;
  for (int i = 0; i < numberTypes; i++){
    //    cerr << "Word " << i;
    int w = sortedWords[i];
    //cerr << *(corpus.wordArray[w]) << endl;
    if (counts[w] > FREQ_CUTOFF){
      //cerr << "Doing " << w << endl;
      if (bestCluster(w, prior)){
	something++;
      }
    }
  }
 
  return something;
}
/**
 * Ejecuta la metaheurística con los datos dados.
 *
 * @param type Si se utilizará una función objetivo de
 *             maximización o de minimización.
 */
void Kmeans::run(int type){
    int i;

    ////////////////////////////
    // Inicializaciones.

    //Inicializaciones del mejor según el tipo de problema.
    float best;
    if(initialized){
        switch(type){
            case T_MAX:
                //Maximización.
                best = 0.0;
                break;
            default:
                //Minimización.
                best = numeric_limits<float>::infinity();
        }
    }else{
        best = bestFO;
    }
    int count   = 0;

    ////////////////////////////
    // Algoritmo K-means.

    while(count < REPS){
        //////////////////////////////
        // Reasignación y evaluación.

        //Asignar elementos a cada cluster.
        for(i = 0; i < N; ++i)
            solution[0][i] = bestCluster(0, i);

        //Renombra los clusters y recalcula los centroides.
        renamer(0, &Ks[0], size);
        //Evalua la función objetivo.
        switch(type){
            case T_MAX:
                of[0] = foMax(0, Ks[0], metric);
                break;
            default:
                of[0] = foMin(0, Ks[0], metric);
        }

        ////////////////////////////
        // Actualización del mejor.
        updateBetter(0, &best, &count, type);
    }

}