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