Main.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #include <algorithm>
  2. #include <chrono>
  3. #include <climits>
  4. #include <iostream>
  5. #include "Reader.h"
  6. int center;
  7. Reader r;
  8. struct Data {
  9. std::vector<int> order;
  10. std::vector<int> vehicles;
  11. mutable int fitness = -1;
  12. Data(int size) : order(size, 0), vehicles(size, rand() % 4) {
  13. int counter = -1;
  14. for(int& i : order) {
  15. counter++;
  16. if(counter == center) {
  17. counter++;
  18. }
  19. i = counter;
  20. }
  21. }
  22. int getFitness() const {
  23. if(fitness != -1) {
  24. return fitness;
  25. }
  26. int last[4] = {center, center, center, center};
  27. int sum[4] = {0, 0, 0, 0};
  28. fitness = 0;
  29. for(size_t i = 0; i < order.size(); i++) {
  30. int v = vehicles[i];
  31. sum[v] += r[last[v]][order[i]];
  32. last[v] = order[i];
  33. }
  34. for(int i = 0; i < 4; i++) {
  35. sum[i] += r[last[i]][center];
  36. }
  37. int max = std::max(std::max(sum[0], sum[1]), std::max(sum[2], sum[3]));
  38. fitness = sum[0] + sum[1] + sum[2] + sum[3] + max * 4;
  39. return fitness;
  40. }
  41. void mutate() {
  42. if(rand() & 1) {
  43. vehicles[rand() % vehicles.size()] = rand() % 4;
  44. } else {
  45. int a = rand() % vehicles.size();
  46. int b = rand() % vehicles.size();
  47. if(b <= a) {
  48. std::swap(a, b);
  49. }
  50. int oldB = order[b];
  51. for(int i = b; i > a; i--) {
  52. order[i] = order[i - 1];
  53. }
  54. order[a] = oldB;
  55. oldB = vehicles[b];
  56. for(int i = b; i > a; i--) {
  57. vehicles[i] = vehicles[i - 1];
  58. }
  59. vehicles[a] = oldB;
  60. }
  61. fitness = -1;
  62. }
  63. void print() const {
  64. for(int i : order) {
  65. std::cout << i << " ";
  66. }
  67. std::cout << "| ";
  68. for(int i : vehicles) {
  69. std::cout << i << " ";
  70. }
  71. std::cout << "| " << getFitness() << "\n";
  72. }
  73. void prettyPrint() const {
  74. for(int i = 0; i < 4; i++) {
  75. std::cout << i << ": " << r.getName(center) << " -> ";
  76. for(size_t k = 0; k < order.size(); k++) {
  77. if(vehicles[k] == i) {
  78. std::cout << r.getName(order[k]) << " -> ";
  79. }
  80. }
  81. std::cout << r.getName(center) << "\n";
  82. }
  83. }
  84. bool operator<(const Data& other) const {
  85. return getFitness() < other.getFitness();
  86. }
  87. };
  88. std::vector<Data> population;
  89. static void init() {
  90. for(int i = 0; i < 1000; i++) {
  91. population.push_back(Data(r.getSize() - 1));
  92. }
  93. for(Data& data : population) {
  94. for(int i = 0; i < 40; i++) {
  95. data.mutate();
  96. }
  97. }
  98. }
  99. static void sort() {
  100. std::sort(population.begin(), population.end());
  101. }
  102. static void findCenter() {
  103. int min = INT_MAX;
  104. int index = 0;
  105. for(int i = 0; i < r.getSize(); i++) {
  106. int sum = 0;
  107. for(int k = 0; k < r.getSize(); k++) {
  108. sum += r[i][k];
  109. }
  110. if(sum < min) {
  111. index = i;
  112. min = sum;
  113. }
  114. }
  115. center = index;
  116. }
  117. long getNanos() {
  118. return std::chrono::high_resolution_clock::now().time_since_epoch().count();
  119. }
  120. int main(int argAmount, char** args) {
  121. long start = -getNanos();
  122. if(r.read("romaniaroads.pl")) {
  123. return 0;
  124. }
  125. if(argAmount >= 2) {
  126. int c = atoi(args[1]);
  127. if(c < 0 || c >= r.getSize()) {
  128. std::cout << c << " is not a valid center\n";
  129. return 0;
  130. }
  131. center = c;
  132. } else {
  133. findCenter();
  134. }
  135. start += getNanos();
  136. long loop = -getNanos();
  137. init();
  138. sort();
  139. for(int gens = 0; gens < 500; gens++) {
  140. size_t half = population.size() / 2;
  141. for(size_t i = half; i < population.size(); i++) {
  142. int parent = rand() % half;
  143. population[i] = population[parent];
  144. population[i].mutate();
  145. }
  146. sort();
  147. }
  148. for(size_t i = 10; i > 0; i--) {
  149. population[i - 1].print();
  150. }
  151. population[0].prettyPrint();
  152. std::cout << "center is " << r.getName(center) << "\n";
  153. loop += getNanos();
  154. std::cout << "Start: " << start / 1'000'000 << "ms\n";
  155. std::cout << "Loop: " << loop / 1'000'000 << "ms\n";
  156. return 0;
  157. }