#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
// 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.
// [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.
-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 ;
} ;
+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
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