int run_alg(struct rcps_solver *s, struct rcps_problem *p) { /* run the algorithm */ int end = 0; int count = 0; int tcount = 0; int lcount = 0; struct rcps_fitness last_fitness; int last_overuse = 1; int breakoff_count = 0; int desperate = 0; last_fitness.group = FITNESS_MAX_GROUP; last_fitness.weight = 0; fflush(stderr); // make this configurable breakoff_count = 100000 / s->jobs; #ifdef HAVE_PTHREAD // XXX look at error code pthread_mutex_lock(&s->lock); #endif do { // breed int i,j; int son_overuse, daughter_overuse, best_overuse; struct rcps_individual *father; struct rcps_individual *mother; struct rcps_individual *son; struct rcps_individual *daughter; struct rcps_phenotype *pheno; struct rcps_fitness f1, f2; f1.group = FITNESS_MAX_GROUP; f1.weight = 0; f2 = f1; son = (struct rcps_individual*)malloc(sizeof(struct rcps_individual)); son->genome.schedule = (int*)malloc(sizeof(int) * p->job_count); son->genome.modes = (int*)malloc(p->genome_modes * sizeof(int)); son->genome.alternatives = (int*)malloc(p->genome_alternatives * sizeof(int)); daughter = (struct rcps_individual*)malloc(sizeof(struct rcps_individual)); daughter->genome.schedule = (int*)malloc(sizeof(int) * p->job_count); daughter->genome.modes = (int*)malloc(p->genome_modes * sizeof(int)); daughter->genome.alternatives = (int*)malloc(p->genome_alternatives * sizeof(int)); // select father and mother // XXX we want a configurable bias towards better individuals here i = irand(s->population->size - 1); j = 1 + irand(s->population->size - 1); j = (i + j) % s->population->size; father = (struct rcps_individual*)slist_node_getdata( slist_at(s->population->individuals, i)); mother = (struct rcps_individual*)slist_node_getdata( slist_at(s->population->individuals, j)); // crossover sched_crossover2(s, p, father->genome.schedule, mother->genome.schedule, son->genome.schedule, daughter->genome.schedule); crossover2(father->genome.modes, mother->genome.modes, son->genome.modes, daughter->genome.modes, p->genome_modes); crossover2(father->genome.alternatives, mother->genome.alternatives, son->genome.alternatives, daughter->genome.alternatives, p->genome_alternatives); #ifdef HAVE_PTHREAD // XXX look at error code pthread_mutex_unlock(&s->lock); #endif // mutate sched_mutation(s, p, son->genome.schedule, s->mut_sched); sched_mutation(s, p, daughter->genome.schedule, s->mut_sched); mutation(son->genome.modes, p->modes_max, p->genome_modes, s->mut_mode); mutation(daughter->genome.modes, p->modes_max, p->genome_modes, s->mut_mode); mutation(son->genome.alternatives, p->alternatives_max, p->genome_alternatives, s->mut_alt); mutation(daughter->genome.alternatives, p->alternatives_max, p->genome_alternatives, s->mut_mode); // add to population pheno = decode(s, p, &son->genome); son->fitness = fitness(p, &son->genome, pheno); son_overuse = pheno->overuse_count; pheno = decode(s, p, &daughter->genome); daughter->fitness = fitness(p, &daughter->genome, pheno); daughter_overuse = pheno->overuse_count; #ifdef HAVE_PTHREAD // XXX look at error code pthread_mutex_lock(&s->lock); #endif add_individual(son, s->population); add_individual(daughter, s->population); // check if we have a better individual, if yes reset count f1 = ((struct rcps_individual*)slist_node_getdata(slist_first( s->population->individuals)))->fitness; // get the best overuse count best_overuse = son_overuse < daughter_overuse ? son_overuse : daughter_overuse; // check if we want to stop if (rcps_fitness_cmp(&f1, &last_fitness) < 0) { last_fitness = f1; last_overuse = best_overuse; count = 0; } count++; tcount++; if (count >= breakoff_count) { if ((last_overuse > 0) && (!desperate)) { // we are going into desperate mode desperate = 1; breakoff_count *= 10; // XXX threading problem: do not do this because is affects // other threads too! intead us desperate accordingly above /* s->population->size *= 5; s->mut_sched += 1000; s->mut_mode += 1000; s->mut_alt += 1000;*/ } else { end = 1; } } // XXX if we use multiple threads, communicate to the others as well! if (s->progress_callback) { if (tcount >= (lcount + s->cb_steps)) { end |= s->progress_callback(tcount, last_fitness, s->cb_arg); lcount = tcount; } } } while (!end); #ifdef HAVE_PTHREAD // XXX look at error code pthread_mutex_unlock(&s->lock); #endif return tcount; }
void* slist_peekn(slist* list, int n) { return slist_at(list,n); }