Sie sind auf Seite 1von 14

/*Main.cpp*/ #include "sudoku.h" #include <iostream> #include <time.

h> using namespace std; #define TAMPOB 3000 //Debe ser par #define ELITISMO 300 //Debe ser par int main(void) { double generaciones = 0; float pm = .3; float pc = .9; int temp = 0; int totalfitness = 0; int p1 = 0; int p2 = 0; int pctemp = 0; int pmtemp = 0; int mejorfitness = 0; int indicenvapob = 0; sudoku nuevapoblacion[TAMPOB]; sudoku individuo[TAMPOB]; srand(time(NULL)); sudoku sudo( "065000730" "300000009" "001234500" "900000007" "000678000" "800000001" "009351400" "100000003" "040000210" ); sudoku sudo0( "090000010" "070000030" "123456789" "060000050" "050000040" "040000060" "030000070" "987654321" "010000090" ); sudoku sudo1( "090710056" "040600382" "006084000" "084007020" "073005908" "900030000"

"000000201" "800300507" "000091000" ); sudoku sudo2( "304291006" "017080092" "920005104" "162050308" "005028067" "000604200" "093500670" "200819050" "040306800" ); //Generar Poblacin for (int x = 0; x < TAMPOB; x++){ individuo[x] = sudo; individuo[x].generaraleatorioh(); totalfitness += individuo[x].fitness; } do{ //Tomar en cuenta elitismo generaciones++; temp = 243; if (ELITISMO){ for (indicenvapob = 0; indicenvapob < ELITISMO; indicenv apob++){ int elitismotemp = temp; int indice = 0; temp = 0; for (int x = 0; x < TAMPOB; x++){ if (individuo[x].fitness > temp && indiv iduo[x].fitness < elitismotemp){ temp = individuo[x].fitness; indice = x; } } nuevapoblacion[indicenvapob] = sudoku(&individuo [indice].matriz[0][0]); if (mejorfitness < temp){ mejorfitness = temp; individuo[0].visualizar(); cout << endl << "Fitness:\t" << mejorfit ness << "/243 "; cout << endl << "% correccion:\t" << (me jorfitness/243.00)*100; cout << endl << "Num generacion:\t" << g eneraciones; cout << endl << "Fitness total:\t" << to talfitness << endl; for (int x = 1; x < 10; x++){ cout << endl << "Individuo:" << x; cout << " iduo[x].fitness; individuo[x].vercromosoma(); Fitness: " << indiv

cout << endl; } } } } indicenvapob--; //Ciclo reproductivo for(int x = 0; x < ((TAMPOB-ELITISMO)/2); x++) { //Calcula indice de padre1 int padre1 = rand() % totalfitness; temp = 0; p1 = 0; while (temp <= padre1){ temp += individuo[p1].fitness; p1++; } p1--; //Calcula indice de padre2 int padre2 = rand() % totalfitness; temp = 0; p2 = 0; while (temp <= padre2){ temp += individuo[p1].fitness; p2++; } p2--; //Probabilidad de cruce pctemp = rand() % 100 + 1; if ( pctemp <= pc*100){ nuevapoblacion[++indicenvapob] = individuo[p1].c ruzar(individuo[p2], false); nuevapoblacion[++indicenvapob] = individuo[p1].c ruzar(individuo[p2], true); } else{ nuevapoblacion[++indicenvapob] = sudoku(individu o[p1]); nuevapoblacion[++indicenvapob] = sudoku(individu o[p2]); } //Probabilidad de mutacion pmtemp = rand() % 99; if ( pctemp <= pm*100){ nuevapoblacion[indicenvapob-1].mutar(); nuevapoblacion[indicenvapob].mutar(); } } //Nueva Generacion totalfitness = 0; for (int x = 0; x < TAMPOB; x++){ individuo[x] = nuevapoblacion[x]; totalfitness += individuo[x].fitness;

} //individuo[rand() % TAMPOB].visualizar(); }while(mejorfitness < 243); system("pause"); }

/*Sudoku.cpp*/ #include "sudoku.h" #include <iostream> #include <time.h> #include <conio.h> #include <Windows.h> using namespace std; gen::gen(){ num='\0'; fijo=false; }; sudoku::sudoku(void){ int i=0; int j=0; for (i=0; i<9; i++) for (j=0; j<9; j++) matriz[i][j].num='0'; matriz[i][j].num='\0'; fitness=0; } sudoku::sudoku(char * mat){ int i = 0, j = 0; for (i=0; i<9; i++) { for (j=0; j<9; j++){ matriz[i][j].num= mat[0]; if (matriz[i][j].num != '0') matriz[i][j].fijo = true; mat++; } matriz[i][j].num='\0'; } calcuafitness(); } sudoku::sudoku(gen * mat){ int i = 0, j = 0; for (i = 0; i < 9; i++) { for (j=0; j<9; j++){ matriz[i][j].num = mat->num;

matriz[i][j].fijo = mat->fijo; mat++; } } calcuafitness(); } void sudoku::visualizar(){ int i =0 , j = 0; HANDLE hConsole; hConsole = GetStdHandle(STD_OUTPUT_HANDLE); system("cls"); cout << endl; SetConsoleTextAttribute(hConsole, 2); for (i = 0; i < 9; i++) { for (j = 0; j < 9; j++) { if (matriz[i][j].num != '0'){ if (matriz[i][j].fijo) SetConsoleTextAttribute(hConsole, 4); cout << matriz[i][j].num; SetConsoleTextAttribute(hConsole, 2); } else cout << ' '; cout << ' '; if ((j+1) % 3 == 0 && j != 8 ){ cout << '\|'; cout <<' '; } } cout << endl; if ((i + 1) % 3 == 0 && i != 8 ){ cout << "---------------------" << endl; } } } void sudoku::vercromosoma(){ int i =0 , j = 0; HANDLE hConsole; hConsole = GetStdHandle(STD_OUTPUT_HANDLE); cout << endl; SetConsoleTextAttribute(hConsole, 2); for (i = 0; i < 9; i++) { for (j = 0; j < 9; j++) { if (matriz[i][j].num != '0'){ if (matriz[i][j].fijo) SetConsoleTextAttribute(hConsole, 4); cout << matriz[i][j].num; SetConsoleTextAttribute(hConsole, 2); } } if ((i + 1) % 3 == 0 && i != 8 ){ cout << endl; } } }

void sudoku::calcuafitness(){ int i = 0, j = 0, k = 0, l = 0, cc = 0; int fit1 = 0, fit2 = 0, fit3 = 0; //Analiza valores por filas for (i = 0; i < 9; i++){ for(j = 0; j < 9; j++){ char c = '1' + j; for (k =0; k < 9; k++){ if (matriz[i][k].num == c){ k = 9; fit1++; } } } } //Analiza valores por columnas for (i = 0; i < 9; i++){ for(j = 0; j < 9; j++){ char c = '1' + j; for (k = 0; k < 9; k++){ if (matriz[k][i].num == c){ k = 9; fit2++; } } } } //Analiza matrices de 3x3 for (i = 0; i < 9; i += 3){ for(j = 0; j < 9; j += 3){ for (cc = 0; cc < 9; cc++){ char c = '1' + cc; for (k = i; k < i + 3; k++){ for (l = j; l < j + 3; l++){ if (matriz[k][l].num == c){ fit3++; k = i + 3; l = j + 3; } } } } } } fitness = fit1 + fit2 + fit3; } int sudoku::fitnesssubcuadro(int x){ int fit = 0; int i = x / 3; int j = x % 3; for (int cc = 0; cc < 9; cc++){ char c = '1' + cc; for (int k = i*3; k < (i*3) + 3; k++){

for (int l = j*3; l < (j*3) + 3; l++){ if (matriz[k][l].num == c){ fit++; k = (i*3) + 3; l = (j*3) + 3; } } } } return fit; } void sudoku::generaraleatorioh(){ char c = '\0'; int i = 0, j = 0, k = 0; bool continuar = true; for (i = 0; i < 9; i++){ for (j = 0; j < 9; j++){ continuar = true; if (!matriz[i][j].fijo && matriz[i][j].num == '0'){ //Comprobar si hay un espacio por llenar for (k = 0; k < 9; k++){ if (matriz[i][k].num == '0') k=9; else if (k==8){ continuar = false; j = 9; } } //Si hay un espacio llenarlo if (continuar){ do{ c = char ('1' + rand() % 9); for (k = 0; k < 9; k++){ if(matriz[i][k].num == c ) k = 8; else{ if (k == 8){ matriz[i ][j].num = c; continua r=false; } } } }while(continuar); } } } } calcuafitness(); } void sudoku::generaraleatoriov(){ char c = '\0'; int i = 0, j = 0, k = 0;

bool continuar = true; for (i = 0; i < 9; i++){ for (j = 0; j < 9; j++){ continuar = true; if (!matriz[j][i].fijo && matriz[j][i].num == '0'){ //Comprobar si hay un espacio por llenar for (k = 0; k < 9; k++){ if (matriz[k][i].num == '0') k=9; else if (k==8) { continuar=false; j = 9; } } //Si hay un espacio, llenalo if (continuar){ do{ c= char ('1' + rand() % 9); for (k = 0; k < 9; k++){ if(matriz[k][i].num == c ) k = 8; else{ if (k == 8){ matriz[j ][i].num = c; continua r=false; } } } }while(continuar); } } } } calcuafitness(); } void sudoku::generaraleatoriom(int x, int y){ char c = '\0'; int i = 0, j= 0, k = 0, l = 0; bool continuar = true; for (i = x; i < x + 3; i++){ for (j = y; j < y + 3; j++){ continuar = true; //Comprobar si hay un espacio por llenar for (k = x; k < x + 3; k++){ for (l = y; l < y + 3; l++){ if (matriz[k][l].num == '0'){ k = x + 3; l = y + 3; } else if (k == i + 2 && l == j + 2) { continuar = false; j = y + 3; i = x + 3; }

} } if (!matriz[i][j].fijo && matriz[i][j].num == '0' && con tinuar){ do{ c= char ('1' + rand() % 9); for (k = x; k < x + 3; k++){ for (l = y; l < y + 3; l++){ if(matriz[k][l].num == c ){ k = x + 3; l = y + 3; } else{ if (k == x + 2 & & l == y + 2){ matriz[i ][j].num = c; continua r = false; } } } } }while(continuar); } } } calcuafitness(); } void sudoku::generaraleatorio(){ for (int x = 0; x < 9; x++){ for (int y=0; y<9; y++){ char c = '1' + rand() % 8; if (!matriz[x][y].fijo && matriz[x][y].num == '0') matriz[x][y].num = c; } } calcuafitness(); } sudoku sudoku::cruzar(sudoku padre2, bool segundohijo){ sudoku temp1 = *this; sudoku temp2 = padre2; int fit[9] = {0,0,0,0,0,0,0,0,0}; int tempindice = 0, tempfit = 0, x = 0, y = 0, i = 0; int mejorfit[5] = {0,0,0,0,0}; //Elige el mejor con mejores genes if (temp1.fitness < temp2.fitness){ temp1 = padre2; temp2 = *this; } if (!segundohijo){ //Metodo Subcuadros //Calcula fitness de subcuadros

for (x = 0; x < 9; x ++) fit[x] = temp1.fitnesssubcuadro(x); //Extrae 5 mejores fitness del padre for (i=0; i<5; i++){ for (x = 0; x < 9; x ++){ if (tempfit < fit[x]){ tempfit = fit[x]; tempindice = x; } } mejorfit[i] = tempindice; fit[tempindice] = 0; tempfit = 0; } //Agrega genes faltantes para completar el nuevo hijo for (x = 0; x < 9; x++){ for (y = 0; y < 5; y++){ if (mejorfit[y] == x) y = 5; else{ if (y == 4) temp1.agregarsubcuadro(temp2, x) ; } } } } else{ int metodo = rand() % 99; if(metodo < 50){ //Metodo filas //Calcula fitness de filas for (x = 0; x < 9; x ++) fit[x] = temp1.fitnesfila(x); //Extrae 5 mejores fitness del padre int mejorfit[5]; int tempindice = 0, tempfit = 0; for (i=0; i<5; i++){ for (x = 0; x < 9; x ++){ if (tempfit < fit[x]){ tempfit = fit[x]; tempindice = x; } } mejorfit[i] = tempindice; fit[tempindice] = 0; tempfit=0; } //Agrega genes faltantes para completar el nuevo hijo for (x=0; x<9; x++){ for (y = 0; y<5; y++){ if (mejorfit[y] == x) y = 5; else{ if (y == 4) temp1.agregarfila(temp2, x); } } }

} else{ //Metodo columnas //Calcula fitness de columnas for (x = 0; x < 9; x ++) fit[x] = temp1.fitnescolumna(x); //Extrae 5 mejores fitness del padre for (i=0; i<5; i++){ for (x = 0; x < 9; x ++){ if (tempfit < fit[x]){ tempfit = fit[x]; tempindice = x; } } mejorfit[i] = tempindice; fit[tempindice] = 0; tempfit=0; } //Agrega genes faltantes para completar el nuevo hijo for (x = 0; x < 9; x++){ for (y = 0; y<5; y++){ if (mejorfit[y] == x) y = 5; else{ if (y == 4) temp1.agregarcolumna(tem p2, x); } } } } } temp1.calcuafitness(); return temp1; } void sudoku::mutar(){ int metodo = rand() % 30 + 1; int i = rand() % 8; int j = rand() % 8; if (metodo < 11){ //Muta matriz for (int x = (i/3)*3; x < (i/3)*3 + 3; x++){ for (int y = (j/3)*3; y < (j/3)*3 + 3; y++){ if (!this->matriz[x][y].fijo) this->matriz[x][y].num = '0'; } } generaraleatoriom((i/3)*3, (j/3)*3); } else if (metodo < 21){ //Muta fila for (int x = 0; x<9; x++){ if (!this->matriz[i][x].fijo) this->matriz[i][x].num = '0'; } generaraleatorioh();

} else if (metodo < 31){ //Muta columna for (int y = 0; y<9; y++){ if (!this->matriz[y][j].fijo && y != i) this->matriz[y][j].num = '0'; } generaraleatoriov(); } else { //Muta 9 numeros al azar for (int x = 0; x < 9; x++){ do{ i = rand() % 9; j = rand() % 9; if (!this->matriz[i][j].fijo){ matriz[i][j].num = '1' + rand() % 9; } } while (this->matriz[i][j].fijo); } } calcuafitness(); } void sudoku::agregarsubcuadro (sudoku cuadro, int subcuadro){ int i = (subcuadro / 3) * 3; int j = (subcuadro % 3) * 3; for (int m = i; m < i + 3; m++){ for (int n = j; n < j + 3; n++){ matriz[m][n] = cuadro.matriz[m][n]; } } } int sudoku::fitnesfila(int fila){ int fit = 0; char c = '0'; for (int x = 0; x<9; x++){ c = '1' + x; for (int y = 0; y<9; y++){ if (matriz[fila][y].num == c){ fit++; y = 9; } } } return fit; } void sudoku::agregarfila (sudoku cuadro, int fila){ for (int m = 0; m < 9; m++)

matriz[fila][m] = cuadro.matriz[fila][m]; } int sudoku::fitnescolumna(int columna){ int fit = 0; char c = '0'; for (int x = 0; x<9; x++){ c = '1' + x; for (int y = 0; y<9; y++){ if (matriz[y][columna].num == c){ fit++; y = 9; } } } return fit; } void sudoku::agregarcolumna (sudoku cuadro, int columna){ for (int m = 0; m < 9; m++) matriz[m][columna] = cuadro.matriz[m][columna]; } /*Sudoku.h*/ #include <iostream> using namespace std; struct gen{ char num; bool fijo; gen(); }; class sudoku { public: gen matriz[9][9]; int fitness; //Constructores sudoku(void); sudoku(char* matriz); sudoku(gen*); //Metodos void visualizar(void); void calcuafitness(); void generaraleatorioh(); void generaraleatoriov(); void generaraleatoriom(int i, int j); void generaraleatorio(); sudoku cruzar(sudoku padre2, bool segundohijo); void mutar(sudoku* mutarcon); void mutar(void); int fitnesssubcuadro(int x);

void agregarsubcuadro (sudoku cuadro, int subcuadro); int fitnesfila(int fila); void agregarfila (sudoku cuadro, int fila); int fitnescolumna(int columna); void agregarcolumna (sudoku cuadro, int columna); void vercromosoma(); };

Das könnte Ihnen auch gefallen