|
@@ -1,103 +1,165 @@
|
|
|
#include <stdio.h>
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
-#define SIZE 9
|
|
|
-#define SUM ((SIZE * (SIZE * SIZE + 1)) / 2)
|
|
|
-
|
|
|
-int data[SIZE][SIZE];
|
|
|
+int size = 0;
|
|
|
+int* data = NULL;
|
|
|
+int (*fitness)() = NULL;
|
|
|
|
|
|
void init() {
|
|
|
- for(int x = 0; x < SIZE; x++) {
|
|
|
- for(int y = 0; y < SIZE; y++) {
|
|
|
- data[x][y] = y * SIZE + x + 1;
|
|
|
- }
|
|
|
+ int end = size * size;
|
|
|
+ data = malloc(sizeof(int) * end);
|
|
|
+ for(int i = 0; i < end; i++) {
|
|
|
+ data[i] = i + 1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+int get(int x, int y) {
|
|
|
+ return data[y * size + x];
|
|
|
+}
|
|
|
+
|
|
|
int errorFactor(int e) {
|
|
|
return e * e;
|
|
|
}
|
|
|
|
|
|
-int getFitness() {
|
|
|
+int getWanted() {
|
|
|
+ return (size * (size * size + 1)) / 2;
|
|
|
+}
|
|
|
+
|
|
|
+int getSemiFitness() {
|
|
|
int fitness = 0;
|
|
|
- for(int y = 0; y < SIZE; y++) {
|
|
|
+ int wanted = getWanted();
|
|
|
+ for(int y = 0; y < size; y++) {
|
|
|
int sum = 0;
|
|
|
- for(int x = 0; x < SIZE; x++) {
|
|
|
- sum += data[x][y];
|
|
|
+ for(int x = 0; x < size; x++) {
|
|
|
+ sum += get(x, y);
|
|
|
}
|
|
|
- fitness += errorFactor(sum - SUM);
|
|
|
+ fitness += errorFactor(sum - wanted);
|
|
|
}
|
|
|
- for(int x = 0; x < SIZE; x++) {
|
|
|
+ for(int x = 0; x < size; x++) {
|
|
|
int sum = 0;
|
|
|
- for(int y = 0; y < SIZE; y++) {
|
|
|
- sum += data[x][y];
|
|
|
+ for(int y = 0; y < size; y++) {
|
|
|
+ sum += get(x, y);
|
|
|
}
|
|
|
- fitness += errorFactor(sum - SUM);
|
|
|
+ fitness += errorFactor(sum - wanted);
|
|
|
}
|
|
|
+ return fitness;
|
|
|
+}
|
|
|
+
|
|
|
+int getDiagonalBase() {
|
|
|
int diaA = 0;
|
|
|
int diaB = 0;
|
|
|
- for(int i = 0; i < SIZE; i++) {
|
|
|
- diaA += data[i][i];
|
|
|
- diaB += data[i][(SIZE - 1) - i];
|
|
|
+ for(int i = 0; i < size; i++) {
|
|
|
+ diaA += get(i, i);
|
|
|
+ diaB += get(i, (size - 1) - i);
|
|
|
+ }
|
|
|
+ int wanted = getWanted();
|
|
|
+ int fitness = errorFactor(diaA - wanted);
|
|
|
+ fitness += errorFactor(diaB - wanted);
|
|
|
+ return fitness;
|
|
|
+}
|
|
|
+
|
|
|
+int getNormalFitness() {
|
|
|
+ return getSemiFitness() + getDiagonalBase();
|
|
|
+}
|
|
|
+
|
|
|
+int getPandiagonalBase() {
|
|
|
+ int fitness = 0;
|
|
|
+ int wanted = getWanted();
|
|
|
+ for(int x = 0; x < size; x++) {
|
|
|
+ int sumA = 0;
|
|
|
+ int sumB = 0;
|
|
|
+ for(int y = 0; y < size; y++) {
|
|
|
+ sumA += get((x + y) % size, y);
|
|
|
+ sumB += get((x - y + size) % size, y);
|
|
|
+ }
|
|
|
+ fitness += errorFactor(sumA - wanted);
|
|
|
+ fitness += errorFactor(sumB - wanted);
|
|
|
}
|
|
|
- fitness += errorFactor(diaA - SUM);
|
|
|
- fitness += errorFactor(diaB - SUM);
|
|
|
return fitness;
|
|
|
}
|
|
|
|
|
|
+int getAssociativeBase() {
|
|
|
+ int fitness = 0;
|
|
|
+ int wanted = size * size + 1;
|
|
|
+ for(int x = 0; x < size; x++) {
|
|
|
+ for(int y = 0; y < size; y++) {
|
|
|
+ int sum = get(x, y) + get(size - x - 1, size - y - 1);
|
|
|
+ fitness += errorFactor(sum - wanted);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return fitness;
|
|
|
+}
|
|
|
+
|
|
|
+int getUltraFitness() {
|
|
|
+ return getSemiFitness() + getPandiagonalBase() + getAssociativeBase();
|
|
|
+}
|
|
|
+
|
|
|
void print() {
|
|
|
- printf("Fitness: %d\n", getFitness());
|
|
|
- for(int y = 0; y < SIZE; y++) {
|
|
|
- for(int x = 0; x < SIZE; x++) {
|
|
|
- printf("%2d ", data[x][y]);
|
|
|
+ printf("Fitness: %d\n", fitness());
|
|
|
+ for(int y = 0; y < size; y++) {
|
|
|
+ for(int x = 0; x < size; x++) {
|
|
|
+ printf("%2d ", get(x, y));
|
|
|
}
|
|
|
putchar('\n');
|
|
|
}
|
|
|
putchar('\n');
|
|
|
}
|
|
|
|
|
|
-void swap(int x1, int y1, int x2, int y2) {
|
|
|
- int tmp = data[x1][y1];
|
|
|
- data[x1][y1] = data[x2][y2];
|
|
|
- data[x2][y2] = tmp;
|
|
|
-}
|
|
|
-
|
|
|
-void randSwap() {
|
|
|
- swap(rand() % SIZE, rand() % SIZE, rand() % SIZE, rand() % SIZE);
|
|
|
+void swap(int a, int b) {
|
|
|
+ int tmp = data[a];
|
|
|
+ data[a] = data[b];
|
|
|
+ data[b] = tmp;
|
|
|
}
|
|
|
|
|
|
void randSwaps(int swaps) {
|
|
|
for(int i = 0; i < swaps; i++) {
|
|
|
- swap(rand() % SIZE, rand() % SIZE, rand() % SIZE, rand() % SIZE);
|
|
|
+ swap(rand() % (size * size), rand() % (size * size));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-int main() {
|
|
|
- init();
|
|
|
- for(int k = 0; k < 2000; k++) {
|
|
|
- for(int i = 0; i < 1000000; i++) {
|
|
|
- int oldFitness = getFitness();
|
|
|
+int main(int argAmount, char** args) {
|
|
|
+ if(argAmount < 5) {
|
|
|
+ if(argAmount <= 0) {
|
|
|
+ printf("... <type> <size> <tries> <generations>\n");
|
|
|
+ } else {
|
|
|
+ printf("%s <type> <size> <tries> <generations>\n", args[0]);
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ int type = atoi(args[1]);
|
|
|
+ size = atoi(args[2]);
|
|
|
+ int tries = atoi(args[3]);
|
|
|
+ int generations = atoi(args[4]);
|
|
|
+
|
|
|
+ switch(type) {
|
|
|
+ case 1: fitness = getNormalFitness; break;
|
|
|
+ case 2: fitness = getUltraFitness; break;
|
|
|
+ default: puts("unknown type"); return 0;
|
|
|
+ }
|
|
|
|
|
|
- int x1 = rand() % SIZE;
|
|
|
- int y1 = rand() % SIZE;
|
|
|
- int x2 = rand() % SIZE;
|
|
|
- int y2 = rand() % SIZE;
|
|
|
+ init();
|
|
|
+ for(int k = 0; k < tries; k++) {
|
|
|
+ for(int i = 0; i < generations; i++) {
|
|
|
+ int oldFitness = fitness();
|
|
|
|
|
|
- swap(x1, y1, x2, y2);
|
|
|
+ int a = rand() % (size * size);
|
|
|
+ int b = rand() % (size * size);
|
|
|
+ swap(a, b);
|
|
|
|
|
|
- int newFitness = getFitness();
|
|
|
+ int newFitness = fitness();
|
|
|
if(newFitness == 0) {
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
if(newFitness >= oldFitness) {
|
|
|
- swap(x1, y1, x2, y2);
|
|
|
+ swap(a, b);
|
|
|
}
|
|
|
}
|
|
|
- if(getFitness() == 0) {
|
|
|
+ if(fitness() == 0) {
|
|
|
print();
|
|
|
}
|
|
|
randSwaps(400);
|
|
|
}
|
|
|
+ free(data);
|
|
|
return 0;
|
|
|
}
|