package algoritmosGeneticos;
import java.util.ArrayList;
import java.util.Random;
import estrutura.Caminho;
import estrutura.Grafo;
import estrutura.No;
//Esssa classe � respons�vel por fazer o controle da execu��o do algoritmo.
public class Controle {
//Atributos da classe Controle
private Grafo grafo = null;
private ArrayList<Caminho> geracao = null;
private ArrayList<Caminho> pais = null;
Random r = new Random();
int k=0;
//M�todo que define a primeira gera��o de caminhos.
public void criaPrimeiraGeracao(){
Caminho c1 = new Caminho();
Caminho c2 = new Caminho();
Caminho c3 = new Caminho();
Caminho c4 = new Caminho();
Caminho c5 = new Caminho();
Caminho c6 = new Caminho();
//caminhos que compoem a primeira gera��o;
c1.getCaminho().add(4); c1.getCaminho().add(3); c1.getCaminho().add(2); c1.getCaminho().add(1);
c1.getCaminho().add(5); c1.getCaminho().add(4); c1.setAptidaoAbsoluta(22); //0
c2.getCaminho().add(1); c2.getCaminho().add(2); c2.getCaminho().add(3); c2.getCaminho().add(4);
c2.getCaminho().add(5); c2.getCaminho().add(1); c2.setAptidaoAbsoluta(22); //1
c3.getCaminho().add(2); c3.getCaminho().add(1); c3.getCaminho().add(5); c3.getCaminho().add(4);
c3.getCaminho().add(3); c3.getCaminho().add(2); c3.setAptidaoAbsoluta(22); //2
c4.getCaminho().add(3); c4.getCaminho().add(4); c4.getCaminho().add(5); c4.getCaminho().add(1);
c4.getCaminho().add(2); c4.getCaminho().add(3); c4.setAptidaoAbsoluta(22); //3
c5.getCaminho().add(5); c5.getCaminho().add(4); c5.getCaminho().add(3); c5.getCaminho().add(2);
c5.getCaminho().add(1); c5.getCaminho().add(5); c5.setAptidaoAbsoluta(22); //4
c6.getCaminho().add(1); c6.getCaminho().add(5); c6.getCaminho().add(3); c6.getCaminho().add(4);
c6.getCaminho().add(2); c6.getCaminho().add(1); c6.setAptidaoAbsoluta(22); //5
System.out.println("Teste");
geracao.add(c1); geracao.add(c2); geracao.add(c3); geracao.add(c4); geracao.add(c5); geracao.add(c6);
}
//Imprime os elementos que est�o contidos na gera��o atual
public void imprimirGeracaoInicial(){
for (int r=0; r<geracao.size(); r++){
System.out.println(geracao.get(r).getCaminho());
}
}
//Fun��o que testa se um determinado caminho � valido.
public boolean validaCaminho(Caminho c){
ArrayList<Integer> caminhos = new ArrayList<Integer>();
int cont = 0;
for(int i = 0; i < c.getCaminho().size()-1; i++){
No aux1 = grafo.buscaNo(c.getCaminho().get(i)); //V�rtice N
No aux2 = grafo.buscaNo(c.getCaminho().get(i+1)); //V�rtices N+100
for(int j = 0; j < aux1.getVizinhos().size(); j++){
if(aux2.getValor() == aux1.getVizinhos().get(j).getValor() && !caminhos.contains(aux2.getValor())){
cont++;
caminhos.add(aux2.getValor());
break;
}
}
}
if(cont == (c.getCaminho().size()-1)){
return true;
}
return false;
}
public void mutacao(Caminho c){
while (true){
int r3 = r.nextInt(6);
int r4 = r.nextInt(6);
while (r3 == r4 || r3 == 0 || r4 == 0 || r3 == 5 || r4 == 5){
r3 = r.nextInt(6);
r4 = r.nextInt(6);
}
int aux = c.getCaminho().get(r3);
c.getCaminho().set(r3, c.getCaminho().get(r4));
c.getCaminho().set(r4, aux);
if (validaCaminho(c) == true){
calculaPeso(c);
geracao.add(c);
break;
}
}
}
//Fun��o que calcula a soma dos pesos das arestas de um caminho.
public void calculaPeso(Caminho c){
for(int i = 0; i < c.getCaminho().size()-1; i++){
No no1 = grafo.buscaNo(c.getCaminho().get(i)); //N� n pertencente ao caminho
No no2 = grafo.buscaNo(c.getCaminho().get(i+1)); //No n+1 pertencente ao caminho
for(int j = 0; j < no1.getVizinhos().size(); j++){ //Procura os vizinhos do n-�simo n�
if(no1.getVizinhos().get(j).getValor() == no2.getValor()){ //testa se o valor do n+1-�simo n� est� entre as arestas do n-�simo n�
c.setAptidaoAbsoluta(c.getAptidaoAbsoluta()+no1.getVizinhos().get(j).getPeso());
}
}
}
//Final do caminho ligando ao seu in�cio
No aux1 = grafo.buscaNo(c.getCaminho().get(c.getCaminho().size()-1));
No aux2 = grafo.buscaNo(c.getCaminho().get(0));
//Fecha o ciclo do caminho. Isso n�o � feito nos comandos acima.
for(int j = 0; j < aux1.getVizinhos().size(); j++){ //Procura os vizinhos do n-�simo n�
if(aux2.getValor() == aux1.getVizinhos().get(j).getValor()){ //testa se o valor do n+1-�simo n� est� entre as arestas do n-�simo n�
c.setAptidaoAbsoluta(c.getAptidaoAbsoluta()+aux1.getVizinhos().get(j).getPeso());
break;
}
}
}
//Construtor padr�o da classe Controle
public Controle(){
grafo = new Grafo();
geracao = new ArrayList<Caminho>();
pais = new ArrayList<Caminho>();
grafo.criarNos();
grafo.criaArestas();
criaPrimeiraGeracao();
}
//Sorteio dos cromossomos para forma��o da pr�xima gera��o.
public void roleta(){
int totalPessos = 0;
for(Caminho c : geracao){
totalPessos += c.getAptidaoAbsoluta();
}
calculaAptidaoRelativa(totalPessos);
// lista dos caminhos selecionados
ArrayList<Caminho> listaCaminhos = new ArrayList<Caminho>();
for(int i = 0; i < geracao.size(); i++){
int selecionado = r.nextInt(9999);
// quando a lista esta vazia adiciona o elemento selecionado
if(listaCaminhos.size() == 0){
listaCaminhos.add(retornaCaminho(selecionado));
}
// verifica se o elemento anterior � diferente ao selecionado
// se for adiciona na lista
else if(retornaCaminho(selecionado) != listaCaminhos.get(i - 1)){
listaCaminhos.add(retornaCaminho(selecionado));
}
// se o elemento selecionado for igual ao anterior � selecionado um novo elemento
else{
while( retornaCaminho(selecionado) == listaCaminhos.get(i - 1)){
selecionado = r.nextInt(9999);
}
listaCaminhos.add(retornaCaminho(selecionado));
}
}
pais.clear();
// seta a lista dos caminhos selecionados na roleta na variavel pais
pais.addAll(listaCaminhos);
for (int r=0; r<pais.size(); r++){
System.out.println(pais.get(r).getCaminho());
}
this.geracao.clear();
}
public void SUS(){
int totalPessos = 0;
for(Caminho c : geracao){
totalPessos += c.getAptidaoAbsoluta();
}
// lista dos caminhos selecionados
ArrayList<Caminho> listaCaminhos = new ArrayList<Caminho>();
calculaAptidaoRelativa(totalPessos);
int selecionado = r.nextInt(9999);
int valorSalto = 10000 / geracao.size();
listaCaminhos.add(retornaCaminho(selecionado));
while (listaCaminhos.size() < geracao.size()){
selecionado += valorSalto;
if(selecionado > 9999){
selecionado -= 9999;
listaCaminhos.add(retornaCaminho(selecionado));
}
else{
listaCaminhos.add(retornaCaminho(selecionado));
}
}
pais.clear();
// seta a lista dos caminhos selecionados na roleta na variavel pais
pais.addAll(listaCaminhos);
for (int r=0; r<pais.size(); r++){
System.out.println(pais.get(r).getCaminho());
}
this.geracao.clear();
}
//Disputa dos cromosssomos para forma��o da pr�xima gera��o.
public void torneio(){
pais.clear();
while (this.pais.size() != 6){
int r1 = r.nextInt(6);
int r2 = r.nextInt(6);
while(r1 == r2){
r1 = r.nextInt(6); //0-3
r2 = r.nextInt(6); //0-3
}
// System.out.println(r1);
// System.out.println(r2);
if (this.geracao.get(r1).getAptidaoAbsoluta() == this.geracao.get(r2).getAptidaoAbsoluta()){
if (pais.contains(this.geracao.get(r1))){
pais.add(this.geracao.get(r2));
}
else {
pais.add(this.geracao.get(r1));
}
}
else {
if (this.geracao.get(r1).getAptidaoAbsoluta() < this.geracao.get(r2).getAptidaoAbsoluta()){
pais.add(this.geracao.get(r1));
}
else {
pais.add(this.geracao.get(r2));
}
}
}
//System.out.println("PAIS");
for (int r=0; r<pais.size(); r++){
System.out.println(pais.get(r).getCaminho());
}
this.geracao.clear();
}
public void crossover(){
for (int m=0; m<pais.size(); m=m+2){
ArrayList<Integer> mapeamento1 = new ArrayList<Integer>();
ArrayList<Integer> mapeamento2 = new ArrayList<Integer>();
Caminho filho1 = new Caminho();
Caminho filho2 = new Caminho();
for(int q=0; q<6; q++){
filho1.getCaminho().add(0);
filho2.getCaminho().add(0);
}
filho1.getCaminho().set(1, pais.get(m+1).getCaminho().get(2));
filho1.getCaminho().set(1, pais.get(m+1).getCaminho().get(3));
filho2.getCaminho().set(2, pais.get(m).getCaminho().get(2));
filho2.getCaminho().set(2, pais.get(m).getCaminho().get(3));
mapeamento1.add(pais.get(m).getCaminho().get(2));
mapeamento1.add(pais.get(m+1).getCaminho().get(2));
mapeamento2.add(pais.get(m).getCaminho().get(3));
mapeamento2.add(pais.get(m+1).getCaminho().get(3));
for (int n=0; n<6; n++){
if (n != 2 || n != 3){
if(!(mapeamento1.contains(pais.get(m).getCaminho().get(n)))){
filho1.getCaminho().set(n, pais.get(m).getCaminho().get(n));
filho2.getCaminho().set(n, pais.get(m+1).getCaminho().get(n));
}
else {
int index = mapeamento1.indexOf(pais.get(m).getCaminho().get(n));
if ((index % 2) == 0){
filho1.getCaminho().set(n, mapeamento1.get(index+1));
}
else{
filho1.getCaminho().set(n, mapeamento1.get(index-1));
}
}
}
}
for (int p=0; p<6; p++){
if (p != 2 || p != 3){
if(!(mapeamento2.contains(pais.get(m+1).getCaminho().get(p)))){
filho2.getCaminho().set(p, pais.get(m+1).getCaminho().get(p));
}
else {
int index = mapeamento2.indexOf(pais.get(m+1).getCaminho().get(p));
if ((index % 2) == 0){
filho2.getCaminho().set(p, mapeamento2.get(index+1));
}
else{
filho2.getCaminho().set(p, mapeamento2.get(index-1));
}
}
}
}
// System.out.println("FILHO "+m);
// System.out.println(filho1.getCaminho());
// System.out.println("FILHO "+(m+1));
// System.out.println(filho2.getCaminho());
if(validaCaminho(filho1) == true){
calculaPeso(filho1);
geracao.add(filho1);
}
else{
this.mutacao(filho1);
}
if(validaCaminho(filho2) == true){
calculaPeso(filho2);
geracao.add(filho2);
}
else{
this.mutacao(filho2);
}
}
//System.out.println("NOVA GERA��O");
imprimirGeracao();
System.out.println("\n");
k++;
}
//Imprime os elementos que est�o contidos na gera��o atual
public void imprimirGeracao(){
for (int r=0; r<geracao.size(); r++){
System.out.println(geracao.get(r).getCaminho());
}
}
//Sets e Gets dos atributos da classe Controle.
public int getK() {
return k;
}
public void setK(int k) {
this.k = k;
}
public Grafo getGrafo() {
return grafo;
}
public void setGrafo(Grafo grafo) {
this.grafo = grafo;
}
public ArrayList<Caminho> getGeracao() {
return geracao;
}
public void setGeracao(ArrayList<Caminho> geracao) {
this.geracao = geracao;
}
public ArrayList<Caminho> getPais() {
return pais;
}
public void setPais(ArrayList<Caminho> pais) {
this.pais = pais;
}
/**
* Calcula a aptid�o relativa de cada caminho al�m de setar o range dele
* @param total
*/
public void calculaAptidaoRelativa(int total){
for(Caminho c : geracao){
c.setAptidaoRelativa(c.getAptidaoAbsoluta() * 100 / total);
float aptidao = c.getAptidaoRelativa();
}
float low = 0;
for(Caminho c : geracao){
c.setLowRange(low);
c.setHighRange(c.getLowRange() + (c.getAptidaoRelativa()*100));
low += (c.getAptidaoRelativa()*100);
}
}
/**
* Dado o n�mero selecionado aleatoriamente (roleta) verifica qual caminho possue
* tal n�mero em seu range
*
* @param i
* @return
*/
public Caminho retornaCaminho(int i){
for(Caminho c : geracao){
if(c.getLowRange() <= i && i < c.getHighRange()){
return c;
}
}
return null;
}
public boolean condicaoParada(){
int i = 0;
for(Caminho c : geracao){
System.out.println("Aptidao do caminho: "+c.getCaminho()+"\t eh: "+c.getAptidaoAbsoluta());
if (c.getAptidaoAbsoluta() == 15){
i++;
}
}
if(i >= 5){
return true;
}
return false;
}
}