]> git.llucax.com Git - z.facultad/75.68/celdas.git/blob - trunk/src/sistemaautonomo.h
d0355fdd8bfd053e892b8a0f0e60132638a56ea3
[z.facultad/75.68/celdas.git] / trunk / src / sistemaautonomo.h
1
2 #ifndef __SISTEMAAUTONOMO__
3 #define __SISTEMAAUTONOMO__
4
5 #include "indicemagico.h"
6
7 // DEFINICIONES:
8 // ------------
9 //
10 //      ENTORNO:                        Variables que definen el entorno.
11 //  CONDICION                   va=a AND vb=b AND vc=c.
12 //      TEORIA:                         Se cumple condicion_inicial y ejecuto funcion F, entonces se cumplira condicion_final.
13 //      SISTEMA AUTONOMO:       Tiene un ENTORNO y una cantidad de TEORIAS.
14 //      CICLO:                          Son los pasos de:
15 //                                                      * Tomar los valores el entorno.
16 //                                                      * Decidir una condicion que deberia cumplir el entorno.
17 //                                                      * Planificar (PLAN) una serie de acciones (PASOS) para alcanzar la condicion deseada.
18 //                                                      * Ejecutar el plan, verificando en cada paso que se vayan cumpliendo las teorias intermedias.
19 //      PLAN:
20 //      PASO:
21
22 class CEntorno ;
23
24 typedef double t_dato ;
25 #define t_fnc(name)             double (*name)(CEntorno&)
26
27
28 #define INFINITO        9999999 //CORREGIR: Poner aca el numero maximo que puede tomar un unsigend long
29
30
31
32 // ------------------------------------------
33 // Parametros de configuracion de SA
34
35
36 // [Ejecutador]
37
38 // Precision en la comparacion de atributos.
39 // Poner en 0 si se quiere hacer la comparacion exacta.
40 #define PRECISION                                                               0.50000
41
42 // Cuando se ejecuta un plan, se espera que al termina el ultimo paso se hallan alcanzado las condiciones finales.
43 // Es posible que las condiciones finales se alcancen en algun paso previo.
44 // Esto permite generar nuevas teorias, pero quita performance al proceso de ejecucion.
45 //#define VERIFICAL_RESULTADOS_EN_CADA_PASO             true
46
47
48 // [Planificador]
49
50 // Cantidad maxima de pasos que puede tener un plan.
51 // Cuanto mas grande sea este numero, mas ciclos puede tardar el proceso de planificacion.
52 // Este valor es un compromiso entre performance y eficiencia.
53 #define PASOS_MAXIMOS_DE_PLAN           20
54
55 // El metodo de planificacion puede encontrar varios planes, y de ellos elige el mejor.
56 // Si se hace seleccionar TODOS los posibles planes, puede tardar demasiado.
57 // Una opcion es determinar una cantidad maxima de posibles planes que se pueden testear.
58 // Este valor es un compromiso entre performance y eficiencia.
59 // Poner INFINITO si se desea deshabilitar esta opcion.
60 #define PLANES_MAXIMOS_TESTEADOS        10
61
62 // Es la minima relacion P/K que puede tener una teoria para considerarse como aceptable.
63 #define TOLERANCIA                                      0.75
64
65
66 // [Heuristicas]
67
68 // Cantidad de ciclos que se recuerda una teoria.
69 // Poner INFINITO si se desea deshabilitar esta opcion.
70 #define CICLOS_DE_MEMORIA                       10
71
72
73
74
75 bool cumple_condiciones (CIndiceMagico<t_dato>&, CIndiceMagico<t_dato>&) ;
76
77
78
79
80 // CTeoria
81 template < typename E >
82 class CTeoria
83 {
84 public:
85
86         std::string                             nombre ;
87
88         // Condiciones iniciales de la teoria.
89         // Cada condicion se representa como un par (clave, valor), que se leen como clave=valor +/- PRECISION.
90         // Las condiciones se concatenan con un operador &&
91         CIndiceMagico<t_dato>   datos_iniciales ;
92         
93         // Condiciones finales que deben cumplirsem luego de ejecutar la funcion final valiendo la condicion inicial
94         CIndiceMagico<t_dato>   datos_finales ;
95
96         // Entorno sobre el cual trabajar
97         E& entorno;
98
99 public:
100
101         CTeoria(const std::string& ini_nombre, 
102                         unsigned long ini_k,
103                         unsigned long ini_p,
104                         E& e):
105                 nombre(ini_nombre),
106                 k(ini_k),
107                 p(ini_p),
108                 entorno(e)
109         {}
110
111         // La funcion que se debe ejecutar para hacer valer la teoria.
112         virtual double funcion() = 0;
113
114 public: 
115         // Cantidad de veces que se probo la teoria.
116         unsigned long                   k ;
117         
118         // Cantidad de veces que se probo la teoria y resulto correcta.
119         unsigned long                   p ;
120
121         // Cantidad de ciclos ocurridos desde que se creo la teoria.
122         // Este parametro se usa para quitarle memoria al SA.
123         unsigned long                   ciclos ;
124
125 } ;
126
127
128
129 // CEntorno
130 class CEntorno
131 {
132 public:
133         CIndiceMagico<t_dato>   datos ;
134
135 public:
136         // Actualizar los datos
137         virtual void actualizar() = 0 ;
138
139         virtual ~CEntorno() {}
140 } ;
141
142
143
144 // CSistemaAutonomo
145 template < typename E >
146 class CSistemaAutonomo
147 {
148 public:
149         // El entono en el que se mueve el SA.
150         E&                              entorno ;
151
152         // Las teorias que tiene el SA.
153         CIndiceMagico< CTeoria< E >* >  teorias ;
154
155         ~CSistemaAutonomo()
156         {
157                 for (int i = 0; i < teorias.m_cant; ++i)
158                 {
159                         delete teorias.m_datos[i];
160                 }
161         }
162
163
164 public:
165         // Retorna true si los valores de la condicion coinciden con los valores del entorno.
166         bool verificar_condicion(CIndiceMagico<t_dato>& datos)
167         {
168                 bool result = true ;
169                 unsigned i ;
170
171
172                 for (i=0; i<datos.count() && result; i++)
173                         result = datos[i] == this->p_entorno->datos.find(datos.keys(i))  ;
174
175
176                 //
177                 return result ;
178         }
179
180
181 protected: 
182
183         // Heuristica de observacion.
184         //      Segun la teoria que se ejecuto, se crea una nueva teoria con TODOS/ALGUNOS valores actuales del entorno como condicion_final.
185         void heurisitca_observacion(CTeoria< E >&)
186         {
187         }
188
189         // Heuristica de correccion por retraccion.
190         //      Si una teoria no se verifico como correcta, se crea una nueva quitandole las condiciones_finales que no se verifican.
191         void heurisitca_retraccion(CTeoria< E >&)
192         {
193         }
194
195
196
197 protected:
198         // Planificador: Se encaga de encontrar una serie de teorias que logren hacer
199         //                              cumplir la condicion_final, partiendo de la condicion_inicial.
200         // Parametros:
201         //              datos_iniciales: Forman la condicion inicial.
202         //              datos_finales:   Forman la condicion final.
203         CIndiceMagico<CTeoria< E >* >*          planificar (
204                         CIndiceMagico<t_dato>&  datos_iniciales,
205                         CIndiceMagico<t_dato>&  datos_finales,
206                         CIndiceMagico<CTeoria< E >* >& plan,
207                         unsigned long numero_de_llamada,
208                         double& p) ;
209
210 public:
211
212         CSistemaAutonomo(E& e): entorno(e) {}
213
214         CIndiceMagico<CTeoria< E >* >* new_plan(CIndiceMagico< t_dato >& datos_finales, double& p)
215         {
216                 CIndiceMagico<CTeoria< E >* >   plan ;
217                 return planificar(entorno.datos, datos_finales, plan, 0, p) ;
218         }
219
220
221         // Ejecuta una serie de pasos.
222         // Retorna true si se alcanza la condicion final.
223         bool ejecutar (CIndiceMagico<CTeoria< E > >& plan) ;
224
225
226 } ;
227
228
229 //--------------------------------------------------------------------------------------------
230 //-- PROBAR BIEN
231 template < typename E >
232 CIndiceMagico< CTeoria< E >* >* CSistemaAutonomo< E >::planificar (
233                 CIndiceMagico< t_dato >&        datos_iniciales,
234                 CIndiceMagico< t_dato >&        datos_finales,
235                 CIndiceMagico< CTeoria< E >* >& plan,
236                 unsigned long numero_de_llamada,
237                 double& p)
238 {
239         unsigned                                                                        i ;
240         double                                                                          nuevo_p ; 
241         double                                                                          max_p = 0 ;
242         CIndiceMagico< CTeoria< E >* >*                                         p_nuevo_plan ;
243         CIndiceMagico< CTeoria< E >* >*                                         pResult = NULL ;
244         CIndiceMagico< CIndiceMagico< CTeoria< E >* > >         planes ;
245         
246
247         for (i=0; i<this->teorias.count(); i++)
248         {
249                 // Si la teoria cumple la condicion inicial
250                 if ( cumple_condiciones(this->teorias[i]->datos_iniciales, datos_iniciales) )
251                 {
252                         p_nuevo_plan = new CIndiceMagico< CTeoria< E >* > ;
253
254                         nuevo_p = ( p + ((double)this->teorias[i]->p) / ((double)this->teorias[i]->k) ) / 2 ;
255                         
256                         // Agrego la teoria al plan
257                         p_nuevo_plan->add (this->teorias[i]->nombre.c_str(), this->teorias[i]) ;
258                         
259                         if (numero_de_llamada<PASOS_MAXIMOS_DE_PLAN)
260                         {
261                                 // Pero si no cumple con la condicion final
262                                 if ( !cumple_condiciones(datos_finales, this->teorias[i]->datos_finales) )
263                                 {
264                                         planificar (this->teorias[i]->datos_finales,
265                                                                 datos_finales,
266                                                                 *p_nuevo_plan,
267                                                                 numero_de_llamada+1,
268                                                                 nuevo_p) ;
269                                 }
270                         }
271
272                 
273                         // Si cumple con la condicion final
274                         if (nuevo_p>max_p)
275                         {
276                                 if ( cumple_condiciones(datos_finales, (*p_nuevo_plan)[p_nuevo_plan->count()-1]->datos_finales) )
277                                 {
278                                         max_p = nuevo_p ;
279
280                                         if (pResult) delete pResult ;
281                                         
282                                         pResult = p_nuevo_plan ;
283                                 }
284                         }
285                 }       
286         }
287
288         //
289         return pResult ;
290 }
291
292
293 //--------------------------------------------------------------------------------------------
294 //--
295 template < typename E >
296 bool CSistemaAutonomo< E >::ejecutar (CIndiceMagico<CTeoria< E > >& plan)
297 {
298         bool result = true ;
299         int i ;
300         CTeoria< E > t ;        
301
302
303         for (i=0; i<plan.count() && result; i++)
304         {
305                 t = plan[i] ;
306
307                 // Ejecuto la funcion
308                 t.funcion() ;
309
310                 // Incremento el K
311                 t.k++ ;
312
313                 // Actualizo los datos del entorno
314                 this->p_entorno->actualizar() ;
315
316                 // Veo si se verifica la condicion final
317                 result = this->verificar_condicion(t.datos_finales) ;
318
319                 // Si fallo la teoria
320                 if (!result)
321                 {
322                         // Aplico heuristicas de correccion
323                         this->heurisitca_retraccion(t) ;
324                 }
325                 else
326                 {
327                         t.p++ ;
328                 }
329
330                 // Aplico heuristicas de observacion
331                 this->heurisitca_observacion(t) ;
332         }
333
334         //
335         return result ;
336 }
337
338
339
340 #endif
341