private GASolution<int[]> algorithmRun() {
		GASolution<int[]> best = null;
		for (int iter = 0; iter < maxiter; iter++) {
			gBestChanged = false;
			evaluate();
//			for (int i = 0; i < popSize; i++) {
//				evaluator.evaluate(population.getSolAt(i));
//			}
			best = Collections.min(population.getSols());
			if (globalBest == null || best.compareTo(globalBest) < 0) {
				globalBest = best;
				gBestChanged = true;
			}
			if (Math.abs(globalBest.fitness) < minFit) {
				return globalBest;
			}
			if (gBestChanged) {
//				System.out.println((iter + 1) + ": " + best.fitness + " -> " + best.toString());
				System.out.println((iter + 1) + ": " + best.fitness);
			}
			List<GASolution<int[]>> newPop = new ArrayList<>(popSize);
			for (int i = 0; i < popSize; i++) {
				GASolution<int[]> parent1 = selection.select(population);
				GASolution<int[]> parent2 = selection.select(population);
				GASolution<int[]> child = crossover.cross(parent1, parent2);
				child = mutation.mutate(child);
				newPop.add(child);
			}
			population = new Population(newPop);
		}
		evaluate();
		best = Collections.min(population.getSols());
		if (best.compareTo(globalBest) < 0) {
			globalBest = best;
		}
		return globalBest;
	}