Advertisement
Guest User

GA_TASK3

a guest
Dec 13th, 2019
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.65 KB | None | 0 0
  1. #include <iostream>
  2. #include <bitset>
  3. #include <vector>
  4. #include <fstream>
  5. #include <math.h>
  6. #include <intrin.h>
  7. #include <random>
  8.  
  9.  
  10. std::ofstream fout("data.out");
  11. std::ifstream fin("data.in");
  12.  
  13. std::default_random_engine gen01;
  14. std::uniform_real_distribution<double> rand01(0.0, 1.0);
  15.  
  16. std::default_random_engine gen05;
  17. std::uniform_real_distribution<double> rand05(0.0, 0.5);
  18.  
  19. unsigned int graphDistances[2000][2000];
  20. unsigned int cityCount;
  21. int popSize = 100;
  22.  
  23. struct Tour
  24. {
  25.     std::bitset<10000> bits;
  26.     std::vector<unsigned int> values; //vectors are assigned at element creation in order to not repeat memory assignment at every modification
  27.     std::vector<unsigned int> orderedValues; //same as above
  28.     std::vector<unsigned int> tourOrder; //same as above
  29.     unsigned int cityLen; //amount of bits assigned per city; value should always be ceil(log2(cityCount))
  30.     unsigned int cityCount;
  31.     unsigned int tourDistance;
  32.     bool modified; //false if the tourOrder and tourDistance correspond to the current bitset; should be turned to true every time the bitset is modified (for example, at mutation)
  33.     double pcx;
  34.     double fitness;
  35.  
  36.  
  37.     Tour(int cityNumber) //constructor; count is the number of cities
  38.     {
  39.         cityCount = cityNumber;
  40.         cityLen = (int)ceil(log2(cityCount));
  41.         tourDistance = 0;
  42.         for (int i = 0; i < cityCount; i++)
  43.             values.push_back(-1), orderedValues.push_back(-1), tourOrder.push_back(-1);
  44.         modified = false;
  45.  
  46.         randomize();
  47.         calculateValues();
  48.         calculatePath();
  49.         calculateDistance();
  50.  
  51.         pcx = rand01(gen01);
  52.     }
  53.  
  54.     Tour(const Tour& t2) //copy contructor
  55.     {
  56.         cityCount = t2.cityCount;
  57.         cityLen = t2.cityLen;
  58.         bits = t2.bits;
  59.         fitness = t2.fitness;
  60.         for (int i = 0; i < cityCount; i++)
  61.             values.push_back(t2.values[i]), orderedValues.push_back(t2.orderedValues[i]), tourOrder.push_back(t2.tourOrder[i]);
  62.  
  63.         tourDistance = t2.tourDistance;
  64.         modified = t2.modified; //ideally, this should ALWAYS be false 
  65.         pcx = rand01(gen01);
  66.     }
  67.  
  68.     void randomize()
  69.     {
  70.         for (int i = 0; i < 10000; i++)
  71.             bits[i] = rand() % 2;
  72.     }
  73.  
  74.     void generatePCX()
  75.     {
  76.         pcx = rand01(gen01);
  77.     }
  78.  
  79.     void showBits()
  80.     {
  81.         for (int i = 0; i < cityCount; i++)
  82.         {
  83.             for (int j = 0; j < cityLen; j++)
  84.                 fout << bits[i * cityLen + j];
  85.             fout << " ";
  86.         }
  87.  
  88.         fout << std::endl;
  89.     }
  90.  
  91.     void showPath()
  92.     {
  93.         for (int i = 0; i < cityCount; i++)
  94.             fout << tourOrder[i] << " ";
  95.         fout << std::endl;
  96.     }
  97.  
  98.     void recalculate()
  99.     {
  100.         calculateValues();
  101.         calculatePath();
  102.         calculateDistance();
  103.         modified = false;
  104.     }
  105.  
  106.     void calculateValues()
  107.     {
  108.         int p2, tValue;
  109.  
  110.         for (int i = 0; i < cityCount; i++)
  111.         {
  112.             p2 = (int)pow(2, cityLen - 1);
  113.             tValue = 0;
  114.             for (int j = 0; j < cityLen; j++)
  115.             {
  116.                 tValue += p2 * bits[i * cityLen + j];
  117.                 p2 /= 2;
  118.             }
  119.             values[i] = tValue;
  120.             orderedValues[i] = tValue;
  121.         }
  122.  
  123.         std::sort(orderedValues.begin(), orderedValues.end());
  124.     }
  125.  
  126.     void calculatePath()
  127.     {
  128.         for (int i = 0; i < cityCount; i++)
  129.             for (int j = 0; j < cityCount; j++)
  130.                 if (values[i] == orderedValues[j])
  131.                 {
  132.                     tourOrder[i] = j;
  133.                     orderedValues[j] = -1;
  134.                     j = cityCount + 1;
  135.                 }
  136.  
  137.         //for (int i = 1; i < cityCount; i++)
  138.             //tourDistance += graphDistances[tourOrder[i - 1]][tourOrder[i]]; //NOTE: MIGHT CHANGE ONCE I LEARN HOW TO USE TSPLIB
  139.     }
  140.  
  141.     void calculateDistance()
  142.     {
  143.         tourDistance = 0;
  144.         for (int i = 1; i < cityCount; i++)
  145.             tourDistance += graphDistances[tourOrder[i - 1]][tourOrder[i]];
  146.     }
  147.  
  148.     void mutate(double pm)
  149.     {
  150.        
  151.         for (int i = 0; i < cityCount * cityLen; i++)
  152.             if (rand01(gen01) < pm) {
  153.                 bits[i] = !bits[i];
  154.                 modified = true;
  155.             }
  156.     }
  157. };
  158.  
  159. //std::vector<Tour*> pop;
  160.  
  161. void showEntirePopulation(std::vector<Tour> population)
  162. {
  163.     for (unsigned int i = 0; i < population.size(); i++)
  164.     {
  165.         //population[i].showBits();
  166.         population[i].showPath();
  167.         fout << population[i].tourDistance << " " << population[i].fitness << "\n";
  168.     }
  169. }
  170.  
  171. void readGraph()
  172. {
  173.     fin >> cityCount;
  174.     for (int i = 0; i < cityCount; i++)
  175.         for (int j = 0; j < cityCount; j++)
  176.             fin >> graphDistances[i][j];
  177. }
  178.  
  179.  
  180. void mutation(double pm, std::vector<Tour>& pop)
  181. {
  182.     for (int i = 0; i < pop.size(); i++) {
  183.         pop[i].mutate(pm);
  184.     }
  185. }
  186.  
  187. bool cmp(const Tour& t1, const Tour& t2) {
  188.     return (t1.pcx < t2.pcx);
  189. }
  190.  
  191. void crossover(double pcx, std::vector<Tour>& pop) {
  192.  
  193.     std::sort(pop.begin(), pop.end(), cmp);
  194.  
  195.     const int L = pop[0].cityLen * pop[0].cityCount;
  196.  
  197.     std::default_random_engine genint;
  198.     std::uniform_int_distribution<int> randint(1, L - 2);
  199.  
  200.     for (int i = 0; i < pop.size(); i++)
  201.     {
  202.         pop[i].generatePCX();
  203.     }
  204.  
  205.     int i;
  206.     for (i = 0; i < pop.size() - 1; i += 2) {
  207.         if (pop[i + 1].pcx < pcx && pop[i].pcx < pcx) {
  208.  
  209.            
  210.             int pos = randint(genint);
  211.             //fout << "pos=" << pos << '\n';
  212.             Tour c1(pop[i]);
  213.             Tour c2(pop[i + 1]);
  214.  
  215.             for (int j = pos; j < L - 1; j++) {
  216.                 c1.bits[j] = pop[i + 1].bits[j];
  217.                 c2.bits[j] = pop[i].bits[j];
  218.             }
  219.             pop.push_back(c1);
  220.             pop.push_back(c2);
  221.         }
  222.         else break;
  223.     }
  224.    
  225.     double newpcx = rand05(gen05);
  226.     if (pop[i].pcx < pcx && newpcx < pcx) {
  227.         int pos = randint(genint);
  228.         //fout << "pos=" << pos << '\n';
  229.         Tour c1(pop[i]);
  230.         Tour c2(pop[i + 1]);
  231.  
  232.         for (int j = pos; j < L - 1; j++) {
  233.             c1.bits[j] = pop[i + 1].bits[j];
  234.             c2.bits[j] = pop[i].bits[j];
  235.         }
  236.         pop.push_back(c1);
  237.         pop.push_back(c2);
  238.     }
  239. }
  240.  
  241. double divFit(Tour* tour)
  242. {
  243.     return (1 / (tour->tourDistance + 0));
  244. }
  245.  
  246. std::vector<Tour> selection(std::vector<Tour>& population, double(*fitnessF)(Tour* tour), int eliteCount)
  247. {
  248.     std::vector<Tour> newPopulation;
  249.     std::vector<double> sectorFitness;
  250.  
  251.     int populationSize = population.size();
  252.  
  253.     for (int i = 0; i < populationSize; i++)
  254.     {
  255.         population[i].fitness = fitnessF(&population[i]);
  256.     }
  257.  
  258.     std::sort(population.begin(), population.end(), [](Tour t1, Tour t2) {return t1.fitness > t2.fitness; });
  259.  
  260.     sectorFitness.push_back(population[0].fitness);
  261.     for (int i = 1; i < populationSize; i++)
  262.         sectorFitness.push_back(sectorFitness[i - 1] + population[i].fitness);
  263.  
  264.     /*
  265.     for (int i = 0; i < sectorFitness.size(); i++)
  266.     {
  267.         std::cout << i << " " << sectorFitness[i] << " ";
  268.     }
  269.     */
  270.     for (int i = 0; i < eliteCount; i++)
  271.         newPopulation.push_back(population[i]); //Elitism keeps the first eliteCount individuals unchanged
  272.  
  273.     for (int i = 0; i < popSize - eliteCount; i++)
  274.     {
  275.         double prob = rand01(gen01) * sectorFitness[sectorFitness.size() - 1];
  276.         for (int j = 0; j < populationSize; j++)
  277.         {
  278.             if (prob <= sectorFitness[j])
  279.             {
  280.                 newPopulation.push_back(population[j]);
  281.                 j = populationSize + 1; //organic break
  282.             }
  283.         }
  284.     }
  285.  
  286.     return newPopulation;
  287. }
  288.  
  289.  
  290. int main() {
  291.  
  292.     srand(__rdtsc());
  293.    
  294.     //double pm = 0.1;
  295.     //double pcx = 0.3;
  296.  
  297.     std::vector<Tour> pop;
  298.    
  299.     readGraph();
  300.  
  301.     for (int i = 0; i < popSize; i++)
  302.     {
  303.         Tour newtour(cityCount);
  304.         pop.push_back(newtour);
  305.     }
  306.  
  307.     int g = 0;
  308.     int shortest = 100000000;
  309.     int shortestIndex = 0;
  310.  
  311.     while (g < 5)
  312.     {
  313.  
  314.         std::cout << "GENERATION "<< g <<std::endl;
  315.         pop = selection(pop, divFit, 5);
  316.         mutation(0.0001, pop);
  317.         crossover(0.7, pop);
  318.  
  319.         shortestIndex = 0;
  320.        
  321.         for (int i = 0; i < pop.size(); i++)
  322.         {
  323.             if (pop[i].modified) pop[i].recalculate();
  324.             if (pop[i].tourDistance <= shortest)
  325.             {
  326.                 //std::cout << shortest << " ";
  327.                 shortestIndex = i;
  328.                 shortest = pop[i].tourDistance;
  329.                 //std::cout << shortest << " ";
  330.             }
  331.         }
  332.        
  333.         //std::cout << shortestIndex << std::endl;
  334.         pop[shortestIndex].showPath();
  335.         fout << pop[shortestIndex].tourDistance<<" "<<pop[shortestIndex].fitness<<std::endl;
  336.         fout << "--------------------------------------------------------------\n";
  337.         g++;
  338.     }
  339.  
  340.  
  341.     fout.close();
  342.     return 0;
  343. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement