int main(void)
{	
	int popsize = 0, max_iter = 0;
	char target[128];
	char str_buffer[64];

	FILE *fp = fopen("conf", "r");
	fscanf(fp, "%s %d", &str_buffer, &popsize);
	fscanf(fp, "%s %s", &str_buffer, &target);
	fscanf(fp, "%s %d", &str_buffer, &max_iter);

	int target_length = strlen(target);

	srand(time(NULL));

	printf("Genetic Algorithm to find a user-specified target string\n");
	printf("Quinn Thibeault - 2015\n");
	printf("Target string: %s Length: %d\n", target, target_length);
	printf("Population Size: %d\n", popsize);
	printf("Maximum Iterations: %d\n\n", max_iter);
	
	struct organism population[POPSIZE], buffer[POPSIZE];
	
	struct organism *p_pop = population;
	struct organism *p_buf = buffer;

	init_population(p_pop, target_length);
	init_population(p_buf, target_length);

	gen_random_population(p_pop, target_length);
	
	
	for(int i=0;i<ITER; ++i){
		calc_fitness(p_pop, target, target_length);
		sort_by_fitness(p_pop);
		//print_most_fit(p_pop);
		
		if(p_pop->fitness == 0){
			printf("Number of generations: %d\n", i);
			break;
		}

		regen_population(p_pop, p_buf, target_length);
		swap(&p_pop, &p_buf);
	}
	
	print_most_fit(p_pop);	
	
	return 0;
}
Пример #2
0
int main(int argc, char *argv[]) {
	int my_rank;
	double mpi_start_time, mpi_end_time;
	deme *subpop = (deme*) malloc(sizeof(deme));

	MPI_Init(&argc, &argv);
	MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
	init_population(subpop, argc, argv);
	mpi_start_time = MPI_Wtime();

	while (!subpop->complete) {
		migration(subpop);
		reproduction(subpop);
		crossover(subpop);
		mutation(subpop);
		fitness(subpop);
		subpop->old_pop = subpop->new_pop;
		subpop->cur_gen++;
		check_complete(subpop);
		sync_complete(subpop);
		report_all(subpop);
	}
	
	mpi_end_time = MPI_Wtime();
	report_fittest(subpop);
	MPI_Finalize();
	printf("[%i] Elapsed time: %f\n", my_rank, mpi_end_time - mpi_start_time);
	return 1;
}
Пример #3
0
/* initialize the network */
network* init_network(int npop, int psz)
{
	network* n = (network*)calloc(1, sizeof(network));
	n->nsize = npop;
	n->pops = (population*)calloc(n->nsize, sizeof(population));
	for (int i = 0; i<n->nsize; i++)
		n->pops[i] = init_population((short)i, psz);

	return n;
}
/**
 * main program
 */
int
main (void)
{

	float cpu1,cpu2;	
	cpu1 = ((float) clock())/CLOCKS_PER_SEC;
  srand (time (NULL));

  ga_struct *population = malloc (sizeof (ga_struct) * POPSIZE);
  ga_struct *beta_population = malloc (sizeof (ga_struct) * POPSIZE);

  init_population (population, beta_population);


  char *gen_str = population[0].gen;
char element[5] = "\0";
	  strncpy (element, gen_str, 4);
	  //if (strcmp ("0000", element) == 0)
	  
	  
  int index = 0;
  for (; index < POPSIZE; index++)
    {
      
      cal_fitness (population);
      
      sort_by_fitness (population);
      

      // print current best individual
      printf ("binary string: %s - fitness: %d\n", population[0].gen,
	      population[0].fitness);

      if (population[0].fitness == 0)
	{
	  //~ print equation
	  decode_gen (&population[0]);
	  break;
	}
	  
      mate (population, beta_population);
      swap (&population, &beta_population);
      
    }

  free_population (population);
  free_population (beta_population);
cpu2 = ((float) clock())/CLOCKS_PER_SEC;
  

  printf("Execution time (s) = %le\n",cpu2-cpu1);

  return 0;
}
Пример #5
0
int main(int argc, char *argv[])
{
  INDIVIDUAL pop[POPSIZE];
  GN_TREE gn_tree;
  int generation;

  gn_init_tree(&gn_tree);
  init_population(pop, &gn_tree);
  for (generation = 0; generation < 100; generation++)
  {
    if ((generation % 30) == 0)
    {
      fprintf(stdout, "g %d\n", generation);
      gn_print_jftrees(&gn_tree, generation, stdout);
    }
    fitness(pop);
    selection(pop, &gn_tree, generation);
    mutation(pop);
  }
  gn_free_tree(&gn_tree);
  return (EXIT_SUCCESS);
}
Пример #6
0
int main(int argc, char *argv[])
{
	// Need to change to 3. need to remove the logging.
	if (argc != 4)
	{
		printf("Usage: ./maxcut <input data path> <output data path> <log file>\n");
		exit(-1);
	}
	
	// Need to remove when submitting.
	log_file = fopen(argv[3], "w");
	fprintf(log_file, "rate, elasped time (s), max val, avg val\n");

	start_time = get_seconds();

	in 		= fopen(argv[1], "r");
	out 	= fopen(argv[2], "w");
	int i, j, v1, v2, w;	// (v1, v2) is the vertex and w is the weight

	fscanf(in, "%d %d\n", &num_of_vertex, &num_of_edge);
	
	int edge[num_of_vertex+1][num_of_vertex+1];
	
	for (i=0; i<=SIZE; i++)
		for (j=0; j<=SIZE; j++)
			edge[i][j] = 0;

	while (fscanf(in, "%d %d %d\n", &v1, &v2, &w) != EOF)
	{
		edge[v1][v2] = w;
		edge[v2][v1] = w;
	}
	
	init_population();
	init_offsprings();
	init_cost(edge);
	sort_population();
	init_crossover();

	int p1, p2;

	while (!(stop_condition()))
	{
		generation++;
		for (i=1; i<=K; i++)
		{
			selection(&p1, &p2);
			crossover(i, p1, p2);
			mutation(i);
			local_optimization(i, edge);
		}

		replacement(edge);

		sort_population();
	}

	for (i=1; i<=SIZE; i++)
	{
		if (population[N]->ch[i] == 1)
			fprintf(out, "%d ", i);
	}

	free_population();

	fclose(in);
	fclose(out);

 	printf("N: %d, K: %d, S_RATE: %lf, M_THRE: %lf, P0: %lf, POINTS: %d, K_FIT: %d, T: %lf\n", N,     K, S_RATE, M_THRE, P0, POINTS, K_FIT, T);


	return 0;
}
Пример #7
0
	bat_t algorithm(float A, float r, uint pop_size, uint max_it, fit_t (*fit_fnc)(bat_t &), float q_min=0, float q_max=MAX/10, uint debug=1, std::vector<float> *avg_fit_at_it=NULL, std::vector<float> *best_at_iter=NULL) {
		srand(time(NULL)); /*inits randomness*/

		bats_t population;
		bats_fit_t fit;

		std::vector<float> Q(pop_size); /*frequency*/
		std::vector<bat_t> v(pop_size); /*bats velocity*/

		/*inits bats velocity to zero*/
		std::for_each(v.begin(), v.end(), [](bat_t &velocity) { velocity = init_bat(BAT_LENGTH, 0.0, 0.0); });

		init_population(population, pop_size, BAT_LENGTH);
		init_fit(fit, pop_size);
		uint it = 0;

		do {
		/*one iteration of bat alg.*/
		evaluate_population(fit, population, fit_fnc);
		bat_t best_bat = utils::return_best_bat(population, fit);

		if (debug >=2) {
			best_at_iter->push_back(fit_fnc(best_bat));
			avg_fit_at_it->push_back(std::accumulate(fit.begin(), fit.end(), 0.0) / fit.size());
		}

		uint index = 0;

		std::for_each(population.begin(), population.end(), [&](bat_t &bat) {
			//Q[index] = utils::rand_in<float>(Q_MIN, Q_MAX);
			Q[index] = utils::rand_in<float>(0.0, 0.1);

			bat_t candidate_v = v[index] + (bat - best_bat)*Q[index];
			bat_t candidate_bat = bat + candidate_v;

			if (utils::rand_in<float>(0.0,1.0) > r) {
				/*random walk in direction of candidate_v scalled down by q_max/100 factor*/
				for (int i=0;i<2;i++) {
					candidate_v = init_bat(BAT_LENGTH)*(q_max/100);
					candidate_bat = best_bat+candidate_v;
				}
			}

			/*evaluate candidate solution, it might be either solution found by appling movement equotions to current solution or by using random walk around best solution*/
			float candidate_bat_fit = fit_fnc(candidate_bat);

			/*accept candidate solution as current solution if better or if not better accept solution with some small probability*/
			if (candidate_bat_fit < fit[index] || utils::rand_in<float>(0.0,1.0) < A) {
				bat = candidate_bat;
				v[index] = candidate_v;
				fit[index] = candidate_bat_fit;
			}

			index++;
		});

		if (debug>=1 && it%100==1) {
			evaluate_population(fit, population, fit_fnc);
			bat_t best = utils::return_best_bat(population, fit);
			std::cout << "at iteration: " << it << " pop avg fit: " <<  std::accumulate(fit.begin(), fit.end(), 0.0) / fit.size() << " best bat fit: " << fit_fnc(best) << std::endl;
		}
		}while(++it < max_it);

		/*find and return best solution*/
		evaluate_population(fit, population, fit_fnc);
		return utils::return_best_bat(population, fit);
	}
Пример #8
0
int  main(int argc, char **argv){

    int rc,num_processors,rank;
    rc=MPI_Init(&argc,&argv);
    if (rc != MPI_SUCCESS) {
    	printf("Error starting MPI program. Terminating\n");
           MPI_Abort(MPI_COMM_WORLD, rc);
    }
   
    MPI_Comm_size(MPI_COMM_WORLD,&num_processors);
    MPI_Comm_rank(MPI_COMM_WORLD,&rank);

   //**************************************************************************************//
   //                  reading input information by all cores                              //
   //**************************************************************************************//
    FILE     *fpenergy=fopen("./energy","w"); // Print the energy evolution
    FILE     *fprestart=fopen("./restart","w"); //print the generation and popsize coordinates
    FILE     *fpoptim=fopen("./optim.xyz","wb");
    FILE     *fp=fopen("data.txt","r");
    time_t    current_time;
    double    seconds,start,end,seconds_new,seconds_old,seconds_total;
    struct    timespec now,tmstart;
    char*     c_time_string,c_time_final;
    int       flag_converge=0;
    int       i=0; 
   
    srand(time(NULL)+rank);
    clock_gettime(CLOCK_REALTIME, &tmstart);
    printf("hello from processor %ld\n",rank);
    start = (double)clock() /(double) CLOCKS_PER_SEC;
    seconds_old=  (double)(tmstart.tv_sec+tmstart.tv_nsec*1e-9);
    current_time = time(NULL);
    c_time_string = ctime(&current_time);
    printf("Current time is %s\n", c_time_string);
    printf("hello from processor %ld\n",rank);
   
 
    char skip[10];
    FILE     *fp_input2 = fopen("ga_dftb_input1.1","r");
    int       NSTEP=0;
    int       step=0;
    double    ee_mate=0 ;       // the energy cretiria for accepting children cluster. the larger, the less restrict. can be 0.1 0 or -0.1 
    double    ELITRATE=0.2;
    int       POPSIZE=0;
    int       min_step=0;
    int       NEWPOPSIZE=POPSIZE;
    double    delte=0.00001 ; //0.00001;
    int       ptnatm,runatm,cnatm;
    double    boxl=0;
    double    Mu=0.2;
    double    dptc;
    int       glob=0,globconvg=20;
    double    globe[30];
    int       Temp; 
    int       flag_res=0;
    double    cell[9];
    int       esize=0;
    int       num_cores_child;
      
    fscanf(fp_input2,"%d  %d %d %s\n", &ptnatm, &runatm,&cnatm,&skip);
    fscanf(fp_input2,"%d %s\n ", &POPSIZE,skip);
    fscanf(fp_input2,"%d %s\n", &NSTEP,skip);
    fscanf(fp_input2,"%d %s\n", &globconvg,skip);
    fscanf(fp_input2,"%lf %s\n",&ELITRATE,skip);
    fscanf(fp_input2,"%lf %s\n",&delte,skip);
    fscanf(fp_input2,"%d %s\n",&Temp,skip);
    fscanf(fp_input2,"%d %s\n",&min_step,skip);
    fscanf(fp_input2,"%lf %s\n",&ee_mate,skip);
    fscanf(fp_input2,"%lf %s\n",&dptc,skip);
    fscanf(fp_input2,"%lf %s\n",&boxl,skip);
    fscanf(fp_input2,"%d %s\n",&flag_res,skip);
    fscanf(fp_input2,"%d %s\n",&num_cores_child,skip);
    int ii=0;
    for (ii=0;ii<3;ii++){
        fscanf(fp_input2,"%lf %lf %lf\n", cell+ii*3+0,cell+ii*3+1,cell+ii*3+2);


   //**************************************************************************************//
   //         Above are the information that all processors need to know                   //
   //**************************************************************************************//

    if(rank==0){
        }
       
        printf("********************JOB started*****************************\n");
        printf("********************JOB started*****************************\n");
        printf("********************JOB started*****************************\n\n\n");


        printf("Attention!! The  dftb excutable file must be in ~/bin and must be named 'dftb+' !!\n");
        printf("Attention!! The  dftb excutable file must be in ~/bin and must be named 'dftb+' !!\n");
        printf("Attention!! The  dftb excutable file must be in ~/bin and must be named 'dftb+' !!\n");
        printf("Attention!! The  dftb excutable file must be in ~/bin and must be named 'dftb+' !!\n");
        printf("Attention!! The  dftb excutable file must be in ~/bin and must be named 'dftb+' !!\n");


        printf("Number of atoms %d %d %d\n", ptnatm,runatm,cnatm);
        if(ptnatm+runatm>=Max_Atom || cnatm>=CMax_Atom) exitp("Number of atoms exceed allowed Max!");
        printf("POPSIZE         %d\n",POPSIZE);
        printf("NSTEP           %d\n",NSTEP);
        printf("globconvg       %d\n",globconvg);
        printf("ELITRATE        %lf\n",ELITRATE);
        printf("delte           %lf\n",delte);
        printf("Temprature      %d\n",Temp);
        printf("minimiz   step  %d\n",min_step);
        printf("ee_mate         %lf\n",ee_mate);
        printf("dptc            %lf\n",dptc);
        printf("intial boxl     %lf\n",boxl);
        printf("reading from pt_coord?  %d\n",flag_res);
        printf("Total number of processsors required  %d\n",num_processors);
        printf("Number of processors for each child  %d\n",num_cores_child);
        printf("\n\n\n******** end reading input information ***********************\n\n\n");
    }
    if(POPSIZE!=num_processors/num_cores_child){
        printf("Error!,POPSZIE=%d num_processrs=%d num_cores_child=%d num_processrs/num_cores_child=%d",\
                POPSIZE,num_processors,num_cores_child,num_processors/num_cores_child);
        MPI_Abort(MPI_COMM_WORLD,0);
    }    

 
    ga_struct *population = malloc(sizeof(ga_struct)*POPSIZE);
    ga_struct *beta_population = malloc(sizeof(ga_struct)*POPSIZE);

 
//****************************************************************************************//
//define new mpi structure for data transfer between processors                           //
//****************************************************************************************//
    int count=4;
    int length[4]={1,3*Max_Atom,3*CMax_Atom,1};
    MPI_Aint offset[4]={offsetof(ga_struct,fitness),offsetof(ga_struct,gen),offsetof(ga_struct,cgen),offsetof(ga_struct,ep)} ;
    MPI_Datatype type[4]={MPI_DOUBLE,MPI_DOUBLE,MPI_DOUBLE,MPI_DOUBLE};
    MPI_Datatype popDatatype;
    MPI_Type_struct(count,length,offset,type,&popDatatype);
    MPI_Type_commit(&popDatatype);
//****************************************************************************************//


//****************************************************************************************//
//Initialization the population for all processors                                        // 
//****************************************************************************************//

    
    
    if(rank==0){
        printf("Total number of processors is %d\n",num_processors);
        printf("Total number of population is %d\n",POPSIZE);
        printf ("For each candidate, there are %d processors to be used\n",num_processors/POPSIZE);
        init_population(ptnatm+runatm,cnatm,POPSIZE,population,beta_population,boxl,flag_res);
        printf("argc=%d\n",argc);
//        int  i=0,j=0;
//        int  esize=POPSIZE*ELITRATE;
        cal_pop_energy(POPSIZE,population,ptnatm,runatm,cnatm,cell,argc, argv);
///        for (i=0;i<POPSIZE;i++){
////////      center(ptnatm+runatm,population[i].gen);  
///           write_coord(fpoptim,ptnatm,runatm,cnatm,population[i].gen,population[i].cgen,population[i].ep);
//           shift(ptnatm+runatm, population[i].gen,dptc);  
///        } 
//        for (i=0;i<POPSIZE;i++)
//           write_coord(fpoptim,ptnatm,runatm,cnatm,population[i].gen,population[i].cgen,population[i].ep);
        fflush(fpoptim);
    }

    char command[30];
    char filename[30];
 
    sprintf(command,"mkdir core%d",rank);
    system(command);
    sprintf(command,"cp dftb_in.hsd *.coord *.skf core%d",rank);
    system(command);
    sprintf(filename,"core%d",rank);
    chdir(filename);
    system("pwd");    

//****************************************************************************************//
//              Loop started                                                              // 
//****************************************************************************************//

    for (step=0;step<NSTEP;step++){ 


       //*********************************************************************************//
       //              master core preparation                                            // 
       //*********************************************************************************//

        if(rank==0){
            cal_pop_energy(POPSIZE,population,ptnatm,runatm,cnatm,cell, argc, argv);
            printf("\n\n\n\n***********************************************\n");
            printf(  "***********************************************\n");
            printf(  "***********************************************\n");
            printf("Gen= %d starting optimization..................\n\n",step); 
        
            qsort (population, POPSIZE, sizeof(ga_struct),sort_func);
        
            normal_fitness(POPSIZE,population);
        
            for(i=0;i<POPSIZE;i++){
                fprintf(fpenergy,"%d num %d   %lf\n",step, i,population[i].ep);
                fflush(fpenergy);
            }  
        
            printf("fabs %lf\n",fabs(population[0].ep-population[POPSIZE-1].ep));
        
            if(fabs(population[0].ep-population[POPSIZE-1].ep)<delte){    
                fprintf(fpenergy,"%d %lf  %lf global minimum \n",step,population[0].ep,population[0].fitness);
                globe[glob]=population[POPSIZE-1].ep;
                glob=glob+1;           
            }
        
            if(glob>20){
                if(fabs(globe[glob]-globe[glob-20])<delte){
                    fprintf(fpenergy,"%d %lf  %lf final global minimum \n",step,population[0].ep,population[0].fitness);
                    flag_converge=1;
                }
            }

///// PPreserve the first esize parentes from the previous generation. copy from population to beta_population
            esize=POPSIZE*ELITRATE;
            if (esize<1){esize=1;}
            elitism(esize,ptnatm+runatm, cnatm,population,beta_population);

            for (i=1;i<num_processors;i++)
                MPI_Send(population,POPSIZE,popDatatype,i,0,MPI_COMM_WORLD); 
        
            
               //send coordinates and energy information to other ith  processors
        }else MPI_Recv(population,POPSIZE,popDatatype,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);

       //*********************************************************************************//
       //              master core preparation ended                                      // 
       //*********************************************************************************//



       //*********************************************************************************//
       //              other cores mating start                                           // 
       //*********************************************************************************//


       //receive coordinates and energy information from 0(master) core
        MPI_Bcast(&flag_converge, 1, MPI_INT,0,MPI_COMM_WORLD);
//        printf("rank=%d,xyz=%lf\n",rank,population[0].gen[0][0]);

        if(flag_converge ==1) {MPI_Finalize(); exit(0);}    
        
//        for (i=0;i<POPSIZE;i++)
//           write_coord(fpoptim,ptnatm,runatm,cnatm,population[i].gen,population[i].cgen,population[i].ep);
        fflush(fpoptim);
//        printf("rank=%d,xyz=%lf\n",rank,population[0].gen[0][0]);

       // Generate the rest part of beta_generation by mating process
        if(rank!=0&&rank<POPSIZE)
            mate(ptnatm,runatm,cnatm,cell,esize,POPSIZE,population,beta_population,Temp,ee_mate,dptc,min_step,argc, argv);
        MPI_Barrier(MPI_COMM_WORLD);
                       
        if(rank!=0&&rank<POPSIZE)
            MPI_Send(&beta_population[0],1,popDatatype,0,1,MPI_COMM_WORLD); //send the information of first children(optimized) from other processors to master core 

       //*********************************************************************************//
       //              other cores mating ended                                           // 
       //*********************************************************************************//
 


        if(rank==0){
            for (i=1;i<POPSIZE;i++)
                MPI_Recv(&population[i],1,popDatatype,i,1,MPI_COMM_WORLD,MPI_STATUS_IGNORE); //recieve coordinates and energy information to other ith  processors
            if (ptnatm!=0&&runatm!=0)
                mutate_perm (ptnatm,runatm, Mu, POPSIZE, beta_population);
            fprestart=fopen("./restart","w");
            for (i=0;i<POPSIZE;i++){
                write_coord(fpoptim,ptnatm,runatm,cnatm,population[i].gen,population[i].cgen,population[i].ep);
                write_coord(fprestart,ptnatm,runatm,cnatm,population[i].gen,population[i].cgen,population[i].ep);
                fflush(fpoptim);
                fflush(fprestart);
            } 
            fclose(fprestart);

         
        clock_gettime(CLOCK_REALTIME, &now);
        seconds_new = (double)((now.tv_sec+now.tv_nsec*1e-9));
        seconds=seconds_new-seconds_old;
        seconds_total = (double)((now.tv_sec+now.tv_nsec*1e-9) - (double)(tmstart.tv_sec+tmstart.tv_nsec*1e-9));
        printf("\nWall time for this generation is %lf s\n",seconds);
        printf("\nWall time totally  %lf s\n",seconds_total);
        seconds_old=seconds_new;
    
        }
 	  
   }




//*********************************************************************************
//************************************loop ended***********************************
//*********************************************************************************


    if(rank==0){ 
        printf("\n********************JOB FINISHED*****************************\n");
        fclose(fpenergy);
        fclose(fpoptim);
       
///////// time information
        current_time = time(NULL);
        c_time_string = ctime(&current_time);
        printf("Current time is %s\n", c_time_string);
        
         // measure elapsed wall time
        clock_gettime(CLOCK_REALTIME, &now);
        seconds = (double)((now.tv_sec+now.tv_nsec*1e-9) - (double)(tmstart.tv_sec+tmstart.tv_nsec*1e-9));
        printf("wall time %fs\n", seconds);
       
         // measure CPU  time
        end = (double)clock() / (double) CLOCKS_PER_SEC;
        printf("cpu time %fs\n", end - start);
        printf("\n********************JOB FINISHED*****************************\n");
        free(population);
        free(beta_population);
    }     
}
Пример #9
0
int run_alps(int *steps)
{
  int i,j,k,p;
  double temp_fitness[FITNESS_COUNT];
  double temp_gene[GENE_COUNT];
  int pareto_front[POP];
  int pareto_count;  

  begin = time(NULL);
  init_population();            // Initialise population.
  t = 0;
  goal_indiv = -1;

  mprintf(1, "preamble -> {expName -> %s, phaseCount -> %d, lobotomise -> %s, task -> %d, \n", exp_name, phase_count, lobotomise ? "True" : "False", task_index + 1);
  mprintf(1, "\ttmax -> %.2lf, fitnessType -> %d, runType -> %d, randomSeed -> %ld }\n", TIME_MAX, fitness_type, run_type, random_seed);

  mprintf(1, "alpsParams -> { layerCount -> %d, popPerLayer -> %d, "
          "popCount -> %d, mutProbability -> %.3f, maxSeconds -> %d }\n",
          LAYER_COUNT, POP_PER_LAYER, POP, mut_prob, MAX_SECONDS);
  fflush(stdout);

  for (p = 0, phase = 1; 
       p < phase_count && elapsed_seconds() < MAX_SECONDS; 
       p++, phase = p + 1) {

    if (p != 0) end_phase(p);
    start_phase(phase);
    for (i = 0; i < POP; i++) {
      // Evaluate every gene.
      evaluate(genes[i], fitness_matrix + FITNESS_INDEX(i));
    }
    int met_goal = 0;
    for (j = 0; j < POP; j++) {
      if (is_goal_fitness(fitness_matrix + FITNESS_INDEX(j))) {
        met_goal = 1;
        goal_indiv = j;
      }
    }
    if (met_goal) 
      continue;
    
    for (; t < MAX_OPT_STEPS && elapsed_seconds() < MAX_SECONDS; t++) { 
      // Evaluate the pareto front for each layer.
      for (k = 0; k < LAYER_COUNT; k++) 
        pareto_front_rowmajor(pareto_front + k * POP_PER_LAYER, 
                              fitness_matrix 
                              + k * FITNESS_COUNT * POP_PER_LAYER,
                              POP_PER_LAYER,
                              FITNESS_COUNT);

      // Grab a non-dominated individual.
      int a;
      // O(n) single pass to count and grab a random individual
      // that's on the pareto front.
      pareto_count=0;
      for (i = 0; i < POP; i++) 
        if (pareto_front[i] && (rand() < 1./(double)++pareto_count))
            a = i;
      k = LAYER_OF_INDIV(a);

      if (t % DISPLAY_FREQ == 0) {
        int n = FITNESS_INDEX(a);
        if (! quiet)
        printf("t = %5d, pi = %3d, a = %2d, k = %2d, N(PF) = %2d, f(a) = {%f, %f}, "
               "efail = %3d, esucc = %5d, secs = %4ld\n", t, a, ages[a], k, 
               pareto_count, fitness_matrix[n], fitness_matrix[n + 1], 
               eval_fail_count, eval_succ_count, elapsed_seconds());

        fflush(stdout);
      }

      if (t % reset_freq == 0) {
        // Reset the bottom layer.
        for (i = 0; i < POP_PER_LAYER; i++) {
          // Try to dislogde in the layer above if it's in the pareto front.
          if (pareto_front[i])
            try_dislodge(genes[i], fitness_matrix + FITNESS_LINDEX(0, i), ages[i], 1);

          init_gene(genes[i]);
          ages[i] = 0;
        }
        for (i = 0; i < POP_PER_LAYER; i++)
          evaluate(genes[i], fitness_matrix + FITNESS_INDEX(i));
        pareto_front_rowmajor(pareto_front, fitness_matrix, POP_PER_LAYER,
                              FITNESS_COUNT);
      }

      copy(genes[a], temp_gene);
      mutate(temp_gene);
      int age = t/POP;
      evaluate(temp_gene, temp_fitness);
      int new_i = try_dislodge(temp_gene, temp_fitness, age, k);
      if (is_goal_fitness(temp_fitness)) {
        if (new_i < 0) {
          printf("warning: goal individual not able to dislodge anyone in layer %d and up.\n", k);
        }
        goal_indiv = new_i;
        break;                  /* Goto next phase */
      }
    }
  }
  if (t == MAX_OPT_STEPS || elapsed_seconds() > MAX_SECONDS) 
    alps_status = ALPS_FAIL;
  else
    alps_status = ALPS_SUCC;

  end_phase(phase - 1);
  if (steps)
    *steps = t;

  return alps_status;
}