def run_swarm_process(self):
        # First we find the combination of creature that cover the space the more thoroughly.
        # To achieve that, we use KMEANS with k=2 on the list of creature position.
        kmeans = KMeans(n_clusters=2)

        swarm_positions = self._swarm.get_list_position()  # Get the list of point in the space for KMeans
        # Normalize the dimension of each point so the point chosen is irrelevant of the possible different unities
        # of each dimensions

        normalized_swarm_position = np.array(swarm_positions) / np.array(self._bound_distance)
        kmeans.fit(normalized_swarm_position)  # Train KMeans
        centers = kmeans.cluster_centers_  # Get the centers
        centers *= self._bound_distance  # Go back to the original dimension
        print "Centers: ", centers

        # Add two new creatures with their position corresponding to the centers of kmeans.
        creature0_position = centers[0]
        creature0_fitness = FitnessFunction.calculate_fitness(self._fitness_function, creature0_position,
                                                              self._number_of_dimensions)
        self._number_of_real_evaluation -= 1  # Did a real evaluation

        creature1_position = centers[1]
        creature1_fitness = FitnessFunction.calculate_fitness(self._fitness_function, creature1_position,
                                                              self._number_of_dimensions)
        self._number_of_real_evaluation -= 1  # Did a real evaluation

        self._swarm.add_creature_to_swarm(position=creature0_position)
        self._swarm.add_creature_to_swarm(position=creature1_position)

        # Add the creatures position and fitness to the list of position and fitness evaluated
        self._list_real_evaluation_position.append(creature0_position)
        self._list_real_evaluation_fitness.append(creature0_fitness)
        self._list_real_evaluation_position.append(creature1_position)
        self._list_real_evaluation_fitness.append(creature1_fitness)

        # Train the regressor
        self._regressor.train_regressor(self._list_real_evaluation_position, self._list_real_evaluation_fitness)

        # From here, we alternate between exploration and exploitation randomly based on an heuristic except for the
        # Very first pass where we for the algorithm to be in exploration mode for one more evaluation
        # (3 evaluations total)
        self.exploration()
        self._number_of_real_evaluation -= 1  # Did a real evaluation

        # Now that we have three points evaluated, we are ready to start the algorithm for the requested amount of real
        # evaluations. Or until the user stop the program
        for generation in range(self._number_of_real_evaluation):
            print self._list_real_evaluation_position
            print self._list_real_evaluation_fitness
            print self._fitness_before_real_evalutation
            # Decide if we explore or exploite.
            exploitation_threshold = max(0.2, 1/math.sqrt((generation+2)/2))
            exploitation_threshold = 0.0
            if self._random.rand() < exploitation_threshold:
                best_creature_ever = self.exploration()

                # TODO once the exploitation algorithm is finish. Remove the if/else and move this block after
                # We are almost done with this generation, get the real value of the point of interest found
                new_point_to_add_fitness = FitnessFunction.calculate_fitness(self._fitness_function,
                                                                             best_creature_ever.get_position(),
                                                                             self._number_of_dimensions)
                # Finish the generation by adding the new creature to the list and updating the regressor
                self._list_real_evaluation_position.append(best_creature_ever.get_position())
                self._list_real_evaluation_fitness.append(new_point_to_add_fitness)

                self._fitness_before_real_evalutation.append(self._regressor.get_estimation_fitness_value(best_creature_ever.get_position())[0])
                choose_kernel = False
                if len(self._list_real_evaluation_fitness) % 10 == 0:
                    choose_kernel = True
                self._regressor.train_regressor(self._list_real_evaluation_position,
                                                self._list_real_evaluation_fitness, choose_kernel=choose_kernel)
                print "Smallest point found: ", new_point_to_add_fitness, "Fitness found by the PSO:", \
                    best_creature_ever.get_fitness(), " At position: ", best_creature_ever.get_position()
                # Reset swarm fitness
                self._swarm.reset_swarm()
            else:
                best_creature_ever = self.exploitation()


        index = self._list_real_evaluation_fitness.index(min(self._list_real_evaluation_fitness))
        print "Smallest point found: ", self._list_real_evaluation_fitness[index], " At position: ", \
            self._list_real_evaluation_position[index]