Моя программа работает нормально в режиме отладки, но падает в режиме выпуска, я прочитал похожий вопрос, и кто-то сказал, что это может быть неинициализированная переменная, но я прошел через код и не смог найти какую-либо помощь?
Я выбрал консольное приложение win32, а затем опустел проект и консольное приложение в настройках
Ошибка происходит ПОСЛЕ того, как я прочитал оба файла, и перед отображением сообщения
"Ingrese el margen de error aceptado"
относительное окончание): "
Вот мой код:
#include <fstream>
#include <string.h>
#include <iostream>
#include <stdio.h>
#include <time.h>
#include <math.h>
#define cantidadDeIndividuos 100
#define cantidadDeFilas 255
#define cantidadDeColumnas 255
#define numeroDeBitsDeLaRegla 32
using namespace std;
class Matriz{
private:
unsigned int dm;
int f,c;
bool** matrizDeBits;
unsigned int resultado;
public:
Matriz(){
f=cantidadDeFilas;
c=cantidadDeColumnas;
dm=((unsigned int)f)*((unsigned int)c);
matrizDeBits=new bool*[f];
int cx,cy;
for(cy=0;cy<f;cy++){
matrizDeBits[cy]=new bool[c];
}
for(cy=0;cy<f;cy++){
for(cx=0;cx<c;cx++){
matrizDeBits[cy][cx]=false;
}
}
}
bool getBit(int i, int j){
return matrizDeBits[i][j];
}
void setBit(int i, int j, bool v){
matrizDeBits[i][j]=v;
}
unsigned int comparar(Matriz m1, Matriz m2){
resultado=dm;
int cx,cy;
for(cy=0;cy<f;cy++){
for(cx=0;cx<c;cx++){
if( (m1.getBit(cy,cx)&&m2.getBit(cy,cx)) || ( (!m1.getBit(cy,cx)) && (!m2.getBit(cy,cx))) )
resultado--;
}
}
return resultado;
}
};
class ManejadorDeNumerosAleatorios{
public:
ManejadorDeNumerosAleatorios(){
srand ( (unsigned)time(NULL) );
}
void reInicializar(){
srand ( (unsigned)time(NULL) );
}
bool* obtenerReglaAleatoria(){
bool* resultado=new bool[numeroDeBitsDeLaRegla];
int contador=0;
int numeroAleatorio; // entre 0 y rand_max, el cual es 32768 (2^15)
do{
numeroAleatorio=rand();
while(numeroAleatorio>0){
if( (numeroAleatorio%2) == 1)
resultado[contador]=true;
else
resultado[contador]=false;
numeroAleatorio/=2;
contador++;
}
}while(contador<numeroDeBitsDeLaRegla);
return resultado;
}
short obtenerIteraciones(int maximo){
return ((short)(rand()%maximo));
}
};
class ManejadorDeArchivos{
private:
bool seHaLeidoArchivoDeEntrada;
bool seHaLeidoArchivoDeSalida;
Matriz datosDeEntrada;
Matriz datosDeSalida;
public:
ManejadorDeArchivos(){
seHaLeidoArchivoDeEntrada=false;
seHaLeidoArchivoDeSalida=false;
}
bool noSeHanLeidoLosArchivosNecesarios(){
if(seHaLeidoArchivoDeEntrada&&seHaLeidoArchivoDeSalida)
return false;
return true;
}
Matriz obtenerDatosDeEntrada(){
return datosDeEntrada;
}
Matriz obtenerDatosDeSalida(){
return datosDeSalida;
}
void leerArchivoDeEntrada(){
char nombre[100];
cout<<endl<<"Ingrese el nombre del archivo de entrada: ";
gets(nombre);
ifstream lectura(nombre,ios::beg);
if(!lectura||lectura.bad()){
cout<<"No se ha podido Abrir el archivo, verifique que el nombre sea correcto y que este en la misma carpeta donde se encuentra este ejecutable";
return;
}
char* miLineaLeida=new char[(cantidadDeColumnas+1)];
int contadorDeLineas,cj;
for(contadorDeLineas=0;!lectura.eof();contadorDeLineas++){
if(contadorDeLineas==cantidadDeFilas){
cout<<endl<<"Se han leido correctamente "<<cantidadDeFilas<<" filas del archivo";
break;
}
lectura>>miLineaLeida;
for(cj=0;miLineaLeida[cj]!='\0';cj++){
if(cj==cantidadDeColumnas){
cout<<endl<<"Se ha encontrado una fila que contiene mas de "<<cantidadDeColumnas<<" elementos, lectura fallida. Por favor verifique el contenido del archivo de entrada.";
return;
}
if(miLineaLeida[cj]=='1')
datosDeEntrada.setBit(contadorDeLineas,cj,true);
else if(miLineaLeida[cj]!='0'){
cout<<"Se ha encontrado un caracter distinto de <<1>> o <<0>>";
return;
}
}
if(cj<cantidadDeColumnas){
cout<<"Se ha encontrado una fila con menos caracteres de lo esperado ("<<cantidadDeColumnas<<")";
return;
}
}
lectura.close();
if(contadorDeLineas<cantidadDeFilas){
cout<<"Se ha encontrado una cantidad de lineas menor de lo esperado ("<<cantidadDeFilas<<")";
return;
}
seHaLeidoArchivoDeEntrada=true;
cout<<endl<<"Lectura Exitosa";
}
void leerArchivoDeSalida(){
char nombre[100];
cout<<endl<<"Ingrese el nombre del archivo de salida: ";
gets(nombre);
ifstream lectura(nombre,ios::beg);
if(!lectura||lectura.bad()){
cout<<"No se ha podido Abrir el archivo, verifique que el nombre sea correcto y que este en la misma carpeta donde se encuentra este ejecutable";
return;
}
char* miLineaLeida=new char[(cantidadDeColumnas+1)];
int contadorDeLineas,cj;
for(contadorDeLineas=0;!lectura.eof();contadorDeLineas++){
if(contadorDeLineas==cantidadDeFilas){
cout<<endl<<"Se han leido correctamente "<<cantidadDeFilas<<" filas del archivo";
break;
}
lectura>>miLineaLeida;
for(cj=0;miLineaLeida[cj]!='\0';cj++){
if(cj==cantidadDeColumnas){
cout<<endl<<"Se ha encontrado una fila que contiene mas de "<<cantidadDeColumnas<<" elementos, lectura fallida. Por favor verifique el contenido del archivo de entrada.";
return;
}
if(miLineaLeida[cj]=='1')
datosDeSalida.setBit(contadorDeLineas,cj,true);
else if(miLineaLeida[cj]!='0'){
cout<<"Se ha encontrado un caracter distinto de <<1>> o <<0>>";
return;
}
}
if(cj<cantidadDeColumnas){
cout<<"Se ha encontrado una fila con menos caracteres de lo esperado ("<<cantidadDeColumnas<<")";
return;
}
}
lectura.close();
if(contadorDeLineas<cantidadDeFilas){
cout<<"Se ha encontrado una cantidad de lineas menor de lo esperado ("<<cantidadDeFilas<<")";
return;
}
seHaLeidoArchivoDeSalida=true;
cout<<endl<<"Lectura Exitosa";
}
};
class Individuo{
private:
bool regla[3][32];
short iteraciones[3];
unsigned int distancia;
public:
Individuo(){
}
void inicializarIndividuo(bool* r1, bool* r2, bool* r3, short i1, short i2, short i3){
distancia=0;
int contador;
for(contador=0;contador<32;contador++) regla[0][contador]=*(r1+contador);
for(contador=0;contador<32;contador++) regla[1][contador]=*(r2+contador);
for(contador=0;contador<32;contador++) regla[2][contador]=*(r3+contador);
iteraciones[0]=i1;
iteraciones[1]=i2;
iteraciones[2]=i3;
}
bool* getRegla(int numeroDeRegla){
return regla[numeroDeRegla];
}
bool getBit(int numeroDeRegla, int posicionEnLaRegla){
return regla[numeroDeRegla][posicionEnLaRegla];
}
short getIteracionesDeRegla(int numeroDeRegla){
return iteraciones[numeroDeRegla];
}
void setDistancia(unsigned int d){
distancia=d;
}
unsigned int getDistancia(){
return distancia;
}
void mutar(int reglaElegida, int posicionDeBitEnLaRegla, int nuevoNumeroDeIteraciones){
regla[reglaElegida][posicionDeBitEnLaRegla]=!regla[reglaElegida][posicionDeBitEnLaRegla];
iteraciones[reglaElegida]=(short)nuevoNumeroDeIteraciones;
}
};
//Dentro de la clase poblacion se manejaran los mecanismos de seleccion de individuos para la reproduccion, y evolucion
class Poblacion{
private:
Matriz matrizInicial,matrizFinal,matrizParaIrAplicandoReglas,matrizParaIrAplicandoReglas2;
Individuo poblacionActual[cantidadDeIndividuos],proximaPoblacion[cantidadDeIndividuos];
ManejadorDeNumerosAleatorios mna;
int posicionEnFila,posicionEnColumna,posicionDeBitEnRegla;
int contadorRegla,contadorIteracionesDeRegla;
int sumatoria;
int margenDeErrorAceptado;
public:
bool solucionEncontrada;
Individuo solucion;
Poblacion(Matriz mi, Matriz mf){
mna.reInicializar();
solucionEncontrada=false;
margenDeErrorAceptado=0;
matrizInicial=mi;
matrizFinal=mf;
int ci;
for(ci=0;ci<cantidadDeIndividuos;ci++){
poblacionActual[ci].inicializarIndividuo( mna.obtenerReglaAleatoria(),mna.obtenerReglaAleatoria(),mna.obtenerReglaAleatoria(),
mna.obtenerIteraciones(8),mna.obtenerIteraciones(8),mna.obtenerIteraciones(8) );
proximaPoblacion[ci]=poblacionActual[ci];
}
calcularSumatoria();
}
void evaluarIndividuos(){
int contadorDeIndividuo,f=cantidadDeFilas,c=cantidadDeColumnas;
for(contadorDeIndividuo=0;contadorDeIndividuo<cantidadDeIndividuos;contadorDeIndividuo++){ // para cada individuo
matrizParaIrAplicandoReglas=matrizInicial;
for(contadorRegla=0;contadorRegla<3;contadorRegla++){ // para aplicar las 3 reglas
for(contadorIteracionesDeRegla=0;contadorIteracionesDeRegla<poblacionActual[contadorDeIndividuo].getIteracionesDeRegla(contadorRegla);contadorIteracionesDeRegla++){ // para aplicar una regla varias veces
for(posicionEnFila=0;posicionEnFila<f;posicionEnFila++){ // para ir recorriendo las filas de la matriz
for(posicionEnColumna=0;posicionEnColumna<c;posicionEnColumna++){ // para ir recorriendo las columnas y aplicar la regla
posicionDeBitEnRegla=0;
if( matrizParaIrAplicandoReglas.getBit( ( (f+posicionEnFila-1)%f) , ((c+posicionEnColumna-1)%c) ) )
posicionDeBitEnRegla+=1;
if( matrizParaIrAplicandoReglas.getBit( ( (f+posicionEnFila-1)%f) , ((posicionEnColumna+1)%c) ) )
posicionDeBitEnRegla+=2;
if( matrizParaIrAplicandoReglas.getBit( ( (posicionEnFila+1)%f) , ((posicionEnColumna+1)%c) ) )
posicionDeBitEnRegla+=4;
if( matrizParaIrAplicandoReglas.getBit( ( (posicionEnFila+1)%f) , ((c+posicionEnColumna-1)%c) ) )
posicionDeBitEnRegla+=8;
if( matrizParaIrAplicandoReglas.getBit( posicionEnFila, posicionEnColumna ) )
posicionDeBitEnRegla+=16;
if(poblacionActual[contadorDeIndividuo].getBit(contadorRegla,posicionDeBitEnRegla))
matrizParaIrAplicandoReglas2.setBit(posicionEnFila,posicionEnColumna,true);
else
matrizParaIrAplicandoReglas2.setBit(posicionEnFila,posicionEnColumna,false);
}//FIN del for para recorrer columnas
}// FIN del for para recorrer filas
matrizParaIrAplicandoReglas=matrizParaIrAplicandoReglas2;
}// FIN del for para aplicar 1 de las reglas varias veces
} // FIN del for de las 3 reglas de cada individuo
poblacionActual[contadorDeIndividuo].setDistancia(matrizFinal.comparar(matrizParaIrAplicandoReglas,matrizFinal));
if(poblacionActual[contadorDeIndividuo].getDistancia()<=(unsigned int)margenDeErrorAceptado){
solucion=poblacionActual[contadorDeIndividuo];
solucionEncontrada=true;
return;
}
} // FIN del for para cada individuo
}// FIN de la funcion EVALUAR_INDIVIDUOS
//La funcion emplea el algoritmo de ordenacion por insercion, no recomendable para poblaciones mayores a 4000
//El primer elemento tiene la mayor distancia de hamming, por lo tanto es el menos deseable
void ordenarIndividuos(){
int i,j;
Individuo auxiliar;
for(i=1;i<cantidadDeIndividuos;i++){
j=i;
auxiliar=poblacionActual[i];
while(j>0&&auxiliar.getDistancia()>poblacionActual[j-1].getDistancia()){
poblacionActual[j]=poblacionActual[j-1];
j--;
}
poblacionActual[j]=auxiliar;
}
}
//El objetivo de esta funcion es poder trabajar con numeros enteros, evitando asi las operaciones de coma flotante que son
//mucho mas lentas.
void calcularSumatoria(){
long sum;
int contador;
for(contador=1,sum=0L;contador<=cantidadDeIndividuos;contador++){
sum+=(long)contador;
if(sum>=RAND_MAX){
sumatoria=RAND_MAX;
return;
}
}
sumatoria=(int)sum;
}
//el primer padre es elegido aleatoriamente de una sola vez
// mientras que el segundo debera superar la probabilidad
void evolucionar(){
int contadorDeIndividuo,primerPadre,segundoPadre,probabilidadAleatoria;
for(contadorDeIndividuo=0;contadorDeIndividuo<cantidadDeIndividuos;contadorDeIndividuo++){ //Generacion de cada individuo
primerPadre=rand()%cantidadDeIndividuos;
do{
segundoPadre=rand()%cantidadDeIndividuos;
probabilidadAleatoria=rand()%sumatoria;
}while(probabilidadAleatoria>segundoPadre || primerPadre==segundoPadre);
//Una vez determinados ambos padres, determinaremos la forma en que se heredaran los cromosomas
//Generaremos un numero [0,7] y luego de acuerdo a su forma en binario tendremos 3 bits
//El primer bit encendido indica que heredara el primer cromosoma del primer padre, en caso contrario
//lo heredara del segundo padre. De igual manera se toma la desicion con respecto al 2do y 3er cromosoma
probabilidadAleatoria=rand()%8;
if(probabilidadAleatoria==0){
proximaPoblacion[contadorDeIndividuo]=poblacionActual[segundoPadre];
}
else if(probabilidadAleatoria==1){
proximaPoblacion[contadorDeIndividuo].inicializarIndividuo(poblacionActual[primerPadre].getRegla(0),
poblacionActual[segundoPadre].getRegla(1),
poblacionActual[segundoPadre].getRegla(2),
poblacionActual[primerPadre].getIteracionesDeRegla(0),
poblacionActual[segundoPadre].getIteracionesDeRegla(1),
poblacionActual[segundoPadre].getIteracionesDeRegla(2));
}
else if(probabilidadAleatoria==2){
proximaPoblacion[contadorDeIndividuo].inicializarIndividuo(poblacionActual[segundoPadre].getRegla(0),
poblacionActual[primerPadre].getRegla(1),
poblacionActual[segundoPadre].getRegla(2),
poblacionActual[segundoPadre].getIteracionesDeRegla(0),
poblacionActual[primerPadre].getIteracionesDeRegla(1),
poblacionActual[segundoPadre].getIteracionesDeRegla(2));
}
else if(probabilidadAleatoria==3){
proximaPoblacion[contadorDeIndividuo].inicializarIndividuo(poblacionActual[primerPadre].getRegla(0),
poblacionActual[primerPadre].getRegla(1),
poblacionActual[segundoPadre].getRegla(2),
poblacionActual[primerPadre].getIteracionesDeRegla(0),
poblacionActual[primerPadre].getIteracionesDeRegla(1),
poblacionActual[segundoPadre].getIteracionesDeRegla(2));
}
else if(probabilidadAleatoria==4){
proximaPoblacion[contadorDeIndividuo].inicializarIndividuo(poblacionActual[segundoPadre].getRegla(0),
poblacionActual[segundoPadre].getRegla(1),
poblacionActual[primerPadre].getRegla(2),
poblacionActual[segundoPadre].getIteracionesDeRegla(0),
poblacionActual[segundoPadre].getIteracionesDeRegla(1),
poblacionActual[primerPadre].getIteracionesDeRegla(2));
}
else if(probabilidadAleatoria==5){
proximaPoblacion[contadorDeIndividuo].inicializarIndividuo(poblacionActual[primerPadre].getRegla(0),
poblacionActual[segundoPadre].getRegla(1),
poblacionActual[primerPadre].getRegla(2),
poblacionActual[primerPadre].getIteracionesDeRegla(0),
poblacionActual[segundoPadre].getIteracionesDeRegla(1),
poblacionActual[primerPadre].getIteracionesDeRegla(2));
}
else if(probabilidadAleatoria==6){
proximaPoblacion[contadorDeIndividuo].inicializarIndividuo(poblacionActual[segundoPadre].getRegla(0),
poblacionActual[primerPadre].getRegla(1),
poblacionActual[primerPadre].getRegla(2),
poblacionActual[segundoPadre].getIteracionesDeRegla(0),
poblacionActual[primerPadre].getIteracionesDeRegla(1),
poblacionActual[primerPadre].getIteracionesDeRegla(2));
}
else{
proximaPoblacion[contadorDeIndividuo]=poblacionActual[primerPadre];
}
//Aqui se trata la posibilidad de que haya una mutacion, en un bit y/o en las iteraciones, la probabilidad es 1/1000
probabilidadAleatoria=rand()%1000;
if(probabilidadAleatoria==212){
proximaPoblacion[contadorDeIndividuo].mutar( (rand()%3), (rand()%31), (rand()%8) );
}
}//Fin del for de generacion de cada individuo
//Ahora esta poblacion generada se convierte en la poblacionActual
for(contadorDeIndividuo=0;contadorDeIndividuo<cantidadDeIndividuos;contadorDeIndividuo++){
poblacionActual[contadorDeIndividuo]=proximaPoblacion[contadorDeIndividuo];
}
}
Individuo obtenerMejorIndividuo(){
return poblacionActual[cantidadDeIndividuos-1];
}
void setMargenDeError(int margen){
margenDeErrorAceptado=margen;
}
};
//Los siguientes metodos solo sirven con reglas de 32 bits
class HerramientasDePrueba{
public:
HerramientasDePrueba(){
}
/*static bool* LONG_to_BOOL_ARRAY(unsigned long x){
bool* resultado=new bool[32];
unsigned long valor=x;
int contador;
for(contador=0;contador<31;contador++,valor/=2L){
if(valor%2L==1L){
resultado[contador]=true;
}
else{
resultado[contador]=false;
}
}
}
static char* BOOL_ARRAY_to_STRING(bool* boolarray, int arraylenght){
char* resultado=new char[arraylenght+1];
int contador;
for(contador=0;contador<arraylenght;contador++){
if(boolarray[contador]){
resultado[contador]='1';
}
else{
resultado[contador]='0';
}
}
resultado[contador]='\0';
return resultado;
}*/
static unsigned long BOOL_ARRAY_to_LONG(bool* boolarray, int arraylenght){
int contador;
unsigned long resultado=0L;
for(contador=0;contador<arraylenght;contador++){
if(boolarray[contador])
resultado+=(unsigned long)pow(2.0,(double)contador);
}
return resultado;
}
static void mostrarResultado(Individuo r){
if(r.getDistancia()==0){
cout<<endl<<"Se ha encontrada la respuesta EXACTA: ";
}
else{
cout<<endl<<"Se ha encontrada una respuesta aceptable: ";
}
cout<<endl<<" Regla 1:"<<BOOL_ARRAY_to_LONG(r.getRegla(0),32)<<" Aplicada: "<<r.getIteracionesDeRegla(0)<<" veces";
cout<<endl<<" Regla 2:"<<BOOL_ARRAY_to_LONG(r.getRegla(1),32)<<" Aplicada: "<<r.getIteracionesDeRegla(1)<<" veces";
cout<<endl<<" Regla 3:"<<BOOL_ARRAY_to_LONG(r.getRegla(2),32)<<" Aplicada: "<<r.getIteracionesDeRegla(2)<<" veces";
}
static void mostrarMejorIndividuo(Individuo r, int i){
cout<<"Datos del mejor individuo de la iteracion #"<<i<<": ";
cout<<endl<<"Distancia: "<<r.getDistancia();
cout<<endl<<" Regla 1:"<<BOOL_ARRAY_to_LONG(r.getRegla(0),32)<<" Aplicada: "<<r.getIteracionesDeRegla(0)<<" veces";
cout<<endl<<" Regla 2:"<<BOOL_ARRAY_to_LONG(r.getRegla(1),32)<<" Aplicada: "<<r.getIteracionesDeRegla(1)<<" veces";
cout<<endl<<" Regla 3:"<<BOOL_ARRAY_to_LONG(r.getRegla(2),32)<<" Aplicada: "<<r.getIteracionesDeRegla(2)<<" veces";
}
};
void main(){
string z="\nMenu:\n1.Leer Archivo de entrada\n2.Leer Archivo de salida\n3.Ejecutar Algoritmo Genetico\n0.Salir\nOpcion Seleccionada: ";
char opcion[20];
int accion=10;
ManejadorDeArchivos archivos;
do{
puts(z.c_str());
gets(opcion);
try{
accion=atoi(opcion);
}
catch(exception e){
cout<<"Seleccion no valida";
continue;
}
if(accion==1){
archivos.leerArchivoDeEntrada();
}
else if(accion==2){
archivos.leerArchivoDeSalida();
}
else if(accion==3){
if(archivos.noSeHanLeidoLosArchivosNecesarios()){
cout<<endl<<"Se debe haber leido correctamente el archivo de entrada(matriz inicial) y el archivo de salida(matriz final) para poder continuar";
continue;
}
Poblacion p(archivos.obtenerDatosDeEntrada(),archivos.obtenerDatosDeSalida());
int numeroDeIteracionesRestantes=0,iteracionesTotales=1,margenError;
cout<<endl<<"Ingrese el margen de error aceptado (numero de bits distintos con respecto a la matriz final): ";
cin>>margenError;
p.setMargenDeError(margenError);
do{
p.evaluarIndividuos();
if(p.solucionEncontrada){
HerramientasDePrueba::mostrarResultado(p.solucion);
cout<<"Programa Finalizado";
cin.get();
return;
}
p.ordenarIndividuos();
HerramientasDePrueba::mostrarMejorIndividuo(p.obtenerMejorIndividuo(),iteracionesTotales);
p.evolucionar();
if(numeroDeIteracionesRestantes==0){
cout<<endl<<"Cuantas Iteraciones mas desea ejecutar antes de terminar el programa (en caso de no encontrar la respuesta exacta)? ingrese 0 en caso de no querer ejecutar mas iteraciones: ";
cin>>numeroDeIteracionesRestantes;
}
numeroDeIteracionesRestantes--;
iteracionesTotales++;
}while(numeroDeIteracionesRestantes>0);
}
else if(accion!=0){
cout<<endl<<"Por favor seleccione una opcion correcta.";
}
}while(accion!=0);
cout<<"Programa Finalizado";
cin.get();
}