]> git.llucax.com Git - z.facultad/75.68/celdas.git/blobdiff - trunk/src/sistemaautonomo.h
Últimos cambios y documentación.
[z.facultad/75.68/celdas.git] / trunk / src / sistemaautonomo.h
index d0355fdd8bfd053e892b8a0f0e60132638a56ea3..2a85b5c56d42df307c6c61f143d47a6106d31bd5 100644 (file)
@@ -3,6 +3,10 @@
 #define __SISTEMAAUTONOMO__
 
 #include "indicemagico.h"
+#include <math.h>
+#include <string>
+#include <iostream>
+
 
 // DEFINICIONES:
 // ------------
 
 class CEntorno ;
 
+
 typedef double t_dato ;
-#define t_fnc(name)            double (*name)(CEntorno&)
+#define ANY -3000000
 
 
-#define INFINITO       9999999 //CORREGIR: Poner aca el numero maximo que puede tomar un unsigend long
+//#define t_fnc(name)          double (*name)(CEntorno&)
 
 
+#define INFINITO       9999999 //CORREGIR: Poner aca el numero maximo que puede tomar un unsigend long
+
 
 // ------------------------------------------
 // Parametros de configuracion de SA
@@ -37,7 +44,7 @@ typedef double t_dato ;
 
 // Precision en la comparacion de atributos.
 // Poner en 0 si se quiere hacer la comparacion exacta.
-#define PRECISION                                                              0.50000
+#define PRECISION                                                              0.150000
 
 // Cuando se ejecuta un plan, se espera que al termina el ultimo paso se hallan alcanzado las condiciones finales.
 // Es posible que las condiciones finales se alcancen en algun paso previo.
@@ -47,11 +54,6 @@ typedef double t_dato ;
 
 // [Planificador]
 
-// Cantidad maxima de pasos que puede tener un plan.
-// Cuanto mas grande sea este numero, mas ciclos puede tardar el proceso de planificacion.
-// Este valor es un compromiso entre performance y eficiencia.
-#define PASOS_MAXIMOS_DE_PLAN          20
-
 // El metodo de planificacion puede encontrar varios planes, y de ellos elige el mejor.
 // Si se hace seleccionar TODOS los posibles planes, puede tardar demasiado.
 // Una opcion es determinar una cantidad maxima de posibles planes que se pueden testear.
@@ -72,49 +74,56 @@ typedef double t_dato ;
 
 
 
-bool cumple_condiciones (CIndiceMagico<t_dato>&, CIndiceMagico<t_dato>&) ;
+bool incluye_a (CIndiceMagico<t_dato>&, CIndiceMagico<t_dato>&) ;
 
 
 
+class CTeoria;
+std::ostream& operator<< (std::ostream& os, const CTeoria& t);
 
 // CTeoria
-template < typename E >
 class CTeoria
 {
 public:
 
-       std::string                             nombre ;
+       std::string             nombre ;
 
        // Condiciones iniciales de la teoria.
        // Cada condicion se representa como un par (clave, valor), que se leen como clave=valor +/- PRECISION.
        // Las condiciones se concatenan con un operador &&
        CIndiceMagico<t_dato>   datos_iniciales ;
-       
+
+       // La funcion que se debe ejecutar para hacer valer la teoria.
+       std::string funcion ;
+       // TODO std::string accion; Debería ser el nombre de la acción que va a realizar el BREVE
+
        // Condiciones finales que deben cumplirsem luego de ejecutar la funcion final valiendo la condicion inicial
        CIndiceMagico<t_dato>   datos_finales ;
 
-       // Entorno sobre el cual trabajar
-       E& entorno;
-
 public:
+       CTeoria()
+       {
+               nombre = "" ;
+               funcion = "" ;
+               k = 1 ;
+               p = 1 ;
+       }
 
        CTeoria(const std::string& ini_nombre, 
+               const std::string& ini_funcion,
                        unsigned long ini_k,
-                       unsigned long ini_p,
-                       E& e):
-               nombre(ini_nombre),
-               k(ini_k),
-               p(ini_p),
-               entorno(e)
-       {}
-
-       // La funcion que se debe ejecutar para hacer valer la teoria.
-       virtual double funcion() = 0;
+                       unsigned long ini_p)
+       {
+               nombre = ini_nombre ;
+               funcion = ini_funcion ;
+               k = ini_k ;
+               p = ini_p ;
+       }
 
 public:        
        // Cantidad de veces que se probo la teoria.
        unsigned long                   k ;
-       
+
        // Cantidad de veces que se probo la teoria y resulto correcta.
        unsigned long                   p ;
 
@@ -124,6 +133,28 @@ public:
 
 } ;
 
+inline
+std::ostream& operator<< (std::ostream& os, const CTeoria& t)
+{
+#ifdef LOG
+       return os << t.nombre << "," << t.funcion << "," << t.p << "," << t.k;
+#else // ! LOG
+       return os << "CTeoria(nombre=" << t.nombre << ", funcion=" << t.funcion
+               << ", p=" << t.p << ", k=" << t.k << ")";
+#endif // LOG
+}
+
+template < >
+inline
+std::ostream& operator<< (std::ostream& os, CIndiceMagico<CTeoria*>& im)
+{
+       unsigned c = im.count();
+       if (c-- == 0) return os << "";
+       for (unsigned i = 0; i < c; ++i)
+               os << *im[i] << "\n";
+       os << *im[c];
+       return os;
+}
 
 
 // CEntorno
@@ -133,209 +164,114 @@ public:
        CIndiceMagico<t_dato>   datos ;
 
 public:
+//     CEntorno() { this->inicializar() ; }
+
+public:
+       // Inicializar los datos
+       virtual void inicializar() {} ;
+
        // Actualizar los datos
-       virtual void actualizar() = 0 ;
+       virtual void actualizar() {} ;
 
+       // Destructor
        virtual ~CEntorno() {}
 } ;
 
 
 
 // CSistemaAutonomo
-template < typename E >
 class CSistemaAutonomo
 {
 public:
        // El entono en el que se mueve el SA.
-       E&                              entorno ;
+       CEntorno*                       p_entorno ;
+
+       // Datos finales a utilizar al hacer
+       CIndiceMagico<t_dato>           m_datos_finales;
 
        // Las teorias que tiene el SA.
-       CIndiceMagico< CTeoria< E >* >  teorias ;
+       CIndiceMagico<CTeoria*>         teorias ;
 
+       // Cantidad maxima de pasos que puede tener un plan.
+       // Cuanto mas grande sea este numero, mas ciclos puede tardar el proceso de planificacion.
+       // Este valor es un compromiso entre performance y eficiencia.
+       unsigned max_pasos;
+
+       // Cantidad máxima de teorías que puede tener el planificador. Al haber muchas teorías el
+       // tarda demasiado tiempo en planificar, por lo tanto es necesario sacar algunas teorías
+       // para que sea utilizable. El valor en realidad no es la cantidad máxima, pueden haber
+       // más, pero en cada nueva planificación se seleccionan las mejores max_teorias teorias.
+       unsigned max_teorias;
+
+public:
+       // Constructor
+       CSistemaAutonomo(unsigned max_pasos = 4, unsigned max_teorias = 15):
+               p_entorno(new CEntorno), max_pasos(max_pasos),
+               max_teorias(max_teorias) {}
+
+       // Destructor
        ~CSistemaAutonomo()
        {
-               for (int i = 0; i < teorias.m_cant; ++i)
-               {
-                       delete teorias.m_datos[i];
-               }
+               delete p_entorno;
+               for (unsigned i = 0; i < teorias.count(); ++i)
+                       delete teorias[i];
        }
 
+       // Genera un nuevo plan
+       void plan();
 
-public:
-       // Retorna true si los valores de la condicion coinciden con los valores del entorno.
-       bool verificar_condicion(CIndiceMagico<t_dato>& datos)
-       {
-               bool result = true ;
-               unsigned i ;
+       // Indica si hay una teoria mas para ejecutar
+       bool has_next_theory();
 
+       // Obtiene la próxima teoría del plan actual
+       CTeoria* get_next_theory();
 
-               for (i=0; i<datos.count() && result; i++)
-                       result = datos[i] == this->p_entorno->datos.find(datos.keys(i))  ;
+       // Retorna true si los valores de la condicion coinciden con los valores del entorno.
+       bool validate_theory(CTeoria*) ;
 
+//protected:
+       // Retorna true si los valores de la condicion coinciden con los valores del entorno.
+       bool verificar_condicion(CIndiceMagico<t_dato>& datos) ;
 
-               //
-               return result ;
-       }
+       // plan actual
+       CIndiceMagico<CTeoria*> m_plan;
 
+       // teoria actual
+       CIndiceMagico<CTeoria*>::iterator curr_theory;
 
 protected: 
 
        // Heuristica de observacion.
        //      Segun la teoria que se ejecuto, se crea una nueva teoria con TODOS/ALGUNOS valores actuales del entorno como condicion_final.
-       void heurisitca_observacion(CTeoria< E >&)
-       {
-       }
+       void heuristca_observacion(CTeoria&) ;
 
        // Heuristica de correccion por retraccion.
        //      Si una teoria no se verifico como correcta, se crea una nueva quitandole las condiciones_finales que no se verifican.
-       void heurisitca_retraccion(CTeoria< E >&)
-       {
-       }
+       void heuristca_retraccion(CTeoria&) ;
 
+       //Heuristica de generalizacion.
+       // Si dentro de las teorias se encuentra unaque solo difiera de los datos del entorno en una condicíon inicial => se agrega una nueva teoria igual pero con ANY en esa condicion.
+       void heuristca_generalizacion(CTeoria&);
 
-
-protected:
-       // Planificador: Se encaga de encontrar una serie de teorias que logren hacer
-       //                              cumplir la condicion_final, partiendo de la condicion_inicial.
-       // Parametros:
-       //              datos_iniciales: Forman la condicion inicial.
-       //              datos_finales:   Forman la condicion final.
-       CIndiceMagico<CTeoria< E >* >*          planificar (
-                       CIndiceMagico<t_dato>&  datos_iniciales,
-                       CIndiceMagico<t_dato>&  datos_finales,
-                       CIndiceMagico<CTeoria< E >* >& plan,
-                       unsigned long numero_de_llamada,
-                       double& p) ;
+       // Purga las teorias que no son muy exitosas.
+       void purgar_teorias();
 
 public:
 
-       CSistemaAutonomo(E& e): entorno(e) {}
-
-       CIndiceMagico<CTeoria< E >* >* new_plan(CIndiceMagico< t_dato >& datos_finales, double& p)
-       {
-               CIndiceMagico<CTeoria< E >* >   plan ;
-               return planificar(entorno.datos, datos_finales, plan, 0, p) ;
-       }
+       
+       void planificar (CIndiceMagico<t_dato>& datos_iniciales,
+                       CIndiceMagico<t_dato>&  datos_finales,
+                       CIndiceMagico<CTeoria*>& plan,
+                       double&         p,
+                       unsigned long   numero_de_llamada=0) ;
 
 
        // Ejecuta una serie de pasos.
        // Retorna true si se alcanza la condicion final.
-       bool ejecutar (CIndiceMagico<CTeoria< E > >& plan) ;
-
-
+//     bool ejecutar (CIndiceMagico<CTeoria>& plan) ;
 } ;
 
 
-//--------------------------------------------------------------------------------------------
-//-- PROBAR BIEN
-template < typename E >
-CIndiceMagico< CTeoria< E >* >*        CSistemaAutonomo< E >::planificar (
-               CIndiceMagico< t_dato >&        datos_iniciales,
-               CIndiceMagico< t_dato >&        datos_finales,
-               CIndiceMagico< CTeoria< E >* >& plan,
-               unsigned long numero_de_llamada,
-               double& p)
-{
-       unsigned                                                                        i ;
-       double                                                                          nuevo_p ; 
-       double                                                                          max_p = 0 ;
-       CIndiceMagico< CTeoria< E >* >*                                         p_nuevo_plan ;
-       CIndiceMagico< CTeoria< E >* >*                                         pResult = NULL ;
-       CIndiceMagico< CIndiceMagico< CTeoria< E >* > >         planes ;
-       
-
-       for (i=0; i<this->teorias.count(); i++)
-       {
-               // Si la teoria cumple la condicion inicial
-               if ( cumple_condiciones(this->teorias[i]->datos_iniciales, datos_iniciales) )
-               {
-                       p_nuevo_plan = new CIndiceMagico< CTeoria< E >* > ;
-
-                       nuevo_p = ( p + ((double)this->teorias[i]->p) / ((double)this->teorias[i]->k) ) / 2 ;
-                       
-                       // Agrego la teoria al plan
-                       p_nuevo_plan->add (this->teorias[i]->nombre.c_str(), this->teorias[i]) ;
-                       
-                       if (numero_de_llamada<PASOS_MAXIMOS_DE_PLAN)
-                       {
-                               // Pero si no cumple con la condicion final
-                               if ( !cumple_condiciones(datos_finales, this->teorias[i]->datos_finales) )
-                               {
-                                       planificar (this->teorias[i]->datos_finales,
-                                                               datos_finales,
-                                                               *p_nuevo_plan,
-                                                               numero_de_llamada+1,
-                                                               nuevo_p) ;
-                               }
-                       }
-
-               
-                       // Si cumple con la condicion final
-                       if (nuevo_p>max_p)
-                       {
-                               if ( cumple_condiciones(datos_finales, (*p_nuevo_plan)[p_nuevo_plan->count()-1]->datos_finales) )
-                               {
-                                       max_p = nuevo_p ;
-
-                                       if (pResult) delete pResult ;
-                                       
-                                       pResult = p_nuevo_plan ;
-                               }
-                       }
-               }       
-       }
-
-       //
-       return pResult ;
-}
-
-
-//--------------------------------------------------------------------------------------------
-//--
-template < typename E >
-bool CSistemaAutonomo< E >::ejecutar (CIndiceMagico<CTeoria< E > >& plan)
-{
-       bool result = true ;
-       int i ;
-       CTeoria< E > t ;        
-
-
-       for (i=0; i<plan.count() && result; i++)
-       {
-               t = plan[i] ;
-
-               // Ejecuto la funcion
-               t.funcion() ;
-
-               // Incremento el K
-               t.k++ ;
-
-               // Actualizo los datos del entorno
-               this->p_entorno->actualizar() ;
-
-               // Veo si se verifica la condicion final
-               result = this->verificar_condicion(t.datos_finales) ;
-
-               // Si fallo la teoria
-               if (!result)
-               {
-                       // Aplico heuristicas de correccion
-                       this->heurisitca_retraccion(t) ;
-               }
-               else
-               {
-                       t.p++ ;
-               }
-
-               // Aplico heuristicas de observacion
-               this->heurisitca_observacion(t) ;
-       }
-
-       //
-       return result ;
-}
-
-
 
 #endif