void multiDS(int n, double *x, double cc, double ce, double lmin, double lstart, int maxiter) { int i, imin, replaced, iter = 0; double **xs, **xr, **xe, **xc, *fs, *fr, *fe, *fc, fsmin, frmin, femin, fcmin, ssize; FILE *fp; void initSimplex(int, double *, double **, double); void printSimplex(int, int, double **, double *); void findBest(int, double **, double *, int *, double *); void copySimplex(int, double **, double **, double *, double *); double simplexSize(int, double **); void vecAdd(int, double *, double *, double *, double); double dmin(int, double *); void mpi_assign(int); void mpi_distribute(int, double *); /* Initial size of simplex */ ssize = lstart; /* Check validity of input parameters */ if(cc <= 0.0 || cc >= 1.0) { printf("multiDS: contraction coefficient must be in (0,1)\n"); exit(0); } if(ce <= 1.0) { printf("multiDS: expandion coefficient must be > 1\n"); exit(0); } if(ssize < lmin) { printf("multiDS: starting simplex size is < minimum\n"); printf(" give lstart > lmin\n"); exit(0); } printf("Parameters for search:\n"); printf(" Contraction factor = %e\n", cc); printf(" Expansion factor = %e\n", ce); printf(" Starting simplex size = %e\n", ssize); printf(" Minimum simplex size = %e\n", lmin); printf(" Maximum number of iter = %d\n", maxiter); /* Allocate memory */ xs = (double **) calloc((n + 1), sizeof(double *)); xr = (double **) calloc((n + 1), sizeof(double *)); xe = (double **) calloc((n + 1), sizeof(double *)); xc = (double **) calloc((n + 1), sizeof(double *)); fs = (double *) calloc(n + 1, sizeof(double)); fr = (double *) calloc(n + 1, sizeof(double)); fe = (double *) calloc(n + 1, sizeof(double)); fc = (double *) calloc(n + 1, sizeof(double)); for(i = 0; i < n + 1; i++) { xs[i] = (double *) calloc(n, sizeof(double)); xr[i] = (double *) calloc(n, sizeof(double)); xe[i] = (double *) calloc(n, sizeof(double)); xc[i] = (double *) calloc(n, sizeof(double)); } /* Initialize the simplex */ initSimplex(n, x, xs, ssize); /* Assign evaluations to different proc */ mpi_assign(n); /* Calculate initial function values */ /* Zeroth vertex is starting vertex, cost = 1. No need to calculate again * since it is already done in multiDS_driver.c */ fs[0] = cost0; for(i = 1; i < n + 1; i++) { if(proc[i] == myproc) fs[i] = objFun(n, xs[i]); } /* Distribute cost functions */ mpi_distribute(n, fs); printf("Initial simplex and function values:\n"); printSimplex(0, n, xs, fs); /* Find best vertex and put in first position */ findBest(n, xs, fs, &imin, &fsmin); if(myproc == 0) fp = fopen("cost.dat", "w"); /* Main iteration loop */ while(ssize > lmin && iter < maxiter) { printf("Iteration = %d\n\n", iter + 1); replaced = 0; while(!replaced && ssize > lmin) { /* inner repeat loop */ /* rotation step */ printf(" Rotation:\n"); for(i = 1; i <= n; i++) { vecAdd(n, xs[0], xs[i], xr[i], 1.0); if(proc[i] == myproc) fr[i] = objFun(n, xr[i]); } mpi_distribute(n, fr); printSimplex(1, n, xr, fr); frmin = dmin(n, fr); replaced = (frmin < fs[0]) ? 1 : 0; if(replaced) { /* expansion step */ printf(" Expansion:\n"); for(i = 1; i <= n; i++) { vecAdd(n, xs[0], xs[i], xe[i], ce); if(proc[i] == myproc) fe[i] = objFun(n, xe[i]); } mpi_distribute(n, fe); printSimplex(1, n, xe, fe); femin = dmin(n, fe); if(femin < frmin) copySimplex(n, xe, xs, fe, fs); //accept expansion else copySimplex(n, xr, xs, fr, fs); //accept rotation } else { /* contraction step */ printf(" Contraction step:\n"); for(i = 1; i <= n; i++) { vecAdd(n, xs[0], xs[i], xc[i], -cc); if(proc[i] == myproc) fc[i] = objFun(n, xc[i]); } mpi_distribute(n, fc); printSimplex(1, n, xc, fc); fcmin = dmin(n, fc); replaced = (fcmin < fs[0]) ? 1 : 0; copySimplex(n, xc, xs, fc, fs); //accept contraction } /* Length of smallest edge in simplex */ ssize = simplexSize(n, xs); } /* End of inner repeat loop */ ++iter; /* Find best vertex and put in first position */ findBest(n, xs, fs, &imin, &fsmin); printf("\n"); printf("Minimum length of simplex = %12.4e\n", ssize); printf("Minimum function value = %12.4e\n", fs[0]); printf("-------------------------------------------------\n"); if(myproc == 0) { fprintf(fp, "%5d %20.10e %20.10e %5d\n", iter, fs[0], ssize, imin); fflush(fp); } } /* End of main iteration loop */ if(myproc == 0) fclose(fp); /* Copy best vertex for output */ for(i = 0; i < n; i++) x[i] = xs[0][i]; /* Best vertex found */ printf("Best vertex:\n"); for(i = 0; i < n; i++) printf("%e ", x[i]); printf("\n"); /* Free memory */ for(i = 0; i < n + 1; i++) { free(xs[i]); free(xr[i]); free(xe[i]); free(xc[i]); } free(xs); free(xr); free(xe); free(xc); free(fs); free(fr); free(fe); free(fc); }
void useCE(std::string startPolicyFile, std::string piecesFile, unsigned int nbGames, unsigned int nbLearnGames, unsigned int boardWidth, unsigned int boardHeight, int randomSeed, ExperimentOptionType<double> initialSigma, unsigned int maxIterations, unsigned int maxAgents, StoppingCriteria stoppingCriteria, std::ostream & out, std::string outname, shark::CrossEntropy::SamplingNoise noiseType, double noise, ExperimentOptionType<unsigned int> lambda, ExperimentOptionType<unsigned int> offspring ) { out << "Running Cross Entropy with following configurations" << std::endl; out << "Start policy : " << startPolicyFile << std::endl; out << "Pieces : " << piecesFile << std::endl; out << "Game evaluations : " << nbGames << std::endl; out << "Game learning games: " << nbLearnGames << std::endl; out << "Game board with : " << boardWidth << std::endl; out << "Game board height : " << boardHeight << std::endl; out << "Random seed : " << randomSeed << std::endl; if (initialSigma.used()) out << "initialSigma : " << initialSigma() << std::endl; out << "MaxIterations : " << maxIterations << std::endl; initialize_random_generator( randomSeed ); shark::Rng::seed( randomSeed ); shark::CrossEntropy ce; Game *game = new_game(0, 10, 20, 0, piecesFile.c_str(), NULL); GamesStatistics *stats = games_statistics_new(NULL, nbGames, NULL); MDPTetris objFun(10,20, nbGames, game, stats, startPolicyFile); if ( outname.size() > 0 ) { objFun.setGamedataFilename(outname); } ce.init(objFun); ce.lambda() = 100; ce.mu() = 10; ce.setSamplingNoisetype(noiseType); ce.SamplingNoiseTerm() = noise; out << "NoiseType : " << noiseType << std::endl; out << "Noise : " << noise << std::endl; if (initialSigma.used()) { ce.setSigma(initialSigma()); } if(lambda.used()) { ce.lambda() = lambda(); } if(offspring.used()) { ce.mu() = offspring(); } // Still need to set the initial sigma vector int t = 0; int generation = 0; double bestScore = 0.0; bool running = true; /* Report header for CSV output */ if ( outname.size() > 0 ) { /* Write the header */ std::ofstream fs; fs.open (outname.c_str()); fs << "generation,agents,minScore,maxScore,meanScore,standardDeviation,"; for (int i = 0; i < objFun.numberOfVariables()-1; i++) { fs << "w" << i << ","; } fs << "w" << objFun.numberOfVariables()-1 << std::endl; fs.close(); } while (running) { _DUMP(generation); ce.step(objFun); t += ce.lambda() * nbGames; if ( outname.size() > 0 ) { /* Set the number of games for the learning curve */ objFun.setNbGames(nbLearnGames); MDPTetris::MDPTetrisDetailedResult report = objFun.evalDetailed(ce.mean()); objFun.setNbGames(nbGames); std::ofstream fs; fs.open (outname.c_str(), std::ios::app); fs << generation << "," << t << "," << report.minScore() << "," << report.maxScore() << "," << report.mean() << "," << report.standardDeviation() << "," << report.printWeights(",") << std::endl; } if (TETRIS_MAX_SCORE - ce.solution().value > bestScore) { bestScore = TETRIS_MAX_SCORE - ce.solution().value; shark::RealVector solution = ce.solution().point; _DUMP(bestScore); _DUMP(t); _DUMP(solution); } generation++; if (stoppingCriteria == STOP_BY_ITERATION && generation > maxIterations) { running = false; } else if (stoppingCriteria == STOP_BY_AGENTS_EVALUATED && t > maxAgents) { running = false; } } }