mamamaria

Untitled

Apr 19th, 2022 (edited)
483
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.35 KB | None | 0 0
  1. // TSP GA.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
  2. //
  3. #include <iostream>
  4. #include <vector>
  5. #include <fstream>
  6. #include <ctime>
  7. #include <random>
  8. #include <chrono>
  9. #include <string>
  10.  
  11. using namespace std;
  12. using namespace chrono;
  13. string mainstr = "C:\\Users\\asus\\Desktop\\petya\\Coursework\\Coursework\\graphs\\";
  14. default_random_engine eng(time(0));
  15. int N;
  16. using Graph = vector<vector<double>>;
  17. using Way = vector<int>; // они же геномы
  18. struct Creature //особь
  19. {
  20.     Way way;
  21.     double fitness;
  22.     Creature() : way(N - 1, 0), fitness(0) {}
  23. };
  24. using Generation = vector <Creature>; //поколение
  25.  
  26. //допустим что все пути по умолчанию начинаются в 0 и заканчиваются в 0
  27. Graph GraphGenerator() {
  28.     Graph graph(N);
  29.     for (int i = 0; i < N; i++) {
  30.         graph[i].resize(N);
  31.     }
  32.     uniform_real_distribution<double> distr(1, 10);
  33.     for (int i = 0; i < N; i++) {
  34.         for (int j = 0; j <= i; j++) {
  35.             if (i == j) {
  36.                 graph[i][j] = INFINITY;
  37.                 continue;
  38.             }
  39.             graph[i][j] = distr(eng);
  40.             graph[j][i] = distr(eng);
  41.         }
  42.     }
  43.     return graph;
  44. }
  45.  
  46.  
  47. void WayShuffling(Creature& creature) {
  48.     for (int i = 0; i < creature.way.size(); i++) {
  49.         creature.way[i] = i + 1;
  50.     }
  51.     shuffle(creature.way.begin(), creature.way.end(), eng);
  52.  
  53. }
  54. Generation GenerationGenerator(int creaturesnumber) {
  55.     Generation generation;
  56.     for (int i = 0; i < creaturesnumber; i++) {
  57.         Creature creature;
  58.         WayShuffling(creature);
  59.         generation.push_back(creature);
  60.     }
  61.     return generation;
  62. }
  63. void Fitness(Creature& creature, const Graph& graph) {
  64.     double waylong = 0;
  65.     for (int i = 0; i < creature.way.size() - 1; i++) {
  66.         waylong += graph[creature.way[i]][creature.way[i + 1]];
  67.     }
  68.     waylong += graph[0][creature.way[0]] + graph[creature.way.back()][0];
  69.     creature.fitness = 1 / waylong;
  70.  
  71. }
  72.  
  73. bool CreaturesComparing(const Creature& creature1, const Creature& creature2) { return (creature1.fitness > creature2.fitness); }
  74.  
  75. void FitnessSort(Generation& generation) {
  76.     sort(generation.begin(), generation.end(), CreaturesComparing);
  77. }
  78.  
  79. Creature TournamentSelection(const Generation& generation, int creaturesnumber) {
  80.     int num, maxindex; double max = 0;
  81.     uniform_int_distribution<int> distr(0, creaturesnumber - 1);
  82.     for (int i = 0; i < 0.1 * creaturesnumber; i++) {
  83.         num = distr(eng);
  84.         if (generation[num].fitness > max) {
  85.             max = generation[num].fitness;
  86.             maxindex = num;
  87.         }
  88.     }
  89.     return generation[maxindex];
  90. }
  91.  
  92. Creature KidMaker(const Creature& parent1, const Creature& parent2, int startInd, int endInd) {
  93.     Creature kid;
  94.     vector<bool>visited(N - 1, 0);
  95.     for (int i = startInd; i <= endInd; i++)
  96.     {
  97.         kid.way[i] = parent1.way[i];
  98.         visited[parent1.way[i] - 1] = true;
  99.     }
  100.     int j = 0;
  101.     for (int i = 0; i < N - 1; ) {
  102.         if (!visited[parent2.way[i] - 1] && kid.way[j] == 0) {
  103.             kid.way[j] = parent2.way[i];
  104.             i++;
  105.             j++;
  106.         }
  107.         else if (visited[parent2.way[i] - 1])
  108.             i++;
  109.         else if (kid.way[j] != 0)
  110.             j++;
  111.     }
  112.  
  113.     return kid;
  114. }
  115.  
  116. void KidsMaker(const Creature& parent1, const Creature& parent2, Generation& generation) {
  117.     uniform_int_distribution<int> distr(0, N - 2); //n-1
  118.  
  119.     int startInd = distr(eng);  int endInd = distr(eng);
  120.     if (startInd > endInd) swap(startInd, endInd);
  121.  
  122.     Creature kid1 = KidMaker(parent1, parent2, startInd, endInd);
  123.     Creature kid2 = KidMaker(parent2, parent1, startInd, endInd);
  124.     generation.push_back(kid1);
  125.     generation.push_back(kid2);
  126. }
  127.  
  128. void Mutation(Creature& creature, double mutation) {
  129.     random_device rd;
  130.     mt19937 gen(rd());
  131.     bernoulli_distribution d(mutation);
  132.     uniform_int_distribution<int> distr(0, N - 2); //N-2
  133.  
  134.     if (d(gen)) {
  135.         int startInd = distr(eng);  int endInd = distr(eng);
  136.         swap(creature.way[startInd], creature.way[endInd]);
  137.     }
  138. }
  139. Creature ShowMeYourBest(const Generation& generation) {
  140.     int maxindex; double max = 0;
  141.     for (int i = 0; i < generation.size(); i++) {
  142.         if (generation[i].fitness > max) {
  143.             max = generation[i].fitness;
  144.             maxindex = i;
  145.         }
  146.     }
  147.     return generation[maxindex];
  148. }
  149.  
  150. double Waylong(const Creature& creature, const Graph& graph) {
  151.     double waylong = 0;
  152.     for (int i = 0; i < creature.way.size() - 1; i++) {
  153.         waylong += graph[creature.way[i]][creature.way[i + 1]];
  154.     }
  155.     waylong += graph[0][creature.way[0]] + graph[creature.way.back()][0];
  156.     return waylong;
  157. }
  158. void GraphReader(Graph& graph, int& N, const string strr) {
  159.     ifstream gin(strr);
  160.     gin >> N;
  161.     graph.resize(N);
  162.     for (int i = 0; i < N; i++) {
  163.         graph[i].resize(N);
  164.     }
  165.     double dub;
  166.     for (int i = 0; i < N; i++) {
  167.         for (int j = 0; j < N; j++) {
  168.             gin >> graph[i][j];
  169.         }
  170.     }
  171.     gin.close();
  172. }
  173. int main()
  174. {
  175.     ofstream filetime("TSPGA_time-N.txt");
  176.     ofstream filelongway("TSPGA_longway-N.txt");
  177.     double mutation = 0.1;
  178.     const int creaturesnumber = 100;
  179.     //Graph graph = GraphGenerator();
  180.     for (int NUMBER = 5; NUMBER <= 100; NUMBER += 5) {
  181.         double averagelong = 0;
  182.         double averagetime = 0;
  183.         for (int graphforN = 0; graphforN < 20; graphforN++) {
  184.             auto GAstart = high_resolution_clock::now();
  185.             //cout << "\nGraph " << graphforN + 1 << " for N " << NUMBER << endl;
  186.             string strr = mainstr + to_string(NUMBER) + "_" + to_string(graphforN) + ".txt";
  187.             int count = 0;
  188.             Graph graph; GraphReader(graph, N, strr);
  189.             Generation generation = GenerationGenerator(creaturesnumber);
  190.             Creature bestofthebest = generation[0];
  191.             double waylongbestofthebest = Waylong(bestofthebest, graph);
  192.             while (count <= 100) {
  193.                 for (int i = 0; i < generation.size(); i++)
  194.                     Fitness(generation[i], graph);
  195.  
  196.                 Creature ruthebest = ShowMeYourBest(generation);
  197.                 double waylongruthebest = Waylong(ruthebest, graph);
  198.                
  199.                 if (waylongruthebest > waylongbestofthebest) {
  200.                     bestofthebest = ruthebest;
  201.                     waylongbestofthebest = waylongruthebest;
  202.                     cout << " GRAPHSIZE: " << NUMBER << " GRAPHNUMBER: " << graphforN << " GENERATIONNUMBER: " << count << endl;
  203.                     cout << "best waylong in generation: " << waylongbestofthebest << endl;
  204.                     for (int i = 0; i < ruthebest.way.size(); i++) {
  205.                         cout << ruthebest.way[i] << "   ";
  206.                     }
  207.                     cout << endl << endl;
  208.                 }
  209.  
  210.                 Creature parent1 = TournamentSelection(generation, creaturesnumber);
  211.                 Creature parent2 = TournamentSelection(generation, creaturesnumber);
  212.  
  213.                 Generation newGeneration;
  214.                 while (newGeneration.size() < creaturesnumber) {
  215.                     KidsMaker(parent1, parent2, newGeneration);
  216.                 }
  217.  
  218.                 for (int i = 0; i < newGeneration.size(); i++)
  219.                     Mutation(newGeneration[i], mutation);
  220.  
  221.                 generation = newGeneration;
  222.                 count++;
  223.  
  224.             }
  225.             auto GAfinish = high_resolution_clock::now();
  226.  
  227.             averagelong += waylongbestofthebest;
  228.             averagetime += duration_cast<milliseconds>(GAfinish - GAstart).count();
  229.         }
  230.         filelongway << "N: " << NUMBER << " waylong: " << averagelong / 20 << endl;
  231.         filetime << "N: " << NUMBER << " timelong: " << averagetime / 20 << endl;
  232.     }
  233.     filetime.close();
  234.     filelongway.close();
  235.  
  236.  
  237.  
  238. }
  239.  
  240. // Запуск программы: CTRL+F5 или меню "Отладка" > "Запуск без отладки"
  241. // Отладка программы: F5 или меню "Отладка" > "Запустить отладку"
  242.  
  243. // Советы по началу работы
  244. //   1. В окне обозревателя решений можно добавлять файлы и управлять ими.
  245. //   2. В окне Team Explorer можно подключиться к системе управления версиями.
  246. //   3. В окне "Выходные данные" можно просматривать выходные данные сборки и другие сообщения.
  247. //   4. В окне "Список ошибок" можно просматривать ошибки.
  248. //   5. Последовательно выберите пункты меню "Проект" > "Добавить новый элемент", чтобы создать файлы кода, или "Проект" > "Добавить существующий элемент", чтобы добавить в проект существующие файлы кода.
  249. //   6. Чтобы снова открыть этот проект позже, выберите пункты меню "Файл" > "Открыть" > "Проект" и выберите SLN-файл.
Add Comment
Please, Sign In to add comment