Skip to content

Instantly share code, notes, and snippets.

@alexsandro-xpt
Created April 29, 2012 02:06
Show Gist options
  • Save alexsandro-xpt/2523359 to your computer and use it in GitHub Desktop.
Save alexsandro-xpt/2523359 to your computer and use it in GitHub Desktop.
Algoritmo genético
//Algoritmo genético
//Trabalho de Inteligência Artificial
//Unileste - Centro Universitário do Leste de Minas Gerais
//Professor Reinaldo
//Autor: Alexsandro Souza Pereira Twitter @alexsandro_xpt
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace AG {
class Program {
static bool t;
static bool Eb() {
//return t = !t;
Console.WriteLine("Escolhendo um valor aleatório");
Thread.Sleep((new Random()).Next(30));
int v = (new Random()).Next();
if (v % 2 == 0)
return true && (t = !t);
else
return false && (t = !t);
}
static void Main(string[] args) {
List<Pais> listadePais = new List<Pais>();
Genotipo gOlhos = new Genotipo("Olhos");
gOlhos.Fenotipo.Add(new bool[] { false, false, false }, new KeyValuePair<int, string>(3, "Castanho"));
gOlhos.Fenotipo.Add(new bool[] { false, false, true }, new KeyValuePair<int, string>(4, "Verde"));
gOlhos.Fenotipo.Add(new bool[] { false, true, false }, new KeyValuePair<int, string>(5, "Azul"));
gOlhos.Fenotipo.Add(new bool[] { false, true, true }, new KeyValuePair<int, string>(6, "Amarelo"));
gOlhos.Fenotipo.Add(new bool[] { true, false, false }, new KeyValuePair<int, string>(7, "Vermelho"));
gOlhos.Fenotipo.Add(new bool[] { true, false, true }, new KeyValuePair<int, string>(8, "Branco"));
gOlhos.Fenotipo.Add(new bool[] { true, true, false }, new KeyValuePair<int, string>(9, "Cinza"));
gOlhos.Fenotipo.Add(new bool[] { true, true, true }, new KeyValuePair<int, string>(10, "Preto"));
Genotipo gEstrutura = new Genotipo("Estrutura");
gEstrutura.Fenotipo.Add(new bool[] { false, false }, new KeyValuePair<int, string>(3, "3 Membros"));
gEstrutura.Fenotipo.Add(new bool[] { false, true }, new KeyValuePair<int, string>(6, "2 Membros"));
gEstrutura.Fenotipo.Add(new bool[] { true, false }, new KeyValuePair<int, string>(10, "4 Membros"));
Genotipo gMente = new Genotipo("Mente");
gMente.Fenotipo.Add(new bool[] { false, false }, new KeyValuePair<int, string>(3, "Burro"));
gMente.Fenotipo.Add(new bool[] { true, true }, new KeyValuePair<int, string>(6, "Esperto"));
gMente.Fenotipo.Add(new bool[] { true, false }, new KeyValuePair<int, string>(10, "Inteligente"));
for (int n = 0; n < 10; n ) {
Cromossomo c1 = new Cromossomo(new bool[] { Eb(), Eb(), Eb(), Eb(), Eb(), Eb(), Eb() }, new Genotipo[] { gOlhos, gEstrutura, gMente });
Cromossomo c2 = new Cromossomo(new bool[] { Eb(), Eb(), Eb(), Eb(), Eb(), Eb(), Eb() }, new Genotipo[] { gOlhos, gEstrutura, gMente });
Pais p1 = new Pais(c1, c2);
listadePais.Add(p1);
}
Cromossomo c = AG.Evoluir(listadePais, 3, 26);
string melhor = "Nao achou";
if (c != null) {
melhor = Cromossomo.Decodifica(c);
Console.WriteLine(c.Forca());
}
Console.WriteLine(melhor);
Console.ReadKey();
}
public class Pais {
public Cromossomo Pai {get; private set;}
public Cromossomo Mae {get; private set;}
public int Locus {get; private set;}
public Pais(Cromossomo p, Cromossomo m) {
if (p.Count != m.Count) {
throw new Exception("Os pais não pode conter diferentes quantidades de locus.");
}
Pai = p;
Mae = m;
Locus = p.Count;
}
public Cromossomo EscolheCromossomo(){
Random r = new Random();
if(r.Next()%2==0){
return Mae;
}else{
return Pai;
}
}
}
interface ICromossomo: IList<bool> {
Genotipo[] Genotipos { get; set; }
}
public class Cromossomo : List<bool>, ICromossomo {
/*public Cromossomo(Genotipo[] genotipos) {
this.Genotipos = genotipos;
}*/
public Cromossomo(bool[] locus, Genotipo[] genotipos) {
int comprimentoGenotipo = 0;
foreach (Genotipo g in genotipos) {
comprimentoGenotipo = g.GetQuantidadeLocus();
}
if (comprimentoGenotipo != locus.Length) {
//throw new Exception("As quantidade de locus deve ser " comprimentoGenotipo " e não " locus.Length " pois a soma do seus genótipos contem este valor.");
//Console.WriteLine("As quantidade de locus deve ser " comprimentoGenotipo " e não " locus.Length " pois a soma do seus genótipos contem este valor.");
}
this.Genotipos = genotipos;
this.AddRange(locus);
}
/*public Cromossomo(bool[] locus) {
this.AddRange(locus);
}*/
/// <summary>
/// Força ou Qualidade ou Pureza do Cromossomo
/// </summary>
/// <remarks>Somar os valores da decoficacao dos fenotipos.</remarks>
/// <returns></returns>
public int Forca() {
int result = 0;
int start = 0;
foreach (Genotipo g in this.Genotipos) {
result = g.Fenotipo[this.GetRange(start, g.GetQuantidadeLocus()).ToArray()].Key;
start = g.GetQuantidadeLocus();
}
return result;
}
#region ICromossomo Members
public Genotipo[] Genotipos { get; set; }
#endregion
public static string Decodifica(Cromossomo c) {
string result = string.Empty;
int start = 0;
foreach (Genotipo g in c.Genotipos) {
result = g.Fenotipo[c.GetRange(start, g.GetQuantidadeLocus()).ToArray()].Value;
start = g.GetQuantidadeLocus();
}
return result;
}
public static bool ExiteCromossomo(Cromossomo c) {
int start = 0;
foreach (Genotipo g in c.Genotipos) {
if (!g.Fenotipo.ContainsKey(c.GetRange(start, g.GetQuantidadeLocus()).ToArray())) {
return false;
}
start = g.GetQuantidadeLocus();
}
return true;
}
}
public class Genotipo {
public string Nome{get; private set;}
public Dictionary<bool[], KeyValuePair<int, string>> Fenotipo { get; private set; }
public Genotipo(string nome) {//, KeyValuePair<int, string> fenotipo
Nome = nome;
Fenotipo = new Dictionary<bool[], KeyValuePair<int, string>>(new FenotipoValueCompare());
//Fenotipo.Add(fenotipo.Key,fenotipo.Value);
}
public int GetQuantidadeLocus() {
Dictionary<bool[], KeyValuePair<int, string>>.KeyCollection kc = Fenotipo.Keys;
return (kc.ToArray() as bool[][])[0].Length;
}
private class FenotipoValueCompare: IEqualityComparer<bool[]>{
#region IEqualityComparer<bool[]> Members
public bool Equals(bool[] x, bool[] y) {
int qtIgualdade = 0;
for (int n = 0;x.Length == y.Length && n < x.Length; n ) {
if (x[n] == y[n]) {
qtIgualdade ;
}
}
return qtIgualdade == x.Length;
}
public int GetHashCode(bool[] obj) {
int result = 0;
if (obj == null) return 0;
foreach (bool b in obj) {
result = b.GetHashCode();
}
return result;
}
#endregion
}
}
public static class AG{
public static int vezes = 0;
public static int Corte {get; private set;}
public static Cromossomo Evoluir(List<Pais> listaDePais, int corte, int PossivelSolucao) {
vezes ;
Console.WriteLine(vezes);
AG.Corte = corte;
foreach (Pais p in listaDePais) {
ICromossomo Filho1, Filho2;
Filho1 = new Cromossomo(p.Mae.GetRange(0, AG.Corte).ToArray(),p.Mae.Genotipos);
Filho2 = new Cromossomo(p.Pai.GetRange(0, AG.Corte).ToArray(),p.Pai.Genotipos);
for (int n = AG.Corte; n < p.Locus; n ) {
Filho1.Add(p.Pai[n]);
Filho2.Add(p.Mae[n]);
}
AG.MutarFilhos(Filho1, Filho2);
Cromossomo Mae = (Cromossomo)Filho1;
Cromossomo Pai = (Cromossomo)Filho2;
//Verifico antes de mutar?
if (Cromossomo.ExiteCromossomo(Mae) && Mae.Forca() > PossivelSolucao) {
return Mae;
}
if (Cromossomo.ExiteCromossomo(Pai) && Pai.Forca() > PossivelSolucao) {
return Pai;
}
if (Cromossomo.ExiteCromossomo(Mae) && Cromossomo.ExiteCromossomo(Pai)) {
Pais novoPais = new Pais(Mae, Pai);
return AG.Evoluir(new List<Pais>() { novoPais }, AG.Corte, PossivelSolucao);
} else if (Cromossomo.ExiteCromossomo(Mae) || Cromossomo.ExiteCromossomo(Pai)) {
Cromossomo sobrevivente = Cromossomo.ExiteCromossomo(Mae) ? Mae : Pai;
//Pode cruzar com próprio pai se for sorteado.
return AG.Evoluir(new List<Pais>() { new Pais(sobrevivente, listaDePais[(new Random()).Next(0, listaDePais.Count - 1)].EscolheCromossomo()) }, AG.Corte, PossivelSolucao);
} else {
return AG.Evoluir(new List<Pais>() { new Pais(listaDePais[(new Random()).Next(0, listaDePais.Count - 1)].EscolheCromossomo(), listaDePais[(new Random()).Next(0, listaDePais.Count - 1)].EscolheCromossomo()) }, AG.Corte, PossivelSolucao);
}
}
return null;
}
private static void MutarFilhos(ICromossomo f1, ICromossomo f2) {
Random r = new Random();
int i = r.Next(0,f1.Count-1);
f1[i] = !f1[i];
f2[i] = !f2[i];
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment