double * optimize(double(*pFun)(double const *), int nrestarts, double incpopsize, char * filename) { cmaes_t evo; /* the optimizer */ double *const*pop; /* sampled population */ double *fitvals; /* objective function values of sampled population */ double fbestever=0, *xbestever=NULL; /* store best solution */ double fmean; int i, irun, lambda = 0, /* offspring population size, 0 invokes default */ countevals = 0; /* used to set for restarts */ char const * stop; /* stop message */ for (irun = 0; irun < nrestarts+1; ++irun) /* restarts */ { /* Parameters can be set in three ways. Here as input parameter * to cmaes_init, as value read from cmaes_initials.par in readpara_init * during initialization, and as value read from cmaes_signals.par by * calling cmaes_ReadSignals explicitely. */ fitvals = cmaes_init(&evo, 0, NULL, NULL, 0, lambda, filename); /* allocs fitvals */ printf("%s\n", cmaes_SayHello(&evo)); evo.countevals = countevals; /* a hack, effects the output and termination */ cmaes_ReadSignals(&evo, "cmaes_signals.par"); /* write initial values, headers in case */ while(!(stop=cmaes_TestForTermination(&evo))) { /* Generate population of new candidate solutions */ pop = cmaes_SamplePopulation(&evo); /* do not change content of pop */ /* Here optionally handle constraints etc. on pop. You may * call cmaes_ReSampleSingle(&evo, i) to resample the i-th * vector pop[i], see below. Do not change pop in any other * way. You may also copy and modify (repair) pop[i] only * for the evaluation of the fitness function and consider * adding a penalty depending on the size of the * modification. */ /* Compute fitness value for each candidate solution */ for (i = 0; i < cmaes_Get(&evo, "popsize"); ++i) { /* We may resample the solution i until it lies within the feasible domain here. The function is_feasible() needs to be user-defined. Assumptions: the feasible domain is convex, the optimum is not on (or very close to) the domain boundary, initialX is feasible (or in case typicalX +- 2*initialStandardDeviations is feasible) and initialStandardDeviations is (are) sufficiently small to prevent quasi-infinite looping. */ /* while (!is_feasible(pop[i])) cmaes_ReSampleSingle(&evo, i); */ fitvals[i] = (*pFun)(pop[i]); } /* update search distribution */ cmaes_UpdateDistribution(&evo, fitvals); /* read control signals for output and termination */ cmaes_ReadSignals(&evo, "cmaes_signals.par"); /* from file cmaes_signals.par */ fflush(stdout); } /* while !cmaes_TestForTermination(&evo) */ lambda = incpopsize * cmaes_Get(&evo, "lambda"); /* needed for the restart */ countevals = cmaes_Get(&evo, "eval"); /* ditto */ /* print some "final" output */ printf("%.0f generations, %.0f fevals (%.1f sec): f(x)=%g\n", cmaes_Get(&evo, "gen"), cmaes_Get(&evo, "eval"), evo.eigenTimings.totaltime, cmaes_Get(&evo, "funval")); printf(" (axis-ratio=%.2e, max/min-stddev=%.2e/%.2e)\n", cmaes_Get(&evo, "maxaxislen") / cmaes_Get(&evo, "minaxislen"), cmaes_Get(&evo, "maxstddev"), cmaes_Get(&evo, "minstddev") ); printf("Stop (run %d):\n%s\n", irun+1, cmaes_TestForTermination(&evo)); /* write some data */ cmaes_WriteToFile(&evo, "all", "allcmaes.dat"); /* keep best ever solution */ if (irun == 0 || cmaes_Get(&evo, "fbestever") < fbestever) { fbestever = cmaes_Get(&evo, "fbestever"); xbestever = cmaes_GetInto(&evo, "xbestever", xbestever); /* alloc mem if needed */ } /* best estimator for the optimum is xmean, therefore check */ if ((fmean = (*pFun)(cmaes_GetPtr(&evo, "xmean"))) < fbestever) { fbestever = fmean; xbestever = cmaes_GetInto(&evo, "xmean", xbestever); } cmaes_exit(&evo); /* does not effect the content of stop string and xbestever */ /* abandon restarts if target fitness value was achieved or MaxFunEvals reached */ if (stop) /* as it can be NULL */ { if (strncmp(stop, "Fitness", 7) == 0 || strncmp(stop, "MaxFunEvals", 11) == 0) break; } if (strncmp(stop, "Manual", 6) == 0) { printf("Press RETURN to start next run\n"); fflush(stdout); getchar(); } } /* for restarts */ return xbestever; /* was dynamically allocated, should be freed in the end */ }
/* the optimization loop */ int main(int argc, char **argv) { cmaes_t evo; /* an CMA-ES type struct or "object" */ double *arFunvals, *xfinal, *const*pop; int i,j; int numberDipoles; int id; //Rank int p; //Number processors double elapsed_time;//Time from beginning. double bestValue; int lambda; int maxLambda; int * sendCnts; //For MPI_Alltoallv for arFunVals int * sdispls; //For MPI_Alltoallv for arFunVals int * recvCnts; //For MPI_Alltoallv for arFunVals int * rdispls; //For MPI_Alltoallv for arFunVals int * sendCntsPop; //For MPI_Alltoallv for pop int * sdisplsPop; //For MPI_Alltoallv for pop int * recvCntsPop; //For MPI_Alltoallv for pop int * rdisplsPop; //For MPI_Alltoallv for pop int canTerminate; int canTerminateBuffer; //Start MPI MPI_Init(&argc, &argv); MPI_Barrier(MPI_COMM_WORLD); elapsed_time = -MPI_Wtime(); //Set initial time. MPI_Comm_rank(MPI_COMM_WORLD, &id); //Set id MPI_Comm_size(MPI_COMM_WORLD, &p); //set p for (i=0;i<32;i++) { observations[i]/=1000.0; } //Set number of dipoles, either first argument or default value of 2. numberDipoles=2; if (argc>=2) { numberDipoles=atoi(argv[1]); } //Set lambda based on entry, default of 40 maxLambda=40; if (argc>=3) { maxLambda=atoi(argv[2]); } if (id==0) { printf("Dipoles:%d MaxLambda:%d\n",numberDipoles,maxLambda); } //Allocate lambda pieces to each processor, based on the size of maxLambda and the number of processors. lambda = BLOCK_SIZE(id,p,maxLambda); printf("Id:%d Lambda:%d\n",id,lambda); //Setup send and receive buffers for function evaluations and populations that resulted in those evaluation. sendCnts = malloc(p*sizeof(int)); sdispls = malloc(p*sizeof(int)); recvCnts = malloc(p*sizeof(int)); rdispls = malloc(p*sizeof(int)); sendCntsPop = malloc(p*sizeof(int)); sdisplsPop = malloc(p*sizeof(int)); recvCntsPop = malloc(p*sizeof(int)); rdisplsPop = malloc(p*sizeof(int)); for (i=0;i<p;i++) { sendCnts[i]=lambda;//Same for all others sdispls[i] = BLOCK_LOW(id,p,maxLambda);//Same for all others recvCnts[i] = BLOCK_SIZE(i,p,maxLambda);//Depends on which we receive from. rdispls[i] = BLOCK_LOW(i,p,maxLambda); sendCntsPop[i]=lambda*((numberDipoles*6+2));//Same for all others sdisplsPop[i] = BLOCK_LOW(id,p,maxLambda)*(numberDipoles*6+2);//Same for all others recvCntsPop[i] = BLOCK_SIZE(i,p,maxLambda)*(numberDipoles*6+2);//Depends on which we receive from. rdisplsPop[i] = BLOCK_LOW(i,p,maxLambda)*(numberDipoles*6+2); } for (i=0;i<p;i++) { printf("Id: %d recvCnts[%d]=%d\n",id,i,recvCnts[i]); printf("Id: %d rdispls[%d]=%d\n",id,i,rdispls[i]); printf("Id: %d recvCntsPop[%d]=%d\n",id,i,recvCntsPop[i]); printf("Id: %d rdisplsPop[%d]=%d\n",id,i,rdisplsPop[i]); } /* Initialize everything into the struct evo, 0 means default */ //arFunvals = cmaes_init(&evo, 0, NULL, NULL, 0, 0, "initials.par"); // printf("0\n"); //The maxLambda parameter has been added so all of them will have enough space to store the results arFunvals = reinit(&evo, maxLambda, numberDipoles); //outputCMAES_t(evo,1); // printf("1\n"); resetSignals(&evo, numberDipoles); /* write header and initial values */ //Reset the seed value based on processor (so they don't all come out the same! evo.sp.seed=evo.sp.seed*(id+1)/p; printf("proc: %d seed: %d\n",id,evo.sp.seed); //outputCMAES_t(evo,0); // printf("2\n"); // printf("%s\n", cmaes_SayHello(&evo)); // i=40; // for (i=32;i<40;i*=2) // { // arFunvals = reinit(&evo, i); //outputCMAES_t(evo); evo.sp.lambda=lambda; canTerminate = (0==1); /* Iterate until stop criterion holds */ while(!canTerminate) { /* generate lambda new search points, sample population */ pop = cmaes_SamplePopulation(&evo); /* do not change content of pop */ /* Here you may resample each solution point pop[i] until it becomes feasible, e.g. for box constraints (variable boundaries). function is_feasible(...) needs to be user-defined. Assumptions: the feasible domain is convex, the optimum is not on (or very close to) the domain boundary, initialX is feasible and initialStandardDeviations are sufficiently small to prevent quasi-infinite looping. */ /*for (i = 0; i < lambda; ++i) { cmaes_ReSampleSingle(&evo, i); }*/ for (i = 0; i < lambda; ++i) { while (!is_feasible(evo.rgrgx[i],(int) cmaes_Get(&evo, "dim"))) { cmaes_ReSampleSingle(&evo, i); } } for (i=0;i<lambda;i++) { for(j=0;j<(6*numberDipoles)+2;j++) { evo.rgrgx[BLOCK_LOW(id,p,maxLambda)+i][j]=evo.rgrgx[i][j]; } } /* evaluate the new search points using fitfun from above */ for (i = BLOCK_LOW(id,p,maxLambda); i <= BLOCK_HIGH(id,p,maxLambda); ++i) { arFunvals[i] = fitfun(evo.rgrgx[i], (int) cmaes_Get(&evo, "dim")); //printf("ID:%d, arFunvals[%d]=%lf\n",id,i,arFunvals[i]); } //Now communicate the arFunvals around MPI_Alltoallv(arFunvals,sendCnts,sdispls,MPI_DOUBLE,arFunvals,recvCnts,rdispls,MPI_DOUBLE,MPI_COMM_WORLD); //Now communicate the populations being looked at around MPI_Alltoallv(&evo.rgrgx[0][0],sendCntsPop,sdisplsPop,MPI_DOUBLE,&evo.rgrgx[0][0],recvCntsPop,rdisplsPop,MPI_DOUBLE,MPI_COMM_WORLD); /* update the search distribution used for cmaes_SampleDistribution() */ cmaes_UpdateDistribution(&evo, arFunvals); //Test for any that can terminate. canTerminate = cmaes_TestForTermination(&evo); if (canTerminate) { printf("id:%d can terminate for reason:%s\n",id,cmaes_TestForTermination(&evo)); } MPI_Allreduce(&canTerminate,&canTerminateBuffer,1,MPI_INT,MPI_MAX,MPI_COMM_WORLD);//Get the max, if any are >0, then someone has terminated. canTerminate = canTerminateBuffer;//Reset so the loop will exit. /* read instructions for printing output or changing termination conditions */ // cmaes_ReadSignals(&evo, "signals.par"); // fflush(stdout); /* useful in MinGW */ } // printf("Stop:\n%s\n", cmaes_TestForTermination(&evo)); /* print termination reason */ // cmaes_WriteToFile(&evo, "all", "allcmaes.dat"); /* write final results */ elapsed_time += MPI_Wtime(); /* get best estimator for the optimum, xmean */ xfinal = cmaes_GetNew(&evo, "xmean"); /* "xbestever" might be used as well */ bestValue = fitfun(xfinal, (int) cmaes_Get(&evo, "dim")); printf("Proccesor:%d has last mean of:%lf elapsedTime:%lf\n",id,bestValue,elapsed_time); for (i=0;i<6*numberDipoles;i++) { printf("(%d:%d:%lf)\n",id,i,xfinal[i]); } // cmaes_exit(&evo); /* release memory */ /* do something with final solution and finally release memory */ free(xfinal); free(sendCnts); free(sdispls); free(recvCnts); free(rdispls); free(sendCntsPop); free(sdisplsPop); free(recvCntsPop); free(rdisplsPop); MPI_Finalize(); //} return 0; }
ReturnFlag CMAES::run_(){ #ifdef OFEC_CONSOLE if (Global::msp_global->m_runId == 0) { mSingleObj::getSingleObj()->setProgrOutputFlag(true); if (mMultiModal::getPopInfor()) mMultiModal::getPopInfor()->setOutProgFlag(true); } #endif // OFEC_CONSOLE cmaes_t evo; /* an CMA-ES type struct or "object" */ double *arFunvals, *const*pop, *xfinal; int i; int numDim = Global::msp_global->mp_problem->getNumDim(); /* Initialize everything into the struct evo, 0 means default */ arFunvals = cmaes_init(&evo, numDim, NULL, NULL, 0, m_pop.size(), initialsFilePathName.c_str());//"cmaes_initials.par" //printf("%s\n", cmaes_SayHello(&evo)); cmaes_ReadSignals(&evo, signalsFilePathName.c_str()); /* "cmaes_signals.par"write header and initial values */ /* Iterate until stop criterion holds */ while (!ifTerminating())/*!cmaes_TestForTermination(&evo)*/ { /* generate lambda new search points, sample population */ pop = cmaes_SamplePopulation(&evo); /* do not change content of pop */ for (i = 0; i < cmaes_Get(&evo, "lambda"); ++i) { copy(pop[i], m_pop[i].data()); } for (i = 0; i < cmaes_Get(&evo, "popsize"); ++i) { /* You may resample the solution i until it lies within the feasible domain here, e.g. until it satisfies given box constraints (variable boundaries). The function is_feasible() needs to be user-defined. Assumptions: the feasible domain is convex, the optimum is not on (or very close to) the domain boundary, initialX is feasible (or in case typicalX +- 2*initialStandardDeviations is feasible) and initialStandardDeviations is (are) sufficiently small to prevent quasi-infinite looping. */ while (!Global::msp_global->mp_problem->isValid(m_pop[i].data())) { cmaes_ReSampleSingle(&evo, i); copy(pop[i], m_pop[i].data()); } } /* evaluate the new search points using fitfun */ for (i = 0; i < cmaes_Get(&evo, "lambda"); ++i) { arFunvals[i] = fitCompute(m_pop[i]); } /* update the search distribution used for cmaes_SamplePopulation() */ cmaes_UpdateDistribution(&evo, arFunvals); /* read instructions for printing output or changing termination conditions */ cmaes_ReadSignals(&evo, signalsFilePathName.c_str());//"cmaes_signals.par" fflush(stdout); /* useful in MinGW */ #ifdef OFEC_CONSOLE if (mMultiModal::getPopInfor()) { int peaksf; peaksf = CAST_PROBLEM_CONT->getGOpt().getNumGOptFound(); mMultiModal::getPopInfor()->input(Global::msp_global.get(), Global::msp_global->mp_problem->getEvaluations(), \ Global::msp_global->m_totalNumIndis, 1, peaksf, \ CAST_PROBLEM_CONT->getGOpt().getNumOpt(), 0, 0, 0, 0, \ 0, 0, CAST_PROBLEM_CONT->getGOpt().isAllFound()); } #endif //cout << cmaes_Get(&evo, "fbestever") <<" "<<Global::msp_global->mp_problem->getEvaluations()<< endl; } //printf("Stop:\n%s\n", cmaes_TestForTermination(&evo)); /* print termination reason */ //cmaes_WriteToFile(&evo, "all", "allcmaes.dat"); /* write final results */ /* get best estimator for the optimum, xmean */ xfinal = cmaes_GetNew(&evo, "xmean"); /* "xbestever" might be used as well */ cmaes_exit(&evo); /* release memory */ /* do something with final solution and finally release memory */ free(xfinal); return Return_Terminate; }
/* the optimization loop */ int main(int argn, char **args) { cmaes_t evo; /* an CMA-ES type struct or "object" */ boundary_transformation_t boundaries; double *arFunvals, *x_in_bounds, *const*pop; double lowerBounds[] = {1.0, DBL_MAX / -1e2}; /* last number is recycled for all remaining coordinates */ double upperBounds[] = {3, 2e22}; int nb_bounds = 1; /* numbers used from lower and upperBounds */ unsigned long dimension; int i; /* initialize boundaries, be sure that initialSigma is smaller than upper minus lower bound */ boundary_transformation_init(&boundaries, lowerBounds, upperBounds, nb_bounds); /* Initialize everything into the struct evo, 0 means default */ arFunvals = cmaes_init(&evo, 0, NULL, NULL, 0, 0, "cmaes_initials.par"); dimension = (unsigned long)cmaes_Get(&evo, "dimension"); printf("%s\n", cmaes_SayHello(&evo)); x_in_bounds = cmaes_NewDouble(dimension); /* calloc another vector */ cmaes_ReadSignals(&evo, "cmaes_signals.par"); /* write header and initial values */ /* Iterate until stop criterion holds */ while(!cmaes_TestForTermination(&evo)) { /* generate lambda new search points, sample population */ pop = cmaes_SamplePopulation(&evo); /* do not change content of pop */ /* transform into bounds and evaluate the new search points */ for (i = 0; i < cmaes_Get(&evo, "lambda"); ++i) { boundary_transformation(&boundaries, pop[i], x_in_bounds, dimension); /* this loop can be omitted if is_feasible is invariably true */ while(!is_feasible(x_in_bounds, dimension)) { /* is_feasible needs to be user-defined, in case, and can change/repair x */ cmaes_ReSampleSingle(&evo, i); boundary_transformation(&boundaries, pop[i], x_in_bounds, dimension); } arFunvals[i] = fitfun(x_in_bounds, dimension); /* evaluate */ } /* update the search distribution used for cmaes_SampleDistribution() */ cmaes_UpdateDistribution(&evo, arFunvals); /* assumes that pop[i] has not been modified */ /* read instructions for printing output or changing termination conditions */ cmaes_ReadSignals(&evo, "cmaes_signals.par"); fflush(stdout); /* useful in MinGW */ } printf("Stop:\n%s\n", cmaes_TestForTermination(&evo)); /* print termination reason */ cmaes_WriteToFile(&evo, "all", "allcmaes.dat"); /* write final results */ /* get best estimator for the optimum, xmean */ boundary_transformation(&boundaries, (double const *) cmaes_GetPtr(&evo, "xmean"), /* "xbestever" might be used as well */ x_in_bounds, dimension); /* do something with final solution x_in_bounds */ /* ... */ /* and finally release memory */ cmaes_exit(&evo); /* release memory */ boundary_transformation_exit(&boundaries); /* release memory */ free(x_in_bounds); return 0; }