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