Genéticos: Exemplo em Java
De Aulas
Afluentes: Inteligência Artificial, Modelos Evolutivos e Tratamento de Incertezas
/*****************************************************************************
Copyright 2001-2003 Saulo Popov Zambiasi. All rights reserved.
Last modified: 2004/06/03 23:04:00
Genetico
Programa para calcular uma configuracao ideal de gastos de
uma residencia, utilizando algoritmos geneticos. As informacoes
utilizadas sao ficticias.
USO:
java Genetico >> log.txt
******************************************************************************/
import java.util.*;
public class Genetico {
List<Elemento> populacao = new ArrayList<Elemento>();
List<Integer> selecionados = new ArrayList<Integer>();
private Random r = new Random();
final double ideal = 45.0; // Preco ideal em reais
final int POPULACAO = 50; // Populacao maxima
final int SELECAO = 20; // Quantidade que pode exceder, nos cruzamentos.
static final int EPOCAS = 100;
static final int MUTANTES = 20;
static final boolean MELHORES = true;
static final boolean PIORES = false;
static boolean DEBUG = true;
public void criaPopulacao() {
for (int i = 0; i < POPULACAO; i++) {
populacao.add(new Elemento());
}
}
public void ordenaPopulacao() {
recalculaPontuacao();
for (int a = 0; a < populacao.size() - 1; a++) {
for (int b = a + 1; b > 0; b--) {
Elemento e1 = (Elemento) populacao.get(b - 1);
Elemento e2 = (Elemento) populacao.get(b);
double v1 = e1.pontuacao - ideal;
double v2 = e2.pontuacao - ideal;
if (v1 < 0) {
// Calcula o modulo
v1 *= -1;
}
if (v2 < 0) {
// Calcula o modulo
v2 *= -1;
}
// Inverte
if (v1 < v2) {
populacao.remove(b - 1);
populacao.remove(b - 1);
populacao.add(b - 1, e2);
populacao.add(b, e1);
}
}
}
}
// os elementos selecionados podem ser os mais fortes ou os mais fracos
void selecao(int quantidade, boolean fortes) {
selecionados.clear();
ordenaPopulacao();
// Criando a roleta
Vector<Integer> roleta = new Vector<Integer>();
int peso = 1;
if (!fortes) {
peso = 10;
}
int cont = 0;
for (int i = 0; i < populacao.size(); i++) {
for (int j = 0; j < peso; j++) {
Integer aux = i;
roleta.add(aux);
}
if (cont > 4) {
if (fortes) {
peso++;
} else {
peso--;
}
cont = 0;
} else {
cont++;
}
}
// Seleciona os elementos na roleta;
for (int i = 0; i < SELECAO; i++) {
// pega um numero aleatorio na roleta
int escolhido = r.nextInt(roleta.size());
// pega o indice na roleta
Integer aux = (Integer) roleta.get(escolhido);
// pega o elemento com seu indice
Elemento e = (Elemento) populacao.get(aux.intValue());
if (!e.selecionado) {
// seta o elemento como selecionado
e.selecionado = true;
// insere seu indice no vetor de selecionados
selecionados.add(aux);
} else {
i--;
}
}
dbgln("Selecionados = " + selecionados.size());
}
void cruzamento() {
while (selecionados.size() > 0) {
// Pega o primeiro elemento da lista de selecionados
Integer aux1 = (Integer) selecionados.get(0);
Elemento e1 = (Elemento) populacao.get(aux1.intValue());
e1.selecionado = false;
selecionados.remove(0);
// Pega o segundo elemento da lista de selecionados
Integer aux2 = (Integer) selecionados.get(0);
Elemento e2 = (Elemento) populacao.get(aux2.intValue());
e2.selecionado = false;
selecionados.remove(0);
// cruza, criando dois filhos com as informacoes trocadas e
// insere-os na populacao
Elemento f1 = new Elemento(e1);
Elemento f2 = new Elemento(e2);
int idx1 = r.nextInt(5);
int idx2 = r.nextInt(5);
int troca = f1.elemento[idx1];
f1.elemento[idx1] = f2.elemento[idx1];
f2.elemento[idx1] = troca;
if (idx1 != idx2) {
troca = f1.elemento[idx2];
f1.elemento[idx2] = f2.elemento[idx2];
f2.elemento[idx2] = troca;
}
populacao.add(f1);
populacao.add(f2);
dbg("Cruzando os elementos " + idx1 + " e " + idx2);
dbg(" dos individuos " + aux1.intValue());
dbgln(" e " + aux2.intValue() + "---------------");
e1.mostrarInformacoes();
e2.mostrarInformacoes();
f1.calculaPontuacao();
f1.mostrarInformacoes();
f2.calculaPontuacao();
f2.mostrarInformacoes();
}
ordenaPopulacao();
}
void mutacao() {
// Pode mutar ate 4 elementos
int qtd = r.nextInt(MUTANTES + 1);
for (int i = qtd; i > 0; i--) {
// Escolhe um elemento aleatoriamente
int j = r.nextInt(populacao.size());
Elemento e = (Elemento) populacao.get(i);
// Escolhe aleatoriamente um de seus elementos
int k = r.nextInt(5);
dbgln("Mutando elemento " + k + " do individulo " + j);
if (DEBUG) {
e.mostrarInformacoes();
}
// Muda sua informacao aleatoriamente
e.elemento[k] = r.nextInt(10) + 1;
e.calculaPontuacao();
if (DEBUG) {
e.mostrarInformacoes();
}
}
ordenaPopulacao();
}
void matar() {
boolean matando = true;
int i = 0;
while (matando) {
Elemento e = (Elemento) populacao.get(i);
if (e.selecionado) {
populacao.remove(i);
i--;
}
i++;
if (i >= populacao.size()) {
matando = false;
}
}
selecionados.clear();
}
void recalculaPontuacao() {
for (int i = 0; i < populacao.size(); i++) {
Elemento e = (Elemento) populacao.get(i);
e.calculaPontuacao();
}
}
void mostrarResultado() {
System.out.println("\n\nResultado do algoritmo");
for (int i = 0; i < POPULACAO; i++) {
Elemento e = (Elemento) populacao.get(populacao.size() - 1 - i);
System.out.print("" + (i + 1) + "o: ");
e.mostrarInformacoes();
}
}
public static void dbg(String s) {
if (DEBUG) {
System.out.print(s);
}
}
public static void dbgln(String s) {
if (DEBUG)
System.out.println(s);
}
public static void main(String[] arguments) {
Genetico g = new Genetico();
dbgln("Criando Populacao");
g.criaPopulacao();
for (int i = 0; i < EPOCAS; i++) {
dbgln("**** EPOCA " + (i + 1) + " ****");
dbgln("Populacao = " + g.populacao.size());
dbgln("Selecionando os 20 melhores");
g.selecao(20, MELHORES);
dbgln("Cruzamento");
g.cruzamento();
dbgln("Populacao = " + g.populacao.size());
dbgln("Selecionando os 20 piores");
g.selecao(20, PIORES);
dbgln("Matando");
g.matar();
dbgln("Populacao = " + g.populacao.size());
dbgln("Mutacao");
g.mutacao();
}
g.mostrarResultado();
}
}
/**************************************************************
* Caracteristicas dos elementos (total * 30dias) 0 - Lampadas - 11-20h/dia a
* 100w/h - 1-2k/dia 1 - Chuveiro - 0.1-0.6h/dia a 5kw/h - 0.25-2.75k/dia 2 -
* Televisao - 1-10h/dia a 100w/h - 0-1k/dia 3 - Computador - 1-10h/dia a 300w/h
* - 0-3k/dia 4 - Video K7 - 1-6h/dia a 50w/h - 0-0.5k/dia
**************************************************************/
class Elemento {
int[] elemento = new int[5];
double pontuacao = 0;
boolean selecionado = false;
final double kwh = 0.38;
static Random r = new Random();
Elemento() {
for (int i = 0; i < 5; i++) {
elemento[i] = r.nextInt(10) + 1;
}
calculaPontuacao();
selecionado = false;
if (Genetico.DEBUG) {
mostrarInformacoes();
}
}
Elemento(Elemento e) {
for (int i = 0; i < 5; i++) {
elemento[i] = e.elemento[i];
}
selecionado = false;
}
void mostrarInformacoes() {
System.out.print("LAMPADAS: [" + (int) (elemento[0] + 9) + "h] ");
System.out.print("CHUVEIRO: [" + (int) (((elemento[1] / 2) + 1) * 6)
+ "min] ");
System.out.print("TELEVISAO: [" + (int) (elemento[2]) + "h] ");
System.out.print("COMPUTADOR: [" + (int) (elemento[3]) + "h] ");
System.out.print("VIDEO K7: [" + (int) (elemento[4] / 2) + "h] ");
System.out.println("VALOR: R$ (" + (int) pontuacao + ",00)");
}
public void calculaPontuacao() {
pontuacao = (elemento[0] + 10) * 100; // Lampadas
pontuacao += ((elemento[1] + 2) / 2) * 500; // Chuveiro
pontuacao += elemento[2] * 100; // Televisao
pontuacao += elemento[3] * 300; // Computador
pontuacao += ((elemento[4] + 2) / 2) * 50; // Video k7
pontuacao *= 30; // em 30 Dias
pontuacao = (pontuacao / 1000) * kwh; // kwh = 0.38 - Valor em reais
}
}