]> git.llucax.com Git - z.facultad/75.68/celdas.git/blob - trunk/src/sistemaautonomo.cpp
Evitamos memory leaks.
[z.facultad/75.68/celdas.git] / trunk / src / sistemaautonomo.cpp
1
2 #include "sistemaautonomo.h"
3 #include <sstream>
4
5 #ifdef DEBUG
6 #include <iostream>
7 #endif // DEBUG
8
9
10 //--------------------------------------------------------------------------------------------
11 //-- Funciones Auxiliares
12 bool incluye_a (CIndiceMagico<t_dato>& a, CIndiceMagico<t_dato>& b) 
13 {
14         bool result = true ;
15         unsigned i ;
16
17         // Todas las variables de la condicion b deben estar en la condicion a
18         for (i=0; i<b.count() && result; i++)
19                 result=a.exist(b.keys(i)) ;
20
21         // Todas las variables de la condicion a deben tener el mismo valor que en la condicion b
22         for (i=0; i<b.count() && result; i++)
23                 result = b[i] == a.find(b.keys(i)) || b[i] == ANY || a.find(b.keys(i)) == ANY  ;
24         //
25         return result ;
26 }
27
28 //--------------------------------------------------------------------------------------------
29 //--
30 void CSistemaAutonomo::plan()
31 {
32         double p = 1.0;
33         m_plan.clear();
34 #ifdef DEBUG
35         std::cout << "SA: Planificando...\n";
36         std::cout << "SA: \tentorno:\n" << p_entorno->datos << "\n";
37         std::cout << "SA: \tdatos finales:\n" << m_datos_finales << "\n";
38 #endif // DEBUG
39         planificar(p_entorno->datos, m_datos_finales, m_plan, p);
40 #ifdef DEBUG
41         std::cout << "SA: \tplan:\n" << m_plan << "\n";
42 #endif // DEBUG
43         curr_theory = m_plan.begin();
44 #ifdef DEBUG
45         if (curr_theory == m_plan.end())
46                 std::cout << "SA: No hay teorías\n";
47         else
48                 std::cout << "SA: curr teoria: " << **curr_theory << "\n";
49 #endif // DEBUG
50 }
51
52 //--------------------------------------------------------------------------------------------
53 //--
54 bool CSistemaAutonomo::has_next_theory()
55 {
56         return curr_theory != m_plan.end();
57 }
58
59 //--------------------------------------------------------------------------------------------
60 //--
61 CTeoria* CSistemaAutonomo::get_next_theory()
62 {
63         if (curr_theory == m_plan.end())
64         {
65                 m_datos_finales.clear();
66                 return 0;
67         }
68         else
69         {
70                 return *(curr_theory++);
71         }
72 }
73
74 //--------------------------------------------------------------------------------------------
75 //--
76 bool CSistemaAutonomo::validate_theory(CTeoria* t)
77 {
78         bool result ;
79
80         // Aumento k (cantidad de veces que se probó la teoría
81         ++t->k;
82
83         // Verifico
84         result = verificar_condicion(t->datos_finales) ;
85
86         // Si se ejecuto bien la teoria incremento el p
87         if (result) t->p++ ;
88
89         // Si fallo la teoria
90         if (!result)
91         {
92                 // Aplico heuristicas de observacion
93 #ifdef DEBUG
94                 std::cout << "SA: No verifica, aplicando heuristicas...\n";
95                 std::cout << "SA: Aplicando heuristica de observacion\n";
96 #endif // DEBUG
97                 this->heuristca_observacion(*t) ;
98 #ifdef DEBUG
99                 std::cout << "SA: Aplicando heuristica de generalizacion\n";
100 #endif // DEBUG
101                 this->heuristca_generalizacion(*t);
102 #ifdef DEBUG
103                 std::cout << "SA: Aplicando heuristica de retraccion\n";
104 #endif // DEBUG
105                 // Aplico heuristicas de correccion
106                 this->heuristca_retraccion(*t) ;
107         }
108
109         return result;
110 }
111
112
113 //--------------------------------------------------------------------------------------------
114 //--
115 bool CSistemaAutonomo::verificar_condicion(CIndiceMagico<t_dato>&       datos)
116 {
117         bool result = true ;
118         unsigned i ;
119
120         for (i = 0; i < datos.count() && result; i++)
121                 result = (datos[i] == ANY || datos[i] == this->p_entorno->datos.find(datos.keys(i)));
122
123         return result ;
124 }
125
126 std::string make_nombre(const std::string& n, char mod, unsigned i)
127 {
128         std::ostringstream oss;
129         oss << n << "-" << mod << i;
130         return oss.str();
131 }
132
133 //--------------------------------------------------------------------------------------------
134 //--
135 void CSistemaAutonomo::heuristca_observacion(CTeoria& t)
136 {
137         CTeoria* pnt = new CTeoria ; //Nueva Teoria
138         CTeoria& nt = *pnt;
139
140         // Le agrego los datos iniciales tal cual estaban antes
141         nt.datos_iniciales = t.datos_iniciales;
142
143         // Le agrego todas las condiciones del entorno como condicion final
144         nt.datos_finales = p_entorno->datos;
145
146         // Le cargo nombre y funcion (queda con k=1 y p=1)
147         nt.nombre = make_nombre(t.nombre, 'o', teorias.count());
148         nt.funcion = t.funcion;
149
150         // Agrego la teoria
151         teorias.add (nt.nombre, pnt) ;
152 #ifdef DEBUG
153         std::cout << "SA: Se agrego una nueva teoria: " << nt << " basada en " << t << "\n";
154         std::cout << "SA: \tdatos_iniciales:\n" << nt.datos_iniciales << "\n";
155         std::cout << "SA: \tdatos_finales:\n" << nt.datos_finales << "\n";
156 #endif // DEBUG
157
158 }
159
160 //--------------------------------------------------------------------------------------------
161 //--
162 // Si las condiciones finales del entorno son iguales a las condiciones finales de alguna teoria y
163 // solo una condicion inicial es distinta => agrego una nueva teoría igual (a la q cumple los requisitos
164 // anteriormente detallados) pero tomando ANY en el valor de entrada en el cual difieren.  
165 void CSistemaAutonomo::heuristca_generalizacion(CTeoria& t)
166 {
167         unsigned i ;
168         int count = 0;
169         unsigned k = 0;
170         unsigned j = 0;
171         int posicionCambio = -1;
172         unsigned cantidadTeorias = 0;
173         std::string nombreTeoria;
174
175         cantidadTeorias = this->teorias.count();
176
177         for (i = 0; i < cantidadTeorias; i++)
178         {
179                 for (k = 0; k < this->teorias[i]->datos_finales.count(); k++)
180                 {
181                         //me fijo si las condiciones finales de la teoria se corresponden con la del entorno.
182                         if ((this->teorias[i]->datos_finales[k] != ANY) && (this->p_entorno->datos.find(t.datos_finales.keys(k)) != ANY))
183                         {
184                                 if (this->teorias[i]->datos_finales[k] != this->p_entorno->datos.find(t.datos_finales.keys(k))) 
185                                 {
186                                         count++;
187                                 }
188                         }
189                 }
190                 if (count == 0)
191                 {       // si se corresponden (las condiciones finales son iguales) => me fijo si hay alguna condicion inicial q cambia. 
192                         for (j = 0; j < this->teorias[i]->datos_iniciales.count(); j++)
193                         {
194                                 if ((this->teorias[i]->datos_iniciales[j] != ANY) && (this->p_entorno->datos.find(t.datos_iniciales.keys(j)) != ANY))
195                                 {
196                                         if (this->teorias[i]->datos_iniciales[j] != this->p_entorno->datos.find(t.datos_iniciales.keys(j))) 
197                                         {
198                                                 posicionCambio = j;
199                                                 count++;
200                                         }
201                                 }
202                         }
203                         if (count == 1)
204                         {
205                                 //si cambia solo una => creo una nueva teoria igual pero con ANY en la condicion q cambia.
206                                 CTeoria* nt = new CTeoria ; //Nueva Teoria
207                                 *nt = *this->teorias[i];
208                                 nt->datos_iniciales[posicionCambio] = ANY;
209
210                                 // Agrego la teoria
211                                 nt->nombre = make_nombre(t.nombre, 'g', teorias.count());
212                                 teorias.add (nt->nombre, nt) ;
213 #ifdef DEBUG
214                                 std::cout << "SA: Se agrego una nueva teoria: " << *nt << " basada en " << *teorias[i] << "\n";
215                                 std::cout << "SA: \tdatos_iniciales:\n" << nt->datos_iniciales << "\n";
216                                 std::cout << "SA: \tdatos_finales:\n" << nt->datos_finales << "\n";
217 #endif // DEBUG
218                         }
219                 }
220                 posicionCambio = -1;
221                 count = 0;
222         }
223 }
224
225 //--------------------------------------------------------------------------------------------
226 //--
227 void CSistemaAutonomo::heuristca_retraccion(CTeoria& t)
228 {
229         unsigned i ;
230         unsigned modif = (unsigned)-1;
231
232         // Recorro la condicion final de la teoria
233         for (i = 0; i < t.datos_finales.count(); i++)
234         {
235                 // Si el dato no coincidio con el del entorno, y no era ANY
236                 if (t.datos_finales[i] != ANY && 
237                                 t.datos_finales[i] != this->p_entorno->datos.find(t.datos_finales.keys(i)))
238                 {
239                         // Le asigno ANY
240                         t.datos_finales[i] = ANY ;
241                         modif = i;
242                 }
243         }
244         if (modif != (unsigned)-1)
245         {
246                 // Le cambio el nombre para indicar que fue modificada
247                 t.nombre += "-r";       
248 #ifdef DEBUG
249                 std::cout << "SA: Se modifica la teoria: " << t << ", el dato final '"
250                         << t.datos_finales.keys(modif) << "' puede tomar ahora cualquier valor\n";
251 #endif // DEBUG
252         }
253 }
254
255
256 //--------------------------------------------------------------------------------------------
257 //--
258 void CSistemaAutonomo::planificar (CIndiceMagico<t_dato>&       datos_iniciales,
259                                 CIndiceMagico<t_dato>&          datos_finales,
260                                 CIndiceMagico<CTeoria*>&        plan,
261                                 double&                         p,
262                                 unsigned long                   numero_de_llamada)
263 {
264         unsigned i;
265         CIndiceMagico<CTeoria*> test_plan ;
266         CIndiceMagico<CTeoria*> new_plan ;
267         double test_p ;
268         double max_p = 0 ;
269
270
271         if ( incluye_a(datos_iniciales, datos_finales) ) return ;
272
273         if ( numero_de_llamada > 7 ) return ;
274
275         for (i = 0; i < teorias.count(); i++)
276                 if ( incluye_a(teorias[i]->datos_iniciales, datos_iniciales) )
277                 {
278                         test_plan.clear() ;
279                         test_plan.add (teorias[i]->nombre, teorias[i]) ;
280
281                         test_p = p * ((double)teorias[i]->p)/((double)teorias[i]->k) ;
282
283                         planificar(teorias[i]->datos_finales, datos_finales, test_plan, test_p, numero_de_llamada+1) ; 
284                         
285                         if ( test_p>max_p )
286                         if ( incluye_a(test_plan[test_plan.count()-1]->datos_finales, datos_finales) )
287                         {
288                                 max_p = test_p ;
289                                 new_plan.clear() ;
290                                 new_plan.add (test_plan) ;
291                         }
292                 }
293
294         if (max_p>0)
295                 plan.add (new_plan) ;
296 }
297
298
299 /*
300 //--------------------------------------------------------------------------------------------
301 //--
302 bool CSistemaAutonomo::ejecutar (CIndiceMagico<CTeoria>& plan)
303 {
304         bool result = true ;
305         unsigned i ;
306         t_fnc(pFnc) ;
307         CTeoria t ;     
308
309
310         for (i=0; i<plan.count() && result; i++)
311         {
312                 t = plan[i] ;
313                 pFnc = t.funcion;
314
315                 // Ejecuto la funcion
316                 (*pFnc)(*(this->p_entorno)) ;
317
318                 // Incremento el K
319                 t.k++ ;
320
321                 // Actualizo los datos del entorno
322                 this->p_entorno->actualizar() ;
323
324                 // Veo si se verifica la condicion final
325                 result = this->verificar_condicion(t.datos_finales) ;
326
327                 // Si fallo la teoria
328                 if (!result)
329                 {
330                         // Aplico heuristicas de correccion
331                         this->heuristca_retraccion(t) ;
332                 }
333                 else
334                 {
335                         t.p++ ;
336                 }
337
338                 // Aplico heuristicas de observacion
339                 this->heuristca_observacion(t) ;
340                 this->heuristca_generalizacion(t);
341         }
342
343         //
344         return result ;
345 }
346 */