// generate batch of N samples from a target distribution p(x) // using sampling-importance-rejection sampling w/ one resampling stage Matrix rvSIRBatch(const int& N, const double& PDFscale) { int j=0, k=0, m=0; Matrix Qsamples(1,N); Matrix w(1,N); Matrix wCDF(1,N); Matrix rand(1,N); Matrix x(1,N); // sample from q(x) and calculate weights (and create random array for later) for(int i=0;i<N;i++) { Qsamples[0][i] = rvStdUniform(-1,1)*PDFscale; // [-1,1] to handle all PDFs //w[0][i] = p_x(Qsamples[0][i])/Qsamples[0][i]; // line below works, line above doesn't; w[0][i] = p_x(Qsamples[0][i])/PDFscale; rand[0][i] = rvStdUniform(0,1); } // normalize weights w = w/w.sum(); // create CDF of weights wCDF[0][0] = w[0][0]; for(int j=1;j<N;j++) wCDF[0][j] = wCDF[0][j-1] + w[0][j]; //make copies as many times as numbers occur in CDF for(k = 0; k < N; ++k) { m = 0; while(wCDF[0][m] < rand[0][k]) { ++m; } x[0][k] = Qsamples[0][m]; } // reset weights to uniform values double wUniform = 1./N; w.fill(wUniform); return x; }
// generate one sample from a target distribution p(x) using rejection sampling double rvRejectionSample(const double& M, const double& PDFscale) { double x, u, target, rejectRatio; // note: PDFscale scales the related density g(x) to ensure // it's larger than the distribution we want to sample; // otherwise we'll just end up sampling g(x) // note: machine learning book says to use u < p(x)/Mg(x) // as the acceptance criteria, but actually uses u < p(x) // also, book says to sample from g(x) Gaussian (for Gaussian desired density) // but actually uses uniform density // the following code is "correct" but doesn't seem // to match desired density as well as book's method // to use book's method, comment out all *^ lines // and comment in all ** lines // generate initial sample x = rvGaussian(0,1)*PDFscale; // related density, here Gaussian // can also just choose a constant value // larger than the max of the target distribution // *^ //x = rvStdUniform(0,1)*PDFscale; // ** u = rvStdUniform(0,1)*M; // enveloping uniform distribution //rejectRatio = p_x(x)/u; // threshold to accept/reject samples *^ // generate sample x until it falls within the target distribution //while( u >= rejectRatio) // *^ while( u >= p_x(x) ) // ** { x = rvGaussian(0,1)*PDFscale; // *^ //x = rvStdUniform(0,1)*PDFscale; // ** u = rvStdUniform(0,1)*M; //rejectRatio = p_x(x)/u; // *^ } return x; }
void GeneticAlgorithm::Crossover(std::vector<char***> &population, float probability, float infeasibilitiesWeight, float didacticDissatisfactionWeight, float organizationalDissatisfactionWeight) { int num_pairs = population.size() / 2; int size = population.size(); std::vector<bool> free_pairs(size, true); // Losowanie par. for(int i = 0; i < num_pairs; ++i) { int x = rand() % size; int y = rand() % size; while(!free_pairs[x]) { x++; if(x == size) x = 0; } free_pairs[x] = false; while(!free_pairs[y]) { y++; if(y == size) y = 0; } free_pairs[y] = false; // Krzy¿uj. if(rand() % 100 < probability * 100) { std::vector<std::pair<int, float>> x_fitness; for(int teacher = 0; teacher < teachers_count; ++teacher) { float xf = CalculateLocalFitnessFunction(population.data(), x, teacher, didacticDissatisfactionWeight, organizationalDissatisfactionWeight); std::pair<int, float> p_x(teacher, xf); x_fitness.push_back(p_x); } std::sort(x_fitness.begin(), x_fitness.end(), [] (std::pair<int, float> &_x, std::pair<int, float> &_y) -> bool { return _x.second < _y.second; } ); int k = teachers_count / 2; // TODO: wybieraæ k na podstawie œredniej. char ***timetable1 = new char**[teachers_count]; char ***timetable2 = new char**[teachers_count]; for(int t = 0; t < teachers_count; ++t) { if(t < k) { timetable1[x_fitness[t].first] = population[x][x_fitness[t].first]; timetable2[x_fitness[t].first] = population[y][x_fitness[t].first]; } else { timetable1[x_fitness[t].first] = population[y][x_fitness[t].first]; timetable2[x_fitness[t].first] = population[x][x_fitness[t].first]; } } delete [] population[x]; delete [] population[y]; population[x] = timetable1; population[y] = timetable2; } } }