Main.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int size = 0;
  4. int *data = NULL;
  5. int (*fitness)() = NULL;
  6. void init()
  7. {
  8. int end = size * size;
  9. data = malloc(sizeof(int) * end);
  10. for (int i = 0; i < end; i++)
  11. {
  12. data[i] = i + 1;
  13. }
  14. }
  15. int get(int x, int y) { return data[y * size + x]; }
  16. int errorFactor(int e) { return e * e; }
  17. int getWanted() { return (size * (size * size + 1)) / 2; }
  18. int getSemiFitness()
  19. {
  20. int fitness = 0;
  21. int wanted = getWanted();
  22. for (int y = 0; y < size; y++)
  23. {
  24. int sum = 0;
  25. for (int x = 0; x < size; x++)
  26. {
  27. sum += get(x, y);
  28. }
  29. fitness += errorFactor(sum - wanted);
  30. }
  31. for (int x = 0; x < size; x++)
  32. {
  33. int sum = 0;
  34. for (int y = 0; y < size; y++)
  35. {
  36. sum += get(x, y);
  37. }
  38. fitness += errorFactor(sum - wanted);
  39. }
  40. return fitness;
  41. }
  42. int getDiagonalBase()
  43. {
  44. int diaA = 0;
  45. int diaB = 0;
  46. for (int i = 0; i < size; i++)
  47. {
  48. diaA += get(i, i);
  49. diaB += get(i, (size - 1) - i);
  50. }
  51. int wanted = getWanted();
  52. int fitness = errorFactor(diaA - wanted);
  53. fitness += errorFactor(diaB - wanted);
  54. return fitness;
  55. }
  56. int getNormalFitness() { return getSemiFitness() + getDiagonalBase(); }
  57. int getPandiagonalBase()
  58. {
  59. int fitness = 0;
  60. int wanted = getWanted();
  61. for (int x = 0; x < size; x++)
  62. {
  63. int sumA = 0;
  64. int sumB = 0;
  65. for (int y = 0; y < size; y++)
  66. {
  67. sumA += get((x + y) % size, y);
  68. sumB += get((x - y + size) % size, y);
  69. }
  70. fitness += errorFactor(sumA - wanted);
  71. fitness += errorFactor(sumB - wanted);
  72. }
  73. return fitness;
  74. }
  75. int getAssociativeBase()
  76. {
  77. int fitness = 0;
  78. int wanted = size * size + 1;
  79. for (int x = 0; x < size; x++)
  80. {
  81. for (int y = 0; y < size; y++)
  82. {
  83. int sum = get(x, y) + get(size - x - 1, size - y - 1);
  84. fitness += errorFactor(sum - wanted);
  85. }
  86. }
  87. return fitness;
  88. }
  89. int getUltraFitness()
  90. {
  91. return getSemiFitness() + getPandiagonalBase() + getAssociativeBase();
  92. }
  93. int get2x2SquareBase()
  94. {
  95. int fitness = 0;
  96. int wanted = 2 * (size * size + 1);
  97. for (int x = 0; x < size; x++)
  98. {
  99. for (int y = 0; y < size; y++)
  100. {
  101. if (x % 2 == 0 && y % 2 == 0)
  102. {
  103. int sum = get(x, y) + get(x + 1, y) + get(x, y + 1) +
  104. get(x + 1, y + 1);
  105. fitness += errorFactor(sum - wanted);
  106. }
  107. }
  108. }
  109. return fitness;
  110. }
  111. int getPerfectDiagonalBase()
  112. {
  113. int fitness = 0;
  114. int wanted = size * size + 1;
  115. for (int x = 0; x < size / 2; x++)
  116. {
  117. for (int y = 0; y < size; y++)
  118. {
  119. int sum =
  120. get(x, y) + get((x + size / 2) % size, (y + size / 2) % size);
  121. fitness += errorFactor(sum - wanted);
  122. }
  123. }
  124. return fitness;
  125. }
  126. int getMostPerfectFitness()
  127. {
  128. // printf("ultra: %d\n", getUltraFitness());
  129. // printf("square: %d\n", get2x2SquareBase());
  130. // printf("diagonal: %d\n", getPerfectDiagonalBase());
  131. return getSemiFitness() + getPandiagonalBase() + get2x2SquareBase() +
  132. getPerfectDiagonalBase();
  133. }
  134. void print()
  135. {
  136. printf("Fitness: %d\n", fitness());
  137. for (int y = 0; y < size; y++)
  138. {
  139. for (int x = 0; x < size; x++)
  140. {
  141. printf("%2d ", get(x, y));
  142. }
  143. putchar('\n');
  144. }
  145. putchar('\n');
  146. }
  147. void swap(int a, int b)
  148. {
  149. int tmp = data[a];
  150. data[a] = data[b];
  151. data[b] = tmp;
  152. }
  153. void randSwaps(int swaps)
  154. {
  155. for (int i = 0; i < swaps; i++)
  156. {
  157. swap(rand() % (size * size), rand() % (size * size));
  158. }
  159. }
  160. int main(int argAmount, char **args)
  161. {
  162. if (argAmount < 5)
  163. {
  164. if (argAmount <= 0)
  165. {
  166. printf("... <type> <size> <tries> <generations>\n");
  167. }
  168. else
  169. {
  170. printf("%s <type> <size> <tries> <generations>\n", args[0]);
  171. }
  172. return 0;
  173. }
  174. int type = atoi(args[1]);
  175. size = atoi(args[2]);
  176. int tries = atoi(args[3]);
  177. int generations = atoi(args[4]);
  178. switch (type)
  179. {
  180. case 1:
  181. fitness = getNormalFitness;
  182. break;
  183. case 2:
  184. fitness = getUltraFitness;
  185. break;
  186. case 3:
  187. fitness = getMostPerfectFitness;
  188. break;
  189. default:
  190. puts("unknown type");
  191. return 0;
  192. }
  193. init();
  194. for (int k = 0; k < tries; k++)
  195. {
  196. for (int i = 0; i < generations; i++)
  197. {
  198. int oldFitness = fitness();
  199. int a = rand() % (size * size);
  200. int b = rand() % (size * size);
  201. swap(a, b);
  202. int newFitness = fitness();
  203. if (newFitness == 0)
  204. {
  205. break;
  206. }
  207. if (newFitness >= oldFitness)
  208. {
  209. swap(a, b);
  210. }
  211. }
  212. // if (fitness() < 50)
  213. if (fitness() == 0)
  214. {
  215. print();
  216. }
  217. randSwaps(100);
  218. }
  219. free(data);
  220. return 0;
  221. }