Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Primer Tutorial De Ia / First Ai Tutorial

Iniciado por Vicente, 03 de Marzo de 2006, 04:17:11 PM

« anterior - próximo »

Vicente

 Hola,

ya he subido el primer tutorial sobre la librería de IA de Haddd. El formato es algo diferente a los tutoriales que había hasta ahora: es un pdf de 5 páginas y el código fuente del tutorial. Trata sobre computación evolutiva (una breve introducción) y como se usa en Haddd. No estoy muy acostumbrado a escribir tutoriales, espero que no seáis muy duros con el estilo :D A ver si os gusta y os animáis a hacer algo! ;) Un saludo!

Vicente

------------------------------------------------------------------------------------------------------------------------

Hi,

I´ve uploaded the first tutorial about AI with Haddd. The tutorial format is a little different from the ones done before: it´s a 5 pages pdf with a project with the source code. It´s about evolutionary computing (a little introduction) and how it´s managed in Haddd. I´m not used to write tutorials, so I expect you won´t be very hard with my way of writting :D I hope you enjoy it and I hope to see somethings done by other people! ;) Greetings!

Vicente

 Magnifico!!! felicidades por tu tutorial !!! es lo que se necesita. Una breve introduccion para poder manejar el vocabulario y los conceptos que se usen en el tuto , y un ejemplo con codigo incluido , muy bueno
Ojala se hiciese lo mismo con los tutos de graficos  :P
Oye, a ver si cae :D  

Vicente

 Que ilusión! Alguien que responde cuando hablo de IA :) Me alegro que te haya gustado, a pesar de lo corto que es me ha llevado unos cuantos días escribirlo todo.

Ahora mismo estoy con el segundo de computación evolutiva (donde ya se verá un problema más complicado y como escribir un operador personalizado) y he cazado un fallo gordo gordo (los tutos me vienen genial para hacer pruebas). La verdad es que me sorprendía que el genético se comportara tan poco bien con la funcion X*X, ya que es muy sencilla. 50 generaciones son muchas para algo tan fácil (incluso poniéndoselo cuesta arriba), y a veces salían soluciones bastante malas (0.5-0.6). Pero no era capaz de ver el fallo, y con el segundo tuto lo he encontrado: el ChromosomeComparer está mal implementado, con lo cual el Sort no ordena las listas de cromosomas por fitness, sino casi al azar  :P

Ahora lo que me sorprende es que son semejante pifia el genético encontrara soluciones tan buenas :P

El código bueno del método compare sería:

public int Compare(IChromosome<T> x, IChromosome<T> y)
 {
  if (x.Fitness == y.Fitness)
   return 0;

  if (x.Fitness < y.Fitness)
  {
   if (order == EvolutionObjective.Minimize)
    return -1;

   else
    return 1;
  }

  else
  {
   if (order == EvolutionObjective.Minimize)
    return 1;

   else
    return -1;
  }
 }


Si lo comparáis con el viejo veréis que tenía una cagada grande grande, jejeje :)

Pues nada, a ver si alguien más se anima a verlo y gracias por los comentarios. Para cualquier duda ya sabes! Un saludo!

Vicente

 Oye, pues yo te animo a que sigas haciendo tutos, porque ve los voy a aprender todos!!!!!
Es normal que la gente escriba poco , porque los motores graficos son conocidos, los motores de fisica menos, pero los motores de IA ... uffff con los dedos de la mano...
Pero creo que no hay que dejar pasar la oportunidad.
Que vicente escriba tutos, en español, y orientado a un motor de jegos como haddd es un privilegio
Ojala cunda el ejemplo y formemos una comunidad de tutos  (uoh)  (uoh)  

zupervaca

 Vicente como no haces la funcion de comparar los cromosas como un estandar de comprobacion, es decir:

   public int Compare(IChromosome<T> x, IChromosome<T> y)
   {
       return order == EvolutionObjective.Minimize ?
           y.Fitness - x.Fitness :
           x.Fitness - y.Fitness;
   }

De esta manera lo haces compatible con todos los sistemas de busquedas y ganas algo de velocidad, si miramos los casos tenemos que si x e y son iguales no importa el order ya que siempre sera 0, si order es minimize resta a la inversa, si order es diferente a minimize coge la resta tal cual, en las comprobaciones externas a la funcion es mirar si es mayor o menor a cero y un else para si es 0.

Vicente

 Hola,

zupervaca: pues tienes toda la razón :P (aunque el operador ternario no me gusta nada, pero lo de la resta tiene toda la lógica del mundo).

QTR: gracias por los animos, mi idea es seguir escribiendo tutos de la librería y diferentes formas de usar las herramientas que proporciona (además de breves introducciones a cada ténica). Luego cuando eso termine estaría bien hacer un mini-jueguecito para ver todo puesto en una situación más realista. Tiempo al tiempo, de momento sigo con el 2, pero el N-Puzzle genético se me está resistiendo...

Un saludo!

Vicente

zupervaca

 Yep como siempre no me deja editar el anterior post :(

Si no quieres usar el ternario ponlo como al final lo dejaria el compilador, yo mas que nada lo hago por elegancia y todas esas chorradas que nos mandan los jefes de equipo :lol:

   public int Compare(IChromosome<T> x, IChromosome<T> y)
   {
       if (order == EvolutionObjective.Minimize)
       {
           return y.Fitness - x.Fitness;
       }
       return x.Fitness - y.Fitness;
   }


PD: Espero que hagas bastantes tutoriales para entender todos la IA, por que a primera vista tienes un porron de clases y no se por donde empezar :lol:  

Vicente

 Seguramente lo dejaré con el if normal (es que a mi para ver el código el ternario me cuesta mucho más trabajo, la falta de costumbre supongo).

Respecto a los tutoriales, sip, planeo tocar todo. Ya se que son un montón de clases (je, vaya peñazo documentarlas...). Lo que pasa que yo también aprendo mientras hago los tutos, por eso tardo. Por ejemplo el segundo de genéticos trata de resolver el N-Puzzle con un genético, y aún no lo he conseguido (ya llevo dos días intentándolo). Se que el problema se puede enfocar con un genético, pero aun no he debido dar con la función de fitness adecuada (estoy usando la distancia de manhattan de las fichas a su posición correcta, pero no consigo buenos resultados) o no he dado con los operadores adecuados.

Está gracioso la verdad. Creo que el tercero será de resolver el TSP con genéticos (para ver un problema donde si que se comportan realmente bien y ver en que tipo de cosas son útiles). Después iré a máquinas de estados y mensajes.  Luego grafos y después a ampliar la librería :)

Si queréis que trate de algún tema en concreto decidlo, que tomo nota ;) Un saludo!

Vicente

Vicente

 Hola otra vez,

zupervaca, no me vale el código ;) Te cuento porque: a veces los cromosomas son fitness entre 0 y 1 (normalizados para poder compararlos a simple vista mejor). Como compare devuelve un int, la resta de los dos es un double, si la casteo a int, me sale casi siempre 0 ;) (usease iguales). Si me pongo a usar Math.Round entonces ya no se si sería más rápido así o como estaba antes...

Un saludo!

Vicente

zupervaca

 Si el fitness es de tipo double retorna double en la funcion, es decir:

  public double Compare(IChromosome<T> x, IChromosome<T> y)
  {
      if (order == EvolutionObjective.Minimize)
      {
          return y.Fitness - x.Fitness;
      }
      return x.Fitness - y.Fitness;
  }

Despues es comprobar como antes si es mayor a 0, si no comprobar si es menor a 0 y si no hacer el codigo cuando es 0.

Vicente

 No puedo retornar double, Compare es un método de la interfaz IComparer y tiene que devolver un int :( Un saludo!

Vicente

zupervaca

 ¿Pero por que usas el interface IComparer?, solo da el patron de una funcion Compare, creo que seria mejor que crearas tu propio IComparer, es decir, crear tu propio interface sin derivar de IComparer para comprobar valores entre cromosomas, algo asi:

   interface IHadddComparer<T>
   {
       double CompareDouble(T obj1, T obj2);
   }

Despues en vez de usar el IComparer usas el IHadddComparer.
Si no lo ves claro tambien puedes usar el interface IComparer como base de este dando soporte a int y double, algo asi:

   interface IHadddComparer<T> : IComparer<T>
   {
       double CompareDouble(T obj1, T obj2);
   }

Despues en la clase que uses el interface tendrias que definir dos funciones para comprobar objetos entre si.

Otra cosa, en vez de usar una clase para esto podrias poner la propia comprobacion entre cromosomas en la propia clase de cromosomas pasandole el cromosoma contra el que quieres comprobarlo y el objetivo de la evolucion, ya que al final estarias pasandole el mismo numero de parametros y tamaño de estos.
Te comento esto por que el verdadero funcionamiento de la clase IComparer es el que dentro de la funcion se llame a la funcion CompareTo del objeto que tuvo que ser instanciado de IComparable, asi de esta manera se crea la comprobacion entre objetos distintos de forma abstracta, te paso info por si estas interesado en implementar todo este sistema de comprobaciones entre objetos. http://msdn.microsoft.com/library/default....paretotopic.asp Todo este sistema de clases de comprobaciones entre objetos esta muy bien pensado para comprobar por ejemplo un string entre un int optimizando al maximo la velocidad en el proceso, pero ello implica mucho curro :(  

Vicente

 Necesito el comparer para poder usar el Sort, hasta lo que yo se las cosas van así:

- si la lista tiene un IComparer, se usa el Compare del IComparer.
- si no lo tiene, se usa el Comparer.Default genérico (esto es si, el tipo T implementa IComparable).
- si esto tampoco se cumple, se mira si usa el Comparer.Default (esto es, si el tipo T implementa IComparable).

Si todas fallan peta. El Sort espera llamar al metodo Compare, no al método CompareDouble, no veo que gano implementando con esa interfaz (implementarme yo el Sort haciendome mi propia colección no es una solución válida :P).

No entiendo lo de que IComparer llame al CompareTo (si el objeto no es IComparable ese método no existe). Quizás es que como son las dos de la mañana ando algo espeso tambien :P Pero vamos, que no me he enterado mucho de lo que me querías decir, a ver si me lo aclaras. Un saludo!

Vicente

zupervaca

 El motivo de usar CompareTo es que ya existe una implementacion por defecto para todos los tipos de datos, puedes acceder a ella desde "Comparer.DefaultInvariant.Compare(object, object);", deberias de poner un "using System.Collections", esta implementacion lo que hace es algo parecido a esto:

public int Compare( object obj1, object obj2 )
{
return obj1.CompareTo(obj2);
}

De esta manera en la propia clase del cromosoma defines que cromosoma es mayor o menor o igual, no obstante como tienes el objetivo de evolucion deberias de implementar tantos IComparer como objetivos de evolucion tengas, pero el sistema de ordenacion del cromosoma es identico para todos, es decir:

   class Cromosoma : IComparable<...>
   {
       public int CompareTo( cromosoma obj )
       {
           ... (Aqui compruebas si es mayor, menor o igual)
       }
   }
   class IOEMinimize : IComparer<...>
   {
       public int Compare(object obj1, object obj2) // En vez de object pones la clase cromosoma
       {
           return - obj1.CompareTo(obj2);
       }
   };

   class IOEMaximize : IComparer<...> // Puse maximize por poner algo por que de esto ya no tengo ni idea :)
   {
       public int Compare(object obj1, object obj2)
       {
           return obj1.CompareTo(obj2);
       }
   };

Despues dependiendo de como quieres ordenar los cromosas usarias una u otra clase, el mimize cambia el signo y el maximize lo deja como esta.
No se si explique bien la filosofia del comparar objetos en csharp con las intefaces, si quieres intento poner mas ejemplos que se me da mejor que las palabras :lol:

Vicente

 Hola,

si entiendo lo que dices, pero no veo que gano con todo eso (además de que obligo a implementar IComparable a alguien que quiera utilizar un cromosoma, con lo que le doy mas curro).

Lo que si se podría hacer es:


if(order == EvolutionObjective.Minimize)
     return x.Finess.CompareTo(y.Finess);

return y.Fitness.CompareTo(x.Finess);


Ya que double si que tiene IComparable (a lo mejor te referías a esto). Pero tampoco veo que gano con eso. Un saludo!

Vicente






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.