void init() { // allocate memory and initialize population Pop[0] = malloc(N*sizeof(unsigned long)); Pop[1] = malloc(N*sizeof(unsigned long)); initpop(Pop[0]); }
int main (int argc, char *argv[]) { double frce; input(); inithydro(); equili(); initpop(); for (istep = 1; istep <= nsteps; istep++) { pbc(); mbc(); move(); hydrovar(); equili(); collis(); if (iforce) force(istep, &frce); if (iobst) obst(); if (istep % ndiag == 0) diag0D(); if (istep % nout == 0) profil(istep, frce); } return 0; }
/* The main function */ int main(int argc, char const *argv[]) { DBusError dbe; struct state_st state; /* Parse the command line. */ if (argv[1] && argv[1][0] == 'd') { /* Debug dump */ assert(loadstate(&state)); dumpop(&state); return 0; } else if (argv[1] && argv[1][0] == 'r') { /* Repair the GA state. */ unsigned i; assert(loadstate(&state)); for (i = 0; i < G_N_ELEMENTS(state.pop); i++) { /* Ensure that genes are bounded. */ struct genome_st *g = &state.pop[i]; if (g->window > TIMEOUT) g->window = TIMEOUT; else if (g->window < 3) g->window = 3; if (g->threshold <= 0) g->threshold = 0.1; else if (g->threshold >= 1) g->threshold = 0.9; } savestate(&state); return 0; } /* Redirect stdio. */ assert((stderr = fopen(FNAME".err", "a")) != NULL); assert((stdout = fopen(FNAME".log", "a")) != NULL); /* Initialize infrastructure for the test. */ Loop = g_main_loop_new(0, 0); DBus = dbus_bus_get(DBUS_BUS_SESSION, NULL); dbus_connection_setup_with_g_main(DBus, g_main_context_default()); dbus_error_init(&dbe); dbus_bus_add_match(DBus, "type='method_call',interface='com.nokia.HildonDesktop.AppMgr',member='LaunchApplication'", &dbe); assert(!dbus_error_is_set(&dbe)); Dpy = XOpenDisplay(NULL); assert(Dpy != NULL); if (!loadstate(&state)) initpop(&state); /* Test */ eval(&state.pop[state.idx++]); if (state.idx >= G_N_ELEMENTS(state.pop)) generation(&state); /* Done and reboot. */ savestate(&state); if (argv[1]) system("echo reboot | sudo gainroot"); return 0; } /* main */
int main(int argc,char *argv[]) { //Inicia MPI inicializa_mpi(argc,argv); // Obtiene rutas de trabajo y crea archivos generales if(inicializa_archivos(argc, argv, rank) == -1) exit(-1); #ifdef _PRINT_MIGRACION_ printf("#Bienvenido a MAPAPOC (MÁquina PAralela para Problemas de Optimización Combinatoria) en Rank %d... [OK]\n", rank); #endif if(rank != 0) { //Inicializa semilla aleatoria inicializa_semilla(); //Espera que nodo0 entregue dato runmax (cantidad de archivos a procesar) for(;;){ MPI_Iprobe(nodo0, MPI_ANY_TAG, MPI_COMM_WORLD, &flag1, &status); if(flag1 == true){ if (status.MPI_TAG == MSJ_RUNMAX){ MPI_Recv(&runmax, 1, MPI_INT, nodo0, MPI_ANY_TAG, MPI_COMM_WORLD, &status); flag1 = 0; #ifdef _PRINT_MIGRACION_ printf("Rank = %d Recibió desde Rank = 0 Mensaje RUNMAX = %d (cantidad máxima de instancias a resolver)...\n", rank, runmax); #endif break; }//End else if }//End if }//End for for(run=1; run<=runmax; run++) { #ifdef _PRINT_MIGRACION_ printf("Rank = %d Antes de generar semilla aleatoria...\n", rank); #endif //Nueva semilla aleatoria for(rank_seed = 1; rank_seed <= rank; rank_seed++) { int s = 0; /* s = atoi(argv[7]); */ if(s==0) { do { randomseed = nueva_semilla(); } while (randomseed == 0); } else { randomseed = (float)((s%10000)/10000.0); } }//End for #ifdef _PRINT_MIGRACION_ printf("Rank = %d Después de generar semilla aleatoria...\n", rank); #endif //Espera que nodo0 entregue información relevante para nodox for(;;) { MPI_Iprobe(nodo0, MPI_ANY_TAG, MPI_COMM_WORLD, &flag1, &status); if(flag1 == true){ if (status.MPI_TAG == MSJ_LINEA_IN){ MPI_Recv(linea_in, 100, MPI_CHAR, nodo0, MPI_ANY_TAG, MPI_COMM_WORLD, &status); flag1 = 0; //Asigna variables globales desde linea_in recibida desde Rank 0 //sscanf(linea_in,"%d %s %d %s %d %f %f %f %d %s %f", &tipo_problema, nomarch, &popsize, answer, &maxgen, &pcross, &pmutation, &pind_env_rec, &tasa_migracion, answer_mod_mig, &randomseed); sscanf(linea_in,"%d %s %d %s %d %f %f %f %f %d %s %f", &tipo_problema, nomarch, &popsize, answer, &maxgen, &pcross, &pmutation, &pind_env, &pind_rec, &tasa_migracion, answer_mod_mig, &randomseed); randomseed = randomseed + (rank * 0.001); //printf("#Rank = %d estableción semilla : %f\n", rank, randomseed); #ifdef _PRINT_MIGRACION_ printf("Rank = %d Recibió desde Rank = 0 Mensaje LINEA_IN (PARAMETROS GLOBALES)...\n", rank); #endif } else if (status.MPI_TAG == MSJ_CANT_CHAR_A_REC) { //cantidad_char_a_recibir es la variable que indica cuantos enteros recibirá nodox desde Rank 0 MPI_Recv(&cantidad_char_a_recibir, 1, MPI_INT, nodo0, MPI_ANY_TAG, MPI_COMM_WORLD, &status); flag1 = 0; #ifdef _PRINT_MIGRACION_ printf("Rank = %d Recibió desde Rank = 0 Mensaje MSJ_CANT_CHAR_A_REC...\n", rank); #endif break; } else if (status.MPI_TAG == MSJ_ERROR_ARCHIVO_INSTANCIA) { MPI_Recv(0, 0, MPI_INT, nodo0, MPI_ANY_TAG, MPI_COMM_WORLD, &status); flag1 = 0; cantidad_char_a_recibir = -1; //setea a -1 para indicar que hubo error al leer archivo instancia #ifdef _PRINT_MIGRACION_ printf("Rank = %d Recibió desde Rank = 0 Mensaje MSJ_ERROR_ARCHIVO_INSTANCIA...\n", rank); #endif break; }//End else if }//End if }//End for //Setea variable printstrings if(strncmp(answer,"n",1) == 0) printstrings = 0; else printstrings = 1; //Setea variables dependiendo de la cantidad de workers popsize = popsize / workers; if(popsize%2) popsize++; //n_ind_a_enviar = (int) popsize * pind_env_rec; //% de la subpoblación se envía //n_ind_a_recibir = (int) popsize * pind_env_rec; //% de la subpoblación se recibe n_ind_a_enviar = (int) popsize * pind_env; //% de la subpoblación se envía n_ind_a_recibir = (int) popsize * pind_rec; //% de la subpoblación se recibe //tasa_migracion = maxgen / workers; //tasa de migración depende de la cantidad de generaciones #ifdef _PRINT_MIGRACION_ printf("Rank = %d tiene popsize %d, n_ind_a_enviar %d, n_ind_a_recibir %d, tasa_migracion %d...\n", rank, popsize, n_ind_a_enviar, n_ind_a_recibir, tasa_migracion); #endif // nro. que identifica que migración está ocurriendo n_migracion = 0; //Inicializa contador de segundos de comunicación time_comm = 0.0; //Setea variable modelo_migracion if(strncmp(answer_mod_mig,"A",1) == 0) modelo_migracion = 0; // Migración Asíncrona else modelo_migracion = 1; //Migración Síncrona #ifdef _PRINT_MIGRACION_ printf("Rank %d debería recibir %d caracteres representando la instancia a resolver...\n", rank, cantidad_char_a_recibir); #endif if(cantidad_char_a_recibir > 0) { //Lee enteros con información del archivo instancia if(lee_char_y_genera_achivo_instancia_tmp(tipo_problema, cantidad_char_a_recibir)) { #ifdef _PRINT_MIGRACION_ printf("Espere, MAPAPOC en Rank %d está procesando archivo %s...\n", rank, nomarch); #endif //Actualiza Resultados Estadísticos Evolutivos para cada problema particular fprintf(evofp, "\n\nCorrida : %d, PROBLEMA : %s\n", run, nomarch); fprintf(evofp, "Migracion Generacion Minimo Maximo Media DesvEstandar TiempoTranscurrido GenMejor\n"); // Inicia la cuenta de Segundos time_start = MPI_Wtime(); // Rutina de inicialización de variables globales initialize(); // Ubica espacio malloc para las estructuras de datos globales initmalloc(); // Define tipos de Individuos a Enviar y Recibir Build_type_pop(envpop, &message_type_send, n_ind_a_enviar); Build_type_pop(recpop, &message_type_receive, n_ind_a_recibir); // Initializa la población de individuos y determina datos estadísticos // y mejor individuo de la población initpop(tipo_problema); statistics(oldpop); //Avisa a nodo0 que esté listo para comenzar evolución... time_send = MPI_Wtime(); MPI_Isend(0, 0, MPI_INT, nodo0, MSJ_LISTO_PARA_COMENZAR, MPI_COMM_WORLD, &request); for(;;){ MPI_Test(&request, &flag2, &status); if(flag2 == true){ time_send = MPI_Wtime() - time_send; time_comm += time_send; #ifdef _PRINT_MIGRACION_ printf("Envió desde Rank = %d a Rank = 0 Mensaje Listo para comenzar...\n", rank); #endif break; }//End If }//End for //Espera que nodo0 dé la partida para comenzar evolución... for(;;){ MPI_Iprobe(nodo0, MPI_ANY_TAG, MPI_COMM_WORLD, &flag1, &status); if(flag1 == true) { if (status.MPI_TAG == MSJ_COMIENCE){ MPI_Recv(0, 0, MPI_INT, nodo0, MPI_ANY_TAG, MPI_COMM_WORLD, &status); flag1 = 0; #ifdef _PRINT_MIGRACION_ printf("Rank = %d Recibió desde Rank = 0 Mensaje de COMINECE, comienza evolución...\n", rank); #endif break; }//End if }//End if }//End for //Setea contador de generaciones para Migrar en Modelo de Migración Asíncrona if (modelo_migracion == 0) cuenta_gen_para_migracion=1; for(gen=0; gen<maxgen; gen++) { if(printstrings == 1) fprintf(outfp,"\nGENERATION %d->%d\n",gen,maxgen); // Crea una nueva generación generation(tipo_problema); /* printf("generacion: %d de %d => %f\n",gen, maxgen, bestfit.fitness); */ // Efectúa estadísticas sobre nueva población y obtiene mejor individuo statistics(newpop); if (modelo_migracion == 0) //Establece comunicación Asincrona con Coordinador comunicacion_asincrona_con_coordinador(); else //Establece comunicación sincrona con Coordinador comunicacion_sincrona_con_coordinador(); /* printf("rank %i gen %i best fitness: %f\n", rank, gen, bestfit.fitness); */ /* if(bestfit.fitness < 107.0) { printf("rank %i gen %i best fitness: %f done!\n", rank, gen, bestfit.fitness); gen = maxgen; } */ /* printf("%i.%i=>%f\n", rank, gen, bestfit.fitness); */ // Avanza de Generación temppop = oldpop; oldpop = newpop; newpop = temppop; }//End for // Libera memoria temporal freeall(); //Libera memoria tipos creados por MPI MPI_Type_free(&message_type_send); MPI_Type_free(&message_type_receive); } else printf("!!! ADVERTENCIA ¡¡¡ Rank %d no procesó archivo de instancia ya que hubo problemas al leer enteros, generar o leer tmp...\n", rank); } else printf("!!! ADVERTENCIA ¡¡¡ Rank %d no procesó archivo de instancia ya que Rank 0 tuvo problemas al leerlo...\n", rank); // Libera variables del problema app_free(tipo_problema); //Mensaje de término de procesamiento de archivo actual se envía a Rank = 0 MPI_Isend(&time_comm, 1, MPI_DOUBLE, nodo0, MSJ_TERMINO, MPI_COMM_WORLD, &request); for(;;){ MPI_Test(&request, &flag2, &status); if(flag2 == true){ #ifdef _PRINT_MIGRACION_ printf("Envió desde Rank = %d a Rank = 0 Mensaje de Término, archivo %s...\n", rank, nomarch); #endif break; }//End If }//End for //Espera que nodo0 dé el OK para poder finalizar el procesamiento del archivo actual for(;;){ MPI_Iprobe(nodo0, MPI_ANY_TAG, MPI_COMM_WORLD, &flag1, &status); if(flag1 == true){ if(status.MPI_TAG == MSJ_TERMINO_CONFIRMADO){ MPI_Recv(0, 0, MPI_INT, nodo0, MPI_ANY_TAG, MPI_COMM_WORLD, &status); flag1 = 0; #ifdef _PRINT_MIGRACION_ printf("Rank = %d Recibió desde Rank = 0 Mensaje de TERMINO_CONFIRMADO, pasa siguiente archivo o termina...\n", rank); #endif break; }//End if }//End if }//End for #ifdef _PRINT_MIGRACION_ printf("#Corrida %d, Archivo %s procesado por Rank %d... [OK]\n", run, nomarch, rank); #endif }//End for if(runmax == 0){ //Que runmax = 0 significa que la consistencia del archivo arrojó un error //=> rank debe mandar mensaje al Coordinador que va ha terminar el proceso... //Mensaje de término de procesamiento de archivo actual se envía a Rank = 0 MPI_Isend(&time_comm, 1, MPI_DOUBLE, nodo0, MSJ_TERMINO, MPI_COMM_WORLD, &request); for(;;){ MPI_Test(&request, &flag2, &status); if(flag2 == true){ #ifdef _PRINT_MIGRACION_ printf("Envió desde Rank = %d a Rank = 0 Mensaje de Término, archivo %s...\n", rank, nomarch); #endif break; }//End If }//End for printf("Proceso en Rank %d detenido ya que Rank 0 informa error en archivo de entrada... [OK]\n", rank); }//End if } else { //Rank = 0 => Coordinador /* printf("#Bienvenido a Máquina Paralela para Problemas de Optimización Combinatoria, espere por favor...\n"); */ // Revisa consistencia del archivo de entrada in.txt runmax = consistenciaarchivo(workers); //Envía runmax a cada Rank envia_a_cada_rank(MSJ_RUNMAX); for(run=1;run<=runmax;run++) { //Lee archivo en infp con parametros (todos ya chequeados) //OJO => Cada AG tendrá popsize/workers individuos => Población Total = popsize //fscanf(infp,"%d %s %d %s %d %f %f %f %d %s %f", &tipo_problema, nomarch, &popsize, answer, &maxgen, &pcross, &pmutation, &pind_env_rec, &tasa_migracion, answer_mod_mig, &randomseed); fscanf(infp,"%d %s %d %s %d %f %f %f %f %d %s %f", &tipo_problema, nomarch, &popsize, answer, &maxgen, &pcross, &pmutation, &pind_env, &pind_rec, &tasa_migracion, answer_mod_mig, &randomseed); int i=0; randomseed = (float)((atoi(argv[7])%100)/100.0); /* printf("argv[7]: %i\n", atoi(argv[7])); printf("randomseed: %f\n", randomseed); */ for(i=0; i<argc; i++) { // printf("argv[%i]: %s\n", i, argv[i]); if(strcmp(argv[i], "-pr")==0) tipo_problema = atoi(argv[++i]); if(strcmp(argv[i], "-po")==0) popsize = atoi(argv[++i]); if(strcmp(argv[i], "-g")==0) maxgen = atoi(argv[++i]); if(strcmp(argv[i], "-m")==0) pmutation = atof(argv[++i]); if(strcmp(argv[i], "-c")==0) pcross = atof(argv[++i]); if(strcmp(argv[i], "-pe")==0) pind_env = atof(argv[++i]); if(strcmp(argv[i], "-pa")==0) pind_rec = atof(argv[++i]); if(strcmp(argv[i], "-tm")==0) tasa_migracion = atoi(argv[++i]); if(strcmp(argv[i], "-am")==0) sprintf(answer_mod_mig, "%s", argv[++i]); if(strcmp(argv[i], "-f")==0) sprintf(nomarch, "%s", argv[++i]); if(strcmp(argv[i], "-a")==0) sprintf(answer, "%s", argv[++i]); } // exit(0); //Inicializa contador de segundos de comunicación time_comm = 0.0; //Llena con información linea_in para ser enviada a cada Rank //sprintf(linea_in,"%d %s %d %s %d %f %f %f %d %s %f\n", tipo_problema, nomarch, popsize, answer, maxgen, pcross, pmutation, pind_env_rec, tasa_migracion, answer_mod_mig, randomseed); sprintf(linea_in,"%d %s %d %s %d %f %f %f %f %d %s %f", tipo_problema, nomarch, popsize, answer, maxgen, pcross, pmutation, pind_env, pind_rec, tasa_migracion, answer_mod_mig, randomseed); /* printf("%d %s %d %s %d %f %f %f %f %d %s %f\n", tipo_problema, nomarch, popsize, answer, maxgen, pcross, pmutation, pind_env, pind_rec, tasa_migracion, answer_mod_mig, randomseed); */ #ifdef _PRINT_MIGRACION_ printf("Espere, MAPAPOC en Rank %d está enviando archivo %s a todos los rank...\n", rank, nomarch); #endif //Envía linea_in a cada Rank envia_a_cada_rank(MSJ_LINEA_IN); //Setea variable printstrings if(strncmp(answer,"n",1) == 0) printstrings = 0; else printstrings = 1; //Setea variables dependiendo de la cantidad de workers popsize = popsize / workers; /* printf("popsize: %i\n", popsize); */ if(popsize%2) popsize++; //n_ind_a_enviar = (int) popsize * pind_env_rec; //% de la subpoblación se envía //n_ind_a_recibir = (int) popsize * pind_env_rec; //% de la subpoblación se recibe n_ind_a_enviar = (int) popsize * pind_env; //% de la subpoblación se envía n_ind_a_recibir = (int) popsize * pind_rec; //% de la subpoblación se recibe //tasa_migracion = maxgen / workers; //tasa de migración debende de la cantidad de generaciones //Setea variable modelo_migracion if(strncmp(answer_mod_mig,"A",1) == 0) modelo_migracion = 0; //Migración Asíncrona else modelo_migracion = 1; //Migración Síncrona if(app_leearchivo(tipo_problema, nomarch, rank)) { if(almacena_archivo_instancia(nomarch)) { //Determina cantidad_char_a_recibir por cada rank que coordinador enviará. Todos estos char determinan los datos del problema a resolver cantidad_char_a_recibir = cantidad_char_que_determinan_instancia_del_problema; //Envía a cada Rank cantidad de char a recibir del problema envia_a_cada_rank(MSJ_CANT_CHAR_A_REC); //Envía a cada Rank un grupo de char que determinan la estructura de una instancia del problema envia_a_cada_rank(MSJ_CHAR_ARCHIVO_INSTANCIA); // Rutina de inicialización de variables globales // nro. individuos a enviar desde coord. a nodo AG coord_ind_a_env = n_ind_a_recibir; // nro. individuos a recibir desde cada nodo AG a coord coord_ind_a_rec = n_ind_a_enviar; // nro. individuos total recibidos => Población Global del Coordinador coord_ind_global = workers * n_ind_a_enviar; // nro. que identifica qué migración está ocurriendo n_migracion = 1; #ifdef _PRINT_MIGRACION_ printf("Espere, MAPAPOC en Rank %d está procesando archivo %s...\n", rank, nomarch); printf("Rank = %d tiene popsize %d, coord_ind_a_env %d, coord_ind_a_rec %d, coord_ind_global % d, tasa_migracion %d...\n", rank, popsize, coord_ind_a_env, coord_ind_a_rec, coord_ind_global, tasa_migracion); #endif //Actualiza Resultados Estadísticos Evolutivos para cada problema particular fprintf(evofp, "\n\nCorrida : %d, PROBLEMA : %s\n", run, nomarch); fprintf(evofp, "Migracion Generacion Minimo Maximo Media DesvEstandar TiempoTranscurrido\n"); // Inicia la cuenta de Segundos time_start = MPI_Wtime(); //Rutina de inicialización de variables globales initialize(); //Dimensiona poblaciones de individuos que recibe y envía... initmallocMaster(coord_ind_a_rec, coord_ind_a_env, coord_ind_global); //Define tipos de Individuos a Enviar y Recibir Build_type_pop(envpop, &message_type_send, coord_ind_a_env); Build_type_pop(recpop, &message_type_receive, coord_ind_a_rec); if (modelo_migracion == 0) //Establece comunicación Asincrona con cada rank (AG) comunicacion_asincrona_con_cada_rank(); else //Establece comunicación sincrona con cada rank (AG) comunicacion_sincrona_con_cada_rank(); // Calcula cantidad de segundos que demoró en cada Algoritmo Genético time_end = MPI_Wtime() - time_start; time_consumation.elapsed_time = time_end; time_consumation.comm_time = time_comm; time_consumation.cpu_time = time_end - time_comm; //Graba datos en archivo de resultados del algoritmo genera_resultados_algoritmo(run, tipo_problema, nomarch, &time_consumation); //Graba datos en archivo de resultados del problema app_genera_resultados_problema(run, tipo_problema, nomarch); //IMPRIME SALIDA PARA PROGRAMA PARAMILS /* printf("RunsExecuted = 1\n"); printf("CPUTime_Mean = %f\n", time_consumation.elapsed_time); printf("BestSolution_Mean = %f\n", bestfit.fitness); */ /* printf("Result for ParamILS: SAT, %f, %i, %f, %s\n", -1.0, -1, bestfit.fitness, argv[7]); */ printf("Resultado: SAT, %s, %f, %f, %f, %f\n", nomarch, time_consumation.elapsed_time, time_consumation.cpu_time, bestfit.fitness, randomseed); //Genera la Salida hacia archivo de Resultados LAYOUT app_objfuncfinal(tipo_problema, &(bestfit)); //Libera memoria del Coordinador freeallMaster(coord_ind_a_rec, coord_ind_a_env, coord_ind_global); //Libera memoria tipos creados por MPI MPI_Type_free(&message_type_send); MPI_Type_free(&message_type_receive); }//End if else { printf("!!! ERROR ¡¡¡ Rank 0, en datos del archivo de piezas <%s> => Archivo no procesado...\n", nomarch); //Envía a cada Rank que ARCHIVO_INSTANCIA está con algún error envia_a_cada_rank(MSJ_ERROR_ARCHIVO_INSTANCIA); }//End else }//End if else { printf("!!! ERROR ¡¡¡ Rank 0, en datos del archivo de piezas <%s> => Archivo no procesado...\n", nomarch); //Envía a cada Rank que ARCHIVO_INSTANCIA está con algún error envia_a_cada_rank(MSJ_ERROR_ARCHIVO_INSTANCIA); }//End else // Libera variables del problema app_free(tipo_problema); #ifdef _PRINT_MIGRACION_ printf("#Corrida %d, Archivo %s procesado por Coordinador... [OK]\n", run, nomarch); #else // printf("#Corrida %d, Archivo %s procesado... [OK]\n", run, nomarch); #endif }//End for if(runmax == 0){ //Que runmax = 0 significa que la consistencia del archivo arrojó un error printf("Archivo %s NO procesado por Rank %d debido a error... [OK]\n", nomarch, rank); }//End if }//End else //Cierra archivos cierra_archivos(); //Rutina para MPI MPI_Finalize(); #ifdef _PRINT_MIGRACION_ printf("Terminó rank = %d...\n", rank); #endif exit(0); }//End main
void ga() { static char taken[MAXCHIPS]; double prob; int gen=1,i,j,k,ix,iy,a,b,t,*p,*q,*r,rev; int best=-1; popdata=malloc(sizeof(int)*chips*(POP+CAND)); if(!popdata) error("out of memory"); initpop(); while(1) { if(gen%100==0) printf("start of generation %d\n",gen); gen++; qsort(pop,POP,sizeof(ind_t),compo); if(best!=pop[0].cost) { best=pop[0].cost; printind(0); } normalizecumul(); nextp=POP; for(i=0;i<CAND;i++) { again: prob=rand01(); if(prob<UNI1) { /* mutation operator 1: swap 2 nodes */ ix=pickparent(); copyind(POP+i,ix); /* swap 2 random elements */ a=rand()%chips; do b=rand()%chips; while(a==b); p=popdata+pop[POP+i].dataptr*chips; t=p[a]; p[a]=p[b]; p[b]=t; fixind(p); if(!compo(pop+POP+i,pop+ix)) goto again; /* if no change, discard */ pop[POP+i].cost=findcost(p); pop[POP+i].fitness=calcfitness(pop[POP+i].cost); nextp++; } else if(prob<UNI1+UNI2) { /* mutation operator 2: move 1 node */ ix=pickparent(); copyind(POP+i,ix); /* pick random element, and new position for it */ a=rand()%chips; do b=rand()%chips; while(a==b); p=popdata+pop[ix].dataptr*chips; q=popdata+pop[POP+i].dataptr*chips; for(j=0;j<chips;j++) q[j]=-1; q[b]=p[a]; for(j=k=0;j<chips;j++) if(j!=a) { while(k<chips && q[k]>-1) k++; if(k==chips) printf("sanity error"); q[k++]=p[j]; } fixind(q); pop[POP+i].cost=findcost(p); pop[POP+i].fitness=calcfitness(pop[POP+i].cost); nextp++; } else { /* crossover operator: copy substring from parent 1, take remaining nodes from parent 2 in order of occurrence */ ix=pickparent(); do iy=pickparent(); while(ix==iy); copyind(POP+i,iy); a=rand()%chips; b=rand()%chips; if(a>b) t=a,a=b,b=t; b++; do t=rand()%chips; while(t+b-a>chips); rev=rand()&1; p=popdata+pop[ix].dataptr*chips; q=popdata+pop[iy].dataptr*chips; r=popdata+pop[POP+i].dataptr*chips; for(k=0;k<chips;k++) r[k]=-1; for(k=0;k<chips;k++) taken[k]=0; if(rev) for(j=0;j<b-a;j++) taken[p[j+a]]++,r[t+b-a-j-1]=p[j+a]; else for(k=a;k<b;k++) taken[p[k]]++,r[k+t-a]=p[k]; for(k=j=0;k<chips;k++) if(!taken[q[k]]) { while(j<chips && r[j]>-1) j++; if(j==chips) printf("sanity error"); r[j++]=q[k]; } fixind(r); if(!compo(pop+POP+i,pop+ix)) goto again; /* if no change, discard */ if(!compo(pop+POP+i,pop+iy)) goto again; /* if no change, discard */ pop[POP+i].cost=findcost(r); pop[POP+i].fitness=calcfitness(pop[POP+i].cost); nextp++; } } /* sort all children */ qsort(pop+POP,CAND,sizeof(ind_t),compo); /* ensure we only have unique elitists */ /* here shallow copy is ok! */ if(ELITISM) for(j=i=1;i<ELITISM;i++) { if(compo(pop+i,pop+i-1)) pop[j++]=pop[i]; } else j=0; pop[j++]=pop[POP]; /* ensure we only have unique children */ for(i=POP+1;j<POP && i<POP+CAND;i++) if(compo(pop+i,pop+i-1)) pop[j++]=pop[i]; if(j<POP) error("ga failed, need more unique children"); compress(); } }