Foros del Web » Programación para mayores de 30 ;) » C/C++ »

problema algoritmo genetico

Estas en el tema de problema algoritmo genetico en el foro de C/C++ en Foros del Web. bueno, he terminado la implementacion de un algoritmo genetico sencillo. le das un numero y te devuelve una cadena con una manera d llegar a ...
  #1 (permalink)  
Antiguo 29/08/2010, 12:07
 
Fecha de Ingreso: noviembre-2009
Mensajes: 186
Antigüedad: 14 años, 5 meses
Puntos: 2
problema algoritmo genetico

bueno, he terminado la implementacion de un algoritmo genetico sencillo. le das un numero y te devuelve una cadena con una manera d llegar a ese numero.
por ejemplo, si el numero es 10 una posible solucion es "2*5" o "2+2+2+2+2" o "100/10", etc.

sin embargo, hay un punto del programa en el que salta"This application requested the Runtime to terminate in an unusual way. please contact..." y termina devolvieno 3 (el programa).

con un depurador he llegado al punto en el que se produce el error. este me dice "In __cxa_throw () ()". aparece en el bucle de la linea 122 .

bueno, este es el codigo:
Código C++:
Ver original
  1. #include <iostream>
  2. #include <string>
  3. #include <math.h>
  4. #include <time.h>
  5. #include <stdlib.h>
  6.  
  7. #define CROMO_LON 300
  8. #define GEN_LON 4
  9. #define TAM_POBLACION 300
  10. #define PROB_MUTAR 0.01
  11. #define PROB_CRUCE 0.75
  12. #define MAX_GENERACIONES 400
  13. #define NUM_ALE ((float)rand() / (RAND_MAX+1))
  14.  
  15. using namespace std;
  16. using std::string;
  17.  
  18. /* TABLA DE VALORES:
  19.     * 0000 -> 0
  20.     * 0001 -> 1
  21.     * 0010 -> 2
  22.     * 0011 -> 3
  23.     * 0100 -> 4
  24.     * 0101 -> 5
  25.     * 0110 -> 6
  26.     * 0111 -> 7
  27.     * 1000 -> 8
  28.     * 1001 -> 9
  29.     * 1010 -> +
  30.     * 1011 -> -
  31.     * 1100 -> *
  32.     * 1101 -> /
  33.     * 1110 -> NADA (se toman precauciones para que no sea tomado en cuenta)
  34.     * 1111 -> NADA (se toman precauciones para que no sea tomado en cuenta)
  35.  */
  36.  
  37.  
  38. // Prototipos
  39.  
  40.  
  41.  
  42. struct cromosoma{//unidad basica
  43.     string bits;
  44.  
  45.     float aptitud;
  46.  
  47.     cromosoma(): bits(""), aptitud(0.0f) {};
  48.     cromosoma(string m_bits, float m_aptitud): bits(m_bits), aptitud(m_aptitud){};
  49. };
  50.  
  51.  
  52. void MuestraSimboloGen(int valor);
  53. int BinaDec(string bits);
  54. int analiza_cromo(string bits, int *buffer);
  55. void MuestraCromo(string cromosoma);
  56. string genes_aleatorios(int longitud);
  57. float determina_aptitud(string bits, int deseado);
  58. void mutar(string &bits);
  59. void cruce(string &descendencia1, string &descendencia2);
  60. string ruleta(int aptitud_total, cromosoma* poblacion);
  61.  
  62.  
  63. int main(){
  64.  
  65.     srand((int)time(NULL));
  66.  
  67.     while(true){ //nunca acaba... a no ser que lo cierres :)
  68.  
  69.         cromosoma poblacion[TAM_POBLACION]; //nuestra particular poblacion
  70.  
  71.         float objetivo;
  72.  
  73.         cout<<"\nDame un número: ";
  74.         cin>>objetivo;
  75.         cout << endl << endl;
  76.  
  77.         //creamos la poblacion, con unos genes aleatorios y una aptitud 0
  78.  
  79.         for(int i=0; i<TAM_POBLACION; i++){
  80.  
  81.             poblacion[i].bits = genes_aleatorios(CROMO_LON);
  82.             poblacion[i].aptitud = 0.0f;
  83.         }
  84.  
  85.        int GeneracionesHastaSolucion = 0;
  86.  
  87.        int encontrado = 0; //flag para saber si se ha encontrado una solución
  88.  
  89.        while(!encontrado){
  90.  
  91.            float AptitudTotal = 0.0f;
  92.  
  93.            //actualizamos todas las aptitudes
  94.  
  95.            for(int i=0; i<TAM_POBLACION; i++){
  96.  
  97.                poblacion[i].aptitud = determina_aptitud(poblacion[i].bits, objetivo);
  98.  
  99.                AptitudTotal += poblacion[i].aptitud;
  100.            }
  101.  
  102.            for(int i=0; i<TAM_POBLACION; i++){
  103.  
  104.                if(poblacion[i].aptitud == 999.0f){
  105.  
  106.                    cout<<"\n¡Solucion encontrada en "<<GeneracionesHastaSolucion<<"generaciones!"<<endl<<endl;
  107.  
  108.                    MuestraCromo(poblacion[i].bits);
  109.  
  110.                    encontrado = 1;
  111.  
  112.                    break;
  113.                }
  114.            }
  115.  
  116.            //creamos la nueva poblacion. para ello necesitamos una "memoria intermedia"
  117.  
  118.            cromosoma temp[TAM_POBLACION];
  119.  
  120.            int pobl = 0;
  121.  
  122.            while(pobl<TAM_POBLACION){
  123.  
  124.                // creamos la poblacion a pares, selecionandolos con la ruleta
  125.                // y mas tarde cruzandolos y mutandolos
  126.  
  127.                string descendencia1 = ruleta(AptitudTotal, poblacion);
  128.                string descendencia2 = ruleta(AptitudTotal, poblacion);
  129.  
  130.                cruce(descendencia1, descendencia2);
  131.  
  132.                mutar(descendencia1);
  133.                mutar(descendencia2);
  134.  
  135.                //ahora les añadimos a la nueva poblacion, con una aptitud de 0
  136.  
  137.                temp[pobl++] = cromosoma(descendencia1, 0.0f);
  138.                temp[pobl++] = cromosoma(descendencia2, 0.0f);
  139.  
  140.            } //fin del bucle
  141.  
  142.            //copiamos la poblacion temporal en la real
  143.            for(int i=0; i<TAM_POBLACION; i++){
  144.  
  145.                poblacion[i] = temp[i];
  146.            }
  147.  
  148.            GeneracionesHastaSolucion++;
  149.  
  150.            if(GeneracionesHastaSolucion>MAX_GENERACIONES){
  151.                cout<<"no se encontro ninguna solucion en "<<MAX_GENERACIONES<<" generaciones";
  152.  
  153.                encontrado = 1;
  154.            }
  155.        }
  156.  
  157.        cout<<"\n\n\n";
  158.     } //fin while
  159.  
  160.     return 0;
  161. }
  162.  
  163. void MuestraSimboloGen(int valor){
  164.  
  165.     if(valor<10)
  166.         cout<<valor<<" ";
  167.     else
  168.         switch(valor){
  169.  
  170.             case 10:
  171.                 cout<<"+";
  172.                 break;
  173.  
  174.             case 11:
  175.                 cout<<"-";
  176.                 break;
  177.  
  178.             case 12:
  179.                 cout<<"*";
  180.                 break;
  181.  
  182.             case 13:
  183.                 cout<<"/";
  184.                 break;
  185.         }
  186.         cout<<" ";
  187. }
  188.  
  189.  
  190. int BinaDec(string bits){
  191.     int valor            = 0;
  192.     int valor_a_anyadir   = 1;
  193.  
  194.     for (int i = bits.length(); i > 0; i--)
  195.     {
  196.  
  197.  
  198.         if (bits.at(i-1) == '1')
  199.  
  200.             valor += valor_a_anyadir;
  201.  
  202.         valor_a_anyadir *= 2;
  203.  
  204.     }//siguiente bit
  205.  
  206.     return valor;
  207. }
  208.  
  209.  
  210. int analiza_cromo(string bits, int *buffer){
  211.      int posBuff = 0;
  212.  
  213.      int gen;
  214.  
  215.      int tipo = 1; // 1 si el valor es un numero, 0 si es operador
  216.  
  217.      for (int i=0; i<CROMO_LON; i+=GEN_LON){
  218.          gen=BinaDec(bits.substr(i, GEN_LON));
  219.  
  220.          if(tipo){
  221.              if((gen>13) || (gen<16))
  222.                  continue;
  223.  
  224.              else{
  225.                  tipo=0;
  226.                  buffer[posBuff++] = gen;
  227.              }
  228.          }
  229.  
  230.  
  231.          else{
  232.  
  233.             if(gen>9)
  234.                 continue;
  235.  
  236.  
  237.             else{
  238.  
  239.                 tipo=1;
  240.                 buffer[posBuff++] = gen;
  241.                      continue;
  242.                  }
  243.              }
  244.          } //nuevo gen
  245.  
  246.      // tratamiento de errores: comprobamos si existe una posible division entre 0
  247.     //  de ser asi transformamos en '/' en '+'. simple pero eficaz
  248.  
  249.     for(int i=0; i<posBuff; i++){
  250.         if((buffer[i] == 13) && (buffer[i+1] == 0) ){
  251.  
  252.             buffer[i] = 10;
  253.         }
  254.     }
  255.  
  256.     return posBuff;
  257. }
  258.  
  259.  
  260. void MuestraCromo(string cromosoma){
  261.         int buffer[CROMO_LON/GEN_LON];
  262.  
  263.         int num_elementos = analiza_cromo(cromosoma, buffer);
  264.  
  265.         for(int i=0; i<num_elementos; i++){
  266.             MuestraSimboloGen(buffer[i]);
  267.         }
  268. }
  269.  
  270.  
  271. string genes_aleatorios(int longitud){
  272.  
  273.     string bits;
  274.  
  275.     for(int i=0; i<=longitud; i++){
  276.         if(NUM_ALE>0.5f)
  277.             bits +="1";
  278.  
  279.         else
  280.             bits +="0";
  281.         }
  282.         return bits;
  283. }
  284.  
  285.  
  286. float determina_aptitud(string bits, int deseado){
  287.  
  288.     int buffer[CROMO_LON/GEN_LON];
  289.  
  290.     int num_elementos = analiza_cromo(bits, buffer);
  291.  
  292.     float resultado = 0.0f;
  293.  
  294.     for(int i=0; i<num_elementos-1; i+=2){
  295.  
  296.         switch(buffer[i]){
  297.  
  298.             case 10:
  299.                 resultado += buffer[i+1];
  300.                 break;
  301.  
  302.             case 11:
  303.                 resultado -= buffer[i+1];
  304.                 break;
  305.  
  306.             case 12:
  307.                 resultado *= buffer[i+1];
  308.                 break;
  309.  
  310.             case 13:
  311.                 resultado /= buffer[i+1];
  312.                 break;
  313.  
  314.         } //switch
  315.  
  316.     }
  317.  
  318.     // comprobamos si el resultado coincide con el deseado
  319.     // si no coincide se asigna una aptitud, mas alta cuanto mas
  320.     // se aproxime al resultado deseado, de esta manera casi nos aseguramos
  321.     // de que pase a la siguente generacion
  322.  
  323.     if(resultado == (float)deseado)
  324.  
  325.         return 999.0f; //exito
  326.  
  327.     else return 1/((float)fabs((double)(deseado - resultado))); // aptitud
  328.  
  329. }
  330.  
  331.  
  332. void mutar(string &bits){
  333.  
  334.     for(int i=0; i<=bits.length(); i++){
  335.  
  336.         if(NUM_ALE < PROB_MUTAR){
  337.  
  338.             bits.at(i) == 1 ? bits.at(i) = 0 : bits.at(i) = 1;
  339.         }
  340.     }
  341. }
  342.  
  343.  
  344. void cruce(string &descendencia1, string &descendencia2){
  345.  
  346.     if(NUM_ALE < PROB_CRUCE){
  347.  
  348.         int punto = (int) (NUM_ALE * CROMO_LON);
  349.         string t1 = descendencia1.substr(0, punto) + descendencia2.substr(punto, CROMO_LON);
  350.         string t2 = descendencia2.substr(0, punto) + descendencia1.substr(punto, CROMO_LON);
  351.  
  352.         descendencia1 = t1; descendencia2 = t2;
  353.     }
  354. }
  355.  
  356.  
  357. string ruleta(int aptitud_total, cromosoma* poblacion){
  358.  
  359.     // numero aleatorio entre 0 y la aptitud total
  360.     float porcion = (float) (NUM_ALE * aptitud_total);
  361.  
  362.     //acumula las aptutudes
  363.     float AptitudHastaAhora = 0.0f;
  364.  
  365.     for(int i=0; i<TAM_POBLACION; i++){
  366.  
  367.         AptitudHastaAhora = poblacion[i].aptitud;
  368.  
  369.         if(AptitudHastaAhora >= porcion)
  370.  
  371.             return poblacion[i].bits;
  372.     }
  373.  
  374.     return "";
  375. }

agradeceria toda la ayuda posible
  #2 (permalink)  
Antiguo 29/08/2010, 19:57
 
Fecha de Ingreso: mayo-2008
Ubicación: Chile
Mensajes: 189
Antigüedad: 15 años, 11 meses
Puntos: 3
Respuesta: problema algoritmo genetico

lo compile y me da error justo aqui : cruce(descendencia1, descendencia2);
(puse un system pause antes y despues de eso, por eso se que ahi es el error)
__________________
si tienes entre 18 y 20 años... entonces tienes 19 años xD
  #3 (permalink)  
Antiguo 30/08/2010, 05:47
 
Fecha de Ingreso: noviembre-2009
Mensajes: 186
Antigüedad: 14 años, 5 meses
Puntos: 2
Respuesta: problema algoritmo genetico

gracias :) . me pondre a revisar esa funcion.
  #4 (permalink)  
Antiguo 03/09/2010, 08:49
 
Fecha de Ingreso: septiembre-2010
Mensajes: 60
Antigüedad: 13 años, 7 meses
Puntos: 5
Respuesta: problema algoritmo genetico

No tiene nada que ver, pero en la línea 250 creo que el acceso a buffer[i+1] en la última iteración se sale de rango.
  #5 (permalink)  
Antiguo 03/09/2010, 09:28
 
Fecha de Ingreso: septiembre-2010
Mensajes: 60
Antigüedad: 13 años, 7 meses
Puntos: 5
Respuesta: problema algoritmo genetico

Ya encontré el problema:

en ruleta(), devuelves a menudo como cromosoma "" (cromosoma vacío).
Cuando devuelves uno de estos, al entrar en cruce() se buscan subcadenas.
La llamada a substr casca con out_of_range si el indice inicial está fuera de la cadena. En la cadena vacía, al acceder como índice a 'punto' que se supone mayor que 0, casca.

Por cierto, es mejor si pones la línea 13 así:

Código C:
Ver original
  1. #define NUM_ALE ((float)rand() / ((float)RAND_MAX+1))

para que no se queje :)
  #6 (permalink)  
Antiguo 07/09/2010, 15:12
 
Fecha de Ingreso: noviembre-2009
Mensajes: 186
Antigüedad: 14 años, 5 meses
Puntos: 2
Respuesta: problema algoritmo genetico

hola, siento no haber podido contestar antes. os agradezco mucho la ayuda a los 2 . voy a corregir el error y postearé el código completo.

Etiquetas: algoritmos
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 16:34.