X-Git-Url: https://git.llucax.com/z.facultad/75.68/celdas.git/blobdiff_plain/44029734cc5263d0548dc78ce9d71c43719d1ea7..3d6b50d2b60ae819d5879c844639ab78f3a4731e:/trunk/src/sistemaautonomo.cpp?ds=inline diff --git a/trunk/src/sistemaautonomo.cpp b/trunk/src/sistemaautonomo.cpp index f4cbbab..7469d10 100644 --- a/trunk/src/sistemaautonomo.cpp +++ b/trunk/src/sistemaautonomo.cpp @@ -1,22 +1,346 @@ #include "sistemaautonomo.h" +#include + +#ifdef DEBUG +#include +#endif // DEBUG //-------------------------------------------------------------------------------------------- //-- Funciones Auxiliares +bool incluye_a (CIndiceMagico& a, CIndiceMagico& b) +{ + bool result = true ; + unsigned i ; + + // Todas las variables de la condicion b deben estar en la condicion a + for (i=0; idatos << "\n"; + std::cout << "SA: \tdatos finales:\n" << m_datos_finales << "\n"; +#endif // DEBUG + planificar(p_entorno->datos, m_datos_finales, m_plan, p); +#ifdef DEBUG + std::cout << "SA: \tplan:\n" << m_plan << "\n"; +#endif // DEBUG + curr_theory = m_plan.begin(); +#ifdef DEBUG + if (curr_theory == m_plan.end()) + std::cout << "SA: No hay teorías\n"; + else + std::cout << "SA: curr teoria: " << **curr_theory << "\n"; +#endif // DEBUG +} +//-------------------------------------------------------------------------------------------- +//-- +bool CSistemaAutonomo::has_next_theory() +{ + return curr_theory != m_plan.end(); +} -bool cumple_condiciones (CIndiceMagico& muestra, CIndiceMagico& patron) +//-------------------------------------------------------------------------------------------- +//-- +CTeoria* CSistemaAutonomo::get_next_theory() { + if (curr_theory == m_plan.end()) + { + m_datos_finales.clear(); + return 0; + } + else + { + return *(curr_theory++); + } +} + +//-------------------------------------------------------------------------------------------- +//-- +bool CSistemaAutonomo::validate_theory(CTeoria* t) +{ + bool result ; + + // Aumento k (cantidad de veces que se probó la teoría + ++t->k; + // Verifico + result = verificar_condicion(t->datos_finales) ; + + // Si se ejecuto bien la teoria incremento el p + if (result) t->p++ ; + + // Si fallo la teoria + if (!result) + { + // Aplico heuristicas de observacion +#ifdef DEBUG + std::cout << "SA: No verifica, aplicando heuristicas...\n"; + std::cout << "SA: Aplicando heuristica de observacion\n"; +#endif // DEBUG + this->heuristca_observacion(*t) ; +#ifdef DEBUG + std::cout << "SA: Aplicando heuristica de generalizacion\n"; +#endif // DEBUG + this->heuristca_generalizacion(*t); +#ifdef DEBUG + std::cout << "SA: Aplicando heuristica de retraccion\n"; +#endif // DEBUG + // Aplico heuristicas de correccion + this->heuristca_retraccion(*t) ; + } + + return result; +} + + +//-------------------------------------------------------------------------------------------- +//-- +bool CSistemaAutonomo::verificar_condicion(CIndiceMagico& datos) +{ bool result = true ; unsigned i ; - for (i=0; ip_entorno->datos.find(datos.keys(i))); - // return result ; +} +std::string make_nombre(const std::string& n, char mod, unsigned i) +{ + std::ostringstream oss; + oss << n << "-" << mod << i; + return oss.str(); } +//-------------------------------------------------------------------------------------------- +//-- +void CSistemaAutonomo::heuristca_observacion(CTeoria& t) +{ + CTeoria* pnt = new CTeoria ; //Nueva Teoria + CTeoria& nt = *pnt; + + // Le agrego los datos iniciales tal cual estaban antes + nt.datos_iniciales = t.datos_iniciales; + + // Le agrego todas las condiciones del entorno como condicion final + nt.datos_finales = p_entorno->datos; + + // Le cargo nombre y funcion (queda con k=1 y p=1) + nt.nombre = make_nombre(t.nombre, 'o', teorias.count()); + nt.funcion = t.funcion; + + // Agrego la teoria + teorias.add (nt.nombre, pnt) ; +#ifdef DEBUG + std::cout << "SA: Se agrego una nueva teoria: " << nt << " basada en " << t << "\n"; + std::cout << "SA: \tdatos_iniciales:\n" << nt.datos_iniciales << "\n"; + std::cout << "SA: \tdatos_finales:\n" << nt.datos_finales << "\n"; +#endif // DEBUG + +} + +//-------------------------------------------------------------------------------------------- +//-- +// Si las condiciones finales del entorno son iguales a las condiciones finales de alguna teoria y +// solo una condicion inicial es distinta => agrego una nueva teoría igual (a la q cumple los requisitos +// anteriormente detallados) pero tomando ANY en el valor de entrada en el cual difieren. +void CSistemaAutonomo::heuristca_generalizacion(CTeoria& t) +{ + unsigned i ; + int count = 0; + unsigned k = 0; + unsigned j = 0; + int posicionCambio = -1; + unsigned cantidadTeorias = 0; + std::string nombreTeoria; + + cantidadTeorias = this->teorias.count(); + + for (i = 0; i < cantidadTeorias; i++) + { + for (k = 0; k < this->teorias[i]->datos_finales.count(); k++) + { + //me fijo si las condiciones finales de la teoria se corresponden con la del entorno. + if ((this->teorias[i]->datos_finales[k] != ANY) && (this->p_entorno->datos.find(t.datos_finales.keys(k)) != ANY)) + { + if (this->teorias[i]->datos_finales[k] != this->p_entorno->datos.find(t.datos_finales.keys(k))) + { + count++; + } + } + } + if (count == 0) + { // si se corresponden (las condiciones finales son iguales) => me fijo si hay alguna condicion inicial q cambia. + for (j = 0; j < this->teorias[i]->datos_iniciales.count(); j++) + { + if ((this->teorias[i]->datos_iniciales[j] != ANY) && (this->p_entorno->datos.find(t.datos_iniciales.keys(j)) != ANY)) + { + if (this->teorias[i]->datos_iniciales[j] != this->p_entorno->datos.find(t.datos_iniciales.keys(j))) + { + posicionCambio = j; + count++; + } + } + } + if (count == 1) + { + //si cambia solo una => creo una nueva teoria igual pero con ANY en la condicion q cambia. + CTeoria* nt = new CTeoria ; //Nueva Teoria + *nt = *this->teorias[i]; + nt->datos_iniciales[posicionCambio] = ANY; + + // Agrego la teoria + nt->nombre = make_nombre(t.nombre, 'g', teorias.count()); + teorias.add (nt->nombre, nt) ; +#ifdef DEBUG + std::cout << "SA: Se agrego una nueva teoria: " << *nt << " basada en " << *teorias[i] << "\n"; + std::cout << "SA: \tdatos_iniciales:\n" << nt->datos_iniciales << "\n"; + std::cout << "SA: \tdatos_finales:\n" << nt->datos_finales << "\n"; +#endif // DEBUG + } + } + posicionCambio = -1; + count = 0; + } +} + +//-------------------------------------------------------------------------------------------- +//-- +void CSistemaAutonomo::heuristca_retraccion(CTeoria& t) +{ + unsigned i ; + unsigned modif = (unsigned)-1; + + // Recorro la condicion final de la teoria + for (i = 0; i < t.datos_finales.count(); i++) + { + // Si el dato no coincidio con el del entorno, y no era ANY + if (t.datos_finales[i] != ANY && + t.datos_finales[i] != this->p_entorno->datos.find(t.datos_finales.keys(i))) + { + // Le asigno ANY + t.datos_finales[i] = ANY ; + modif = i; + } + } + if (modif != (unsigned)-1) + { + // Le cambio el nombre para indicar que fue modificada + t.nombre += "-r"; +#ifdef DEBUG + std::cout << "SA: Se modifica la teoria: " << t << ", el dato final '" + << t.datos_finales.keys(modif) << "' puede tomar ahora cualquier valor\n"; +#endif // DEBUG + } +} + + +//-------------------------------------------------------------------------------------------- +//-- +void CSistemaAutonomo::planificar (CIndiceMagico& datos_iniciales, + CIndiceMagico& datos_finales, + CIndiceMagico& plan, + double& p, + unsigned long numero_de_llamada) +{ + unsigned i; + CIndiceMagico test_plan ; + CIndiceMagico new_plan ; + double test_p ; + double max_p = 0 ; + + + if ( incluye_a(datos_iniciales, datos_finales) ) return ; + + if ( numero_de_llamada > 7 ) return ; + + for (i = 0; i < teorias.count(); i++) + if ( incluye_a(teorias[i]->datos_iniciales, datos_iniciales) ) + { + test_plan.clear() ; + test_plan.add (teorias[i]->nombre, teorias[i]) ; + + test_p = p * ((double)teorias[i]->p)/((double)teorias[i]->k) ; + + planificar(teorias[i]->datos_finales, datos_finales, test_plan, test_p, numero_de_llamada+1) ; + + if ( test_p>max_p ) + if ( incluye_a(test_plan[test_plan.count()-1]->datos_finales, datos_finales) ) + { + max_p = test_p ; + new_plan.clear() ; + new_plan.add (test_plan) ; + } + } + + if (max_p>0) + plan.add (new_plan) ; +} + + +/* +//-------------------------------------------------------------------------------------------- +//-- +bool CSistemaAutonomo::ejecutar (CIndiceMagico& plan) +{ + bool result = true ; + unsigned i ; + t_fnc(pFnc) ; + CTeoria t ; + + + for (i=0; ip_entorno)) ; + + // 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->heuristca_retraccion(t) ; + } + else + { + t.p++ ; + } + + // Aplico heuristicas de observacion + this->heuristca_observacion(t) ; + this->heuristca_generalizacion(t); + } + + // + return result ; +} +*/