static void do_index(const char* dirname) { /* foreach jpg in dirname, compute channel average */ char filename[256]; DIR* dirp; struct dirent* dent; unsigned char rgb[3]; unsigned char ycc[3]; int line_len; int index_fd; char line_buf[256]; dirp = opendir(dirname); if (dirp == NULL) return ; sprintf(filename, "%s/%s", dirname, "tilit_index"); index_fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0644); dent = readdir(dirp); while (dent != NULL) { if (strcmp(dent->d_name, "tilit_index") == 0) goto skip_index; if (strcmp(dent->d_name, "wget.sh") == 0) goto skip_index; if (strcmp(dent->d_name, "wget.py") == 0) goto skip_index; if (strcmp(dent->d_name, ".") == 0) goto skip_index; if (strcmp(dent->d_name, "..") == 0) goto skip_index; sprintf(filename, "%s/%s", dirname, dent->d_name); average_rgb(filename, rgb); average_ycc(filename, ycc); line_len = sprintf ( line_buf, "%s %02x %02x %02x %02x %02x %02x\n", dent->d_name, rgb[0], rgb[1], rgb[2], ycc[0], ycc[1], ycc[2] ); write(index_fd, line_buf, line_len); skip_index: dent = readdir(dirp); } close(index_fd); closedir(dirp); }
void display() { if(!done && image_match(best_image, base_image)) { done = 1; } if(!paused && !done && generations < MAX_GENS) { float r; double accum_fitness = 0; fprintf(stderr, "evolving..."); // current best is start of sorted list t_image** new_pop = s_malloc(population_size * sizeof(t_image*)); // always add the best solution to survivors new_pop[0] = image_copy(best_image); // get more survivors using roulette wheel selection for(int i = 1; i < pop_select; i++) { r = rand_float(); for(int j = 0; j < population_size; j++) { accum_fitness += image_fitness(population[j]); if(accum_fitness >= r) { new_pop[i] = image_copy(population[j]); break; } } accum_fitness = 0; } // get a normalised fitness distribution for the survivors double survivor_fit[pop_select]; double survivor_sum_fit = 0; for(int i = 0; i < pop_select; i++) { survivor_fit[i] = image_fitness(new_pop[i]); survivor_sum_fit += survivor_fit[i]; } for(int i = 0; i < pop_select; i++) { survivor_fit[i] /= survivor_sum_fit; } // fill rest of population with children int i = pop_select; while(i < population_size) { // 2 random parents from survivors t_image* parents[N_PARENTS] = {0}; for(int j = 0; j < N_PARENTS; j++) { r = rand_float(); for(int k = 0; k < pop_select; k++) { accum_fitness += survivor_fit[k]; if(accum_fitness >= r) { parents[j] = new_pop[k]; break; } } accum_fitness = 0; } int p = 0; t_image* children[N_CHILDREN] = {0}; // seed children with parent data for(int c = 0; c < N_CHILDREN; c++) { children[c] = image_copy(parents[p]); /* NOTE: can get away with this instead of mod as parents is 2, but if we were to use more have to change it */ p = !p; } for(int x = 0; x < base_image->width; x++) { for(int y = 0; y < base_image->height; y++) { // crossover for(int c = 0; c < N_CHILDREN; c++) { /* // use 3 bits of c to get the 8 combinations for crossover p = (c & (1 << 0)) ? 1 : 0; children[c]->pix[x][y].r = parents[p]->pix[x][y].r; p = (c & (1 << 1)) ? 1 : 0; children[c]->pix[x][y].g = parents[p]->pix[x][y].g; p = (c & (1 << 2)) ? 1 : 0; children[c]->pix[x][y].b = parents[p]->pix[x][y].b; */ average_rgb(x, y, parents, children[c]); } // mutation for(int c = 0; c < N_CHILDREN; c++) { if(rand_float() <= MUTATION_RATE) mutate_rgb(&children[c]->pix[x][y]); } } } // add to new population for(int c = 0; c < N_CHILDREN; c++) { // this child is 'born' if(i < population_size && rand_float() <= CROSSOVER_RATE) { new_pop[i++] = children[c]; // you are dead to me! } else { free_image(children[c]); } } } // deallocate last generation for(int i = 0; i < population_size; i++) { free_image(population[i]); } free(population); // set new population as current population = new_pop; // determine new best member and compare to old best qsort(population, population_size, sizeof(t_image*), image_fitness_cmp); double current_fit = image_fitness(population[0]); if(current_fit < last_best) { free_image(best_image); best_image = image_copy(population[0]); last_best = current_fit; } generations++; fprintf(stderr, "done | gen %d | f %.1f\n", generations, current_fit); } // draw the best image glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, base_image->width, base_image->height, 0, 0, 1); glMatrixMode(GL_MODELVIEW); glBegin(GL_POINTS); for(int x = 0; x < best_image->width; x++) { for(int y = 0; y < best_image->height; y++) { glColor3f(best_image->pix[x][y].r/255.0, best_image->pix[x][y].g/255.0, best_image->pix[x][y].b/255.0); glVertex2f(x + 0.5f, y + 0.5f); } } glEnd(); glutSwapBuffers(); }