<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">package optimizer.engine;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import optimizer.Coordenada;
import optimizer.Cromossomo;
import optimizer.DistanceMatrix;
import optimizer.Gene;
import optimizer.crossover.CrossoverContext;
import optimizer.crossover.Cycle;
import optimizer.fitness.FitnessCalculator;
import optimizer.selection.Ranking;
import optimizer.selection.SelectionContext;
import app.model.GoogleDistanceMatrixObject;

public class OptimizerEngine {
	
	private GoogleDistanceMatrixObject matrix;
	private List&lt;Cromossomo&gt; populacao;
	private SelectionContext fitnessContext = new SelectionContext(new Ranking());
	private CrossoverContext crossoverContext = new CrossoverContext(new Cycle());

	public Cromossomo minimizeRoute(List&lt;Coordenada&gt; coordenadas, int popInicial, int geracoes, int fitness_amount) {
		preprocessa(coordenadas);
		populacao = geraPopulacaoInicial(popInicial);
		for(int i=0;i&lt;geracoes;i++) {
			evaluateFitness();
			List&lt;Cromossomo&gt; fittest = selectsTheFittestUsing(fitnessContext, fitness_amount);
			populacao = crossover(crossoverContext, fittest);
			Collections.sort(populacao, Collections.reverseOrder());
			System.out.println(populacao.get(0).getInfoOfAllGenes() + " " + 1/populacao.get(0).getFitness());
		}
		Collections.sort(populacao, Collections.reverseOrder());
		return populacao.get(0);
	}
	
	public List&lt;Cromossomo&gt; minimizeRouteUsingPopularity(List&lt;Coordenada&gt; coordenadas, int popInicial, float popularity_rate, int fitness_amount) {
		
		preprocessa(coordenadas);
		populacao = geraPopulacaoInicial(popInicial);
		Collections.sort(populacao, Collections.reverseOrder());
		
		while((float) Collections.frequency(populacao, populacao.get(0))/populacao.size() &lt; popularity_rate) {
			evaluateFitness();
			List&lt;Cromossomo&gt; fittest = selectsTheFittestUsing(fitnessContext, fitness_amount);
			System.out.println(fittest.get(0).getInfoOfAllGenes() + " " + fittest.get(0).getFitness());
			populacao = crossover(crossoverContext, fittest);
		}
		return populacao;
	}
	
	private void preprocessa(List&lt;Coordenada&gt; coordenadas) {
		this.matrix = new DistanceMatrix(coordenadas).getDistanceMatrix();
	}

	private List&lt;Cromossomo&gt; geraPopulacaoInicial(int n) {
		int dimension = matrix.getDimension();
		List&lt;Gene&gt; genes = geneListWithSize(dimension);

		List&lt;Cromossomo&gt; populacao = new ArrayList&lt;Cromossomo&gt;();
		
		for (int i=0; i&lt;n; i++) {
			List&lt;Gene&gt; copy = new ArrayList&lt;Gene&gt;(genes);
			Collections.shuffle(copy);
			populacao.add(new Cromossomo(copy));
		}
		return populacao;
	}
	
	private void evaluateFitness() {
		for (Cromossomo cromossomo : populacao) {
			new FitnessCalculator(cromossomo, matrix).calculateTotalDistance();
		}
	}
	
	private List&lt;Cromossomo&gt; selectsTheFittestUsing(SelectionContext context, int amount) {
		return context.select(amount, populacao);
	}
	
	private List&lt;Cromossomo&gt; crossover(CrossoverContext context, List&lt;Cromossomo&gt; from) {
		Collections.shuffle(from);
		List&lt;Cromossomo&gt; born = new ArrayList&lt;Cromossomo&gt;();
		
		for(int i=0,j=from.size()-1; i&lt;j; i++, j--) {
			Cromossomo dad = from.get(i);
			Cromossomo mom = from.get(j);
			List&lt;Cromossomo&gt; children = context.cross(dad, mom);
			born.add(children.get(0));
			born.add(children.get(1));
		}
		from.addAll(born);
		return from;
	}
	
	private List&lt;Gene&gt; geneListWithSize(int dimension) {
		List&lt;Gene&gt; genes = new ArrayList&lt;Gene&gt;();
		for(int i=0; i&lt;dimension; i++) {
			Gene gene = new Gene(i, false); //verificar se o gene inicia uma rota.
			genes.add(gene);
		}
		return genes;
	}
}
</pre></body></html>