mamamaria

GA

May 15th, 2021 (edited)
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.89 KB | None | 0 0
  1. // GA.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
  2. //
  3.  
  4. #include <iostream>
  5. #include <random>
  6. #include <vector>
  7. #include <ctime>
  8. #include <cmath>
  9. using namespace std;
  10.  
  11. using Genome = vector<bool>; //геном
  12. std::default_random_engine generator(time(0));
  13.  
  14. int nGenome = 10; //первые 4 бита - под целое число, 6 битов под дробную часть
  15. //чтобы закодировать числа [1, 10], достаточно 4-х бит
  16. int nPoplulation = 100;
  17.  
  18.  
  19. double f(double x) { //вычисляемая функция
  20.     if (x < 1 || x>10) return 0;
  21.     return 3 * x * x * x - 2 * x + 5;
  22. }
  23.  
  24.  
  25. Genome DecimalToBinary(Genome genome, int num) {
  26.     int i = 0;
  27.     while (num != 1) {
  28.         genome[i]=(num % 2);
  29.         num /= 2;
  30.         i++;
  31.     }
  32.     genome[i] = 1;
  33.     return genome;
  34. }
  35.  
  36. double BinaryToDecimal(Genome genome) {
  37.     double num=0;
  38.     for (int i = 0; i < genome.size(); i++) {
  39.         num += genome[i] * pow(2, i);
  40.     }
  41.     num /= pow(2, 6);
  42.     return num;
  43. }
  44.  
  45. Genome Shotgun(Genome genome) { //стратегия "дробовика"  
  46.     for (int i = 0; i < genome.size(); i++)
  47.         genome[i] = rand() % 2;
  48.     return genome;
  49. }
  50. Genome Focus(Genome genome, double x1, double x2) { //стратегия фокусировки
  51.     std::default_random_engine generator (time(0));
  52.     std::uniform_real_distribution<double> distributionDouble(x1, x2);
  53.     double num = distributionDouble(generator);
  54.     num *= pow(2, 6);
  55.     num = round(num);
  56.     genome = DecimalToBinary(genome, num);
  57.     return genome;
  58. }
  59.  
  60. void CreateStartPopulation(vector<Genome>& population, int choice) { //создание начальной популяции
  61.    
  62.     switch (choice) {
  63.     case 1: {
  64.         for (int i = 0; i < population.size(); i++) {
  65.             Genome genome(nGenome, 0);
  66.             population[i] = Shotgun(genome);
  67.         }
  68.         break;
  69.     }
  70.     case 2: {
  71.         int x1; int x2;
  72.         cout << "\nInput the range (from/to)\n";
  73.         cin >> x1; cin >> x2;
  74.         for (int i = 0; i < population.size(); i++) {
  75.             Genome genome(nGenome, 0);
  76.             population[i] = Focus(genome, x1, x2);
  77.         }
  78.         break;
  79.     }
  80.     default:
  81.         break;
  82.     }
  83. }
  84.  
  85. pair<int, int> IndexGeneration(vector<double>& ProbabilisticSeries) { //ищет подходящие индексы в массиве частичных сумм
  86.     pair<int, int> PairIndexes; double index1, index2;
  87.  
  88.    
  89.     std::uniform_real_distribution<double> distributionDouble(0, 1);
  90.  
  91.     index1 = distributionDouble(generator);
  92.     for (int i = 0; i < nPoplulation; i++)
  93.         if (index1 < ProbabilisticSeries[i]) {
  94.             index1 = i;
  95.             break;
  96.     }
  97.  
  98.     index2 = distributionDouble(generator);
  99.     for (int i = 0; i < nPoplulation; i++)
  100.         if (index2 < ProbabilisticSeries[i]) {
  101.             index2 = i;
  102.             break;
  103.         }
  104.  
  105.     PairIndexes.first = index1;
  106.     PairIndexes.second = index2;
  107.  
  108.     return PairIndexes;
  109. }
  110. vector<pair<int, int>> RandomSelection(vector<Genome> population) {
  111.     double sumF = 0;
  112.     vector<double>GenomeDecimalValue;
  113.  
  114.     for (int i = 0; i < nPoplulation; i++) {
  115.         GenomeDecimalValue.push_back(f(BinaryToDecimal(population[i]))); //перевод каждого генома в десятичное число
  116.         // и взятие ЦФ от полученного десятичного числа
  117.         sumF += GenomeDecimalValue.back(); //сумма всех значений ЦФ
  118.     }
  119.  
  120.     for (int i = 0; i < nPoplulation; i++)
  121.         GenomeDecimalValue[i] = GenomeDecimalValue[i] / sumF; //доля каждого генома в общей массе
  122.  
  123.     vector<double>ProbabilisticSeries; // массив с частичными суммами
  124.  
  125.     for (int i = 0; i < nPoplulation; i++) {
  126.         sumF = 0;
  127.         for (int j = 0; j <= i; j++)
  128.             sumF += GenomeDecimalValue[j];
  129.         ProbabilisticSeries.push_back(sumF);
  130.        
  131.     }
  132.     vector<pair<int, int>> PairsIndexes;
  133.     for (int i = 0; i < nPoplulation; i++) {
  134.         PairsIndexes.emplace_back(IndexGeneration(ProbabilisticSeries));
  135.     }
  136.        
  137.     return PairsIndexes;
  138.  
  139. }
  140.  
  141. pair<Genome,Genome> SinglePointCrossover(Genome mama, Genome papa) {
  142.     int point = rand() % (nGenome-1) + 1;
  143.    
  144.     Genome daughter; Genome son;
  145.     daughter = mama;
  146.     son = papa;
  147.     for (int i = point; i < nGenome; i++) swap(daughter[i], son[i]);
  148.     pair<Genome, Genome> kids;
  149.     kids.first = daughter; kids.second = son;
  150.     return kids;
  151. }
  152.  
  153. pair<Genome, Genome> TwoPointCrossover(Genome mama, Genome papa) {
  154.     int point1, point2;
  155.     point1 = rand() % (nGenome - 1) + 1;
  156.     point2 = rand() % (nGenome - 1) + 1;
  157.     while(point1==point2) point2 = rand() % (nGenome - 1) + 1;
  158.     if (point1 > point2) swap(point1, point2);
  159.     Genome daughter; Genome son;
  160.     daughter = mama;
  161.     son = papa;
  162.     for (int i = point1; i < point2; i++)
  163.         swap(daughter[i], son[i]);
  164.    
  165.     pair<Genome, Genome> kids;
  166.     kids.first = daughter; kids.second = son;
  167.     return kids;
  168. }
  169.  
  170. vector<Genome> Offsprings(vector<pair<int, int>> RandomSelection, vector<Genome>& population) {
  171.     int choice;
  172.     cin >> choice;
  173.     vector<Genome> offsprings; pair<Genome, Genome> kids;
  174.     switch (choice) {
  175.     case 1: {
  176.         for (int i = 0; i < population.size(); i++) {
  177.             kids = SinglePointCrossover(population[RandomSelection[i].first], population[RandomSelection[i].second]);
  178.             offsprings.push_back(kids.first);
  179.             offsprings.push_back(kids.second);
  180.         }
  181.     }
  182.     case 2: {
  183.         for (int i = 0; i < population.size(); i++) {
  184.             kids = TwoPointCrossover(population[RandomSelection[i].first], population[RandomSelection[i].second]);
  185.             offsprings.push_back(kids.first);
  186.             offsprings.push_back(kids.second);
  187.         }
  188.  
  189.     }
  190.     }
  191.     return offsprings;
  192. }
  193. void OutputGenome(Genome genome) {
  194.     for (int i = 0; i < nGenome; i++)
  195.         cout << genome[i];
  196.     cout << endl;
  197. }
  198. int main()
  199. {
  200.     vector<Genome> population (nPoplulation);    
  201.     srand(time(0));
  202.  
  203.     CreateStartPopulation(population, 1);
  204.     vector<pair<int, int>> temp = RandomSelection(population);
  205.     for (int i = 0; i < nPoplulation; i++)
  206.     {
  207.         cout << temp[i].first << "\t" << temp[i].second << "\n";
  208.         OutputGenome(population[temp[i].first]);
  209.         cout << endl;
  210.         OutputGenome(population[temp[i].second]);
  211.         cout << endl;
  212.     }
  213.     cout << endl;
  214.     vector<Genome> offsprings(2 * nPoplulation);
  215.     offsprings = Offsprings(temp, population);
  216.  
  217.     for (int i = 0; i < 2 * nPoplulation; i++)
  218.     {
  219.         cout << i << ": ";
  220.         OutputGenome(offsprings[i]);
  221.     }
  222.  
  223. }
  224.  
  225.  
Add Comment
Please, Sign In to add comment