|
@@ -2,42 +2,43 @@
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
int size = 0;
|
|
|
-int* data = NULL;
|
|
|
+int *data = NULL;
|
|
|
int (*fitness)() = NULL;
|
|
|
|
|
|
-void init() {
|
|
|
+void init()
|
|
|
+{
|
|
|
int end = size * size;
|
|
|
data = malloc(sizeof(int) * end);
|
|
|
- for(int i = 0; i < end; i++) {
|
|
|
+ for (int i = 0; i < end; i++)
|
|
|
+ {
|
|
|
data[i] = i + 1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-int get(int x, int y) {
|
|
|
- return data[y * size + x];
|
|
|
-}
|
|
|
+int get(int x, int y) { return data[y * size + x]; }
|
|
|
|
|
|
-int errorFactor(int e) {
|
|
|
- return e * e;
|
|
|
-}
|
|
|
+int errorFactor(int e) { return e * e; }
|
|
|
|
|
|
-int getWanted() {
|
|
|
- return (size * (size * size + 1)) / 2;
|
|
|
-}
|
|
|
+int getWanted() { return (size * (size * size + 1)) / 2; }
|
|
|
|
|
|
-int getSemiFitness() {
|
|
|
+int getSemiFitness()
|
|
|
+{
|
|
|
int fitness = 0;
|
|
|
int wanted = getWanted();
|
|
|
- for(int y = 0; y < size; y++) {
|
|
|
+ for (int y = 0; y < size; y++)
|
|
|
+ {
|
|
|
int sum = 0;
|
|
|
- for(int x = 0; x < size; x++) {
|
|
|
+ for (int x = 0; x < size; x++)
|
|
|
+ {
|
|
|
sum += get(x, y);
|
|
|
}
|
|
|
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++) {
|
|
|
+ for (int y = 0; y < size; y++)
|
|
|
+ {
|
|
|
sum += get(x, y);
|
|
|
}
|
|
|
fitness += errorFactor(sum - wanted);
|
|
@@ -45,10 +46,12 @@ int getSemiFitness() {
|
|
|
return fitness;
|
|
|
}
|
|
|
|
|
|
-int getDiagonalBase() {
|
|
|
+int getDiagonalBase()
|
|
|
+{
|
|
|
int diaA = 0;
|
|
|
int diaB = 0;
|
|
|
- for(int i = 0; i < size; i++) {
|
|
|
+ for (int i = 0; i < size; i++)
|
|
|
+ {
|
|
|
diaA += get(i, i);
|
|
|
diaB += get(i, (size - 1) - i);
|
|
|
}
|
|
@@ -58,17 +61,18 @@ int getDiagonalBase() {
|
|
|
return fitness;
|
|
|
}
|
|
|
|
|
|
-int getNormalFitness() {
|
|
|
- return getSemiFitness() + getDiagonalBase();
|
|
|
-}
|
|
|
+int getNormalFitness() { return getSemiFitness() + getDiagonalBase(); }
|
|
|
|
|
|
-int getPandiagonalBase() {
|
|
|
+int getPandiagonalBase()
|
|
|
+{
|
|
|
int fitness = 0;
|
|
|
int wanted = getWanted();
|
|
|
- for(int x = 0; x < size; x++) {
|
|
|
+ for (int x = 0; x < size; x++)
|
|
|
+ {
|
|
|
int sumA = 0;
|
|
|
int sumB = 0;
|
|
|
- for(int y = 0; y < size; y++) {
|
|
|
+ for (int y = 0; y < size; y++)
|
|
|
+ {
|
|
|
sumA += get((x + y) % size, y);
|
|
|
sumB += get((x - y + size) % size, y);
|
|
|
}
|
|
@@ -78,11 +82,14 @@ int getPandiagonalBase() {
|
|
|
return fitness;
|
|
|
}
|
|
|
|
|
|
-int getAssociativeBase() {
|
|
|
+int getAssociativeBase()
|
|
|
+{
|
|
|
int fitness = 0;
|
|
|
int wanted = size * size + 1;
|
|
|
- for(int x = 0; x < size; x++) {
|
|
|
- for(int y = 0; y < size; y++) {
|
|
|
+ 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);
|
|
|
}
|
|
@@ -90,14 +97,61 @@ int getAssociativeBase() {
|
|
|
return fitness;
|
|
|
}
|
|
|
|
|
|
-int getUltraFitness() {
|
|
|
+int getUltraFitness()
|
|
|
+{
|
|
|
return getSemiFitness() + getPandiagonalBase() + getAssociativeBase();
|
|
|
}
|
|
|
|
|
|
-void print() {
|
|
|
+int get2x2SquareBase()
|
|
|
+{
|
|
|
+ int fitness = 0;
|
|
|
+ int wanted = 2 * (size * size + 1);
|
|
|
+ for (int x = 0; x < size; x++)
|
|
|
+ {
|
|
|
+ for (int y = 0; y < size; y++)
|
|
|
+ {
|
|
|
+ if (x % 2 == 0 && y % 2 == 0)
|
|
|
+ {
|
|
|
+ int sum = get(x, y) + get(x + 1, y) + get(x, y + 1) +
|
|
|
+ get(x + 1, y + 1);
|
|
|
+ fitness += errorFactor(sum - wanted);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return fitness;
|
|
|
+}
|
|
|
+int getPerfectDiagonalBase()
|
|
|
+{
|
|
|
+ int fitness = 0;
|
|
|
+ int wanted = size * size + 1;
|
|
|
+ for (int x = 0; x < size / 2; x++)
|
|
|
+ {
|
|
|
+ for (int y = 0; y < size; y++)
|
|
|
+ {
|
|
|
+ int sum =
|
|
|
+ get(x, y) + get((x + size / 2) % size, (y + size / 2) % size);
|
|
|
+ fitness += errorFactor(sum - wanted);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return fitness;
|
|
|
+}
|
|
|
+
|
|
|
+int getMostPerfectFitness()
|
|
|
+{
|
|
|
+ // printf("ultra: %d\n", getUltraFitness());
|
|
|
+ // printf("square: %d\n", get2x2SquareBase());
|
|
|
+ // printf("diagonal: %d\n", getPerfectDiagonalBase());
|
|
|
+ return getSemiFitness() + getPandiagonalBase() + get2x2SquareBase() +
|
|
|
+ getPerfectDiagonalBase();
|
|
|
+}
|
|
|
+
|
|
|
+void print()
|
|
|
+{
|
|
|
printf("Fitness: %d\n", fitness());
|
|
|
- for(int y = 0; y < size; y++) {
|
|
|
- for(int x = 0; x < size; x++) {
|
|
|
+ for (int y = 0; y < size; y++)
|
|
|
+ {
|
|
|
+ for (int x = 0; x < size; x++)
|
|
|
+ {
|
|
|
printf("%2d ", get(x, y));
|
|
|
}
|
|
|
putchar('\n');
|
|
@@ -105,23 +159,31 @@ void print() {
|
|
|
putchar('\n');
|
|
|
}
|
|
|
|
|
|
-void swap(int a, int b) {
|
|
|
+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++) {
|
|
|
+void randSwaps(int swaps)
|
|
|
+{
|
|
|
+ for (int i = 0; i < swaps; i++)
|
|
|
+ {
|
|
|
swap(rand() % (size * size), rand() % (size * size));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-int main(int argAmount, char** args) {
|
|
|
- if(argAmount < 5) {
|
|
|
- if(argAmount <= 0) {
|
|
|
+int main(int argAmount, char **args)
|
|
|
+{
|
|
|
+ if (argAmount < 5)
|
|
|
+ {
|
|
|
+ if (argAmount <= 0)
|
|
|
+ {
|
|
|
printf("... <type> <size> <tries> <generations>\n");
|
|
|
- } else {
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
printf("%s <type> <size> <tries> <generations>\n", args[0]);
|
|
|
}
|
|
|
return 0;
|
|
@@ -131,15 +193,27 @@ int main(int argAmount, char** args) {
|
|
|
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;
|
|
|
+ switch (type)
|
|
|
+ {
|
|
|
+ case 1:
|
|
|
+ fitness = getNormalFitness;
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ fitness = getUltraFitness;
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ fitness = getMostPerfectFitness;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ puts("unknown type");
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
init();
|
|
|
- for(int k = 0; k < tries; k++) {
|
|
|
- for(int i = 0; i < generations; i++) {
|
|
|
+ for (int k = 0; k < tries; k++)
|
|
|
+ {
|
|
|
+ for (int i = 0; i < generations; i++)
|
|
|
+ {
|
|
|
int oldFitness = fitness();
|
|
|
|
|
|
int a = rand() % (size * size);
|
|
@@ -147,18 +221,22 @@ int main(int argAmount, char** args) {
|
|
|
swap(a, b);
|
|
|
|
|
|
int newFitness = fitness();
|
|
|
- if(newFitness == 0) {
|
|
|
+ if (newFitness == 0)
|
|
|
+ {
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- if(newFitness >= oldFitness) {
|
|
|
+ if (newFitness >= oldFitness)
|
|
|
+ {
|
|
|
swap(a, b);
|
|
|
}
|
|
|
}
|
|
|
- if(fitness() == 0) {
|
|
|
+ // if (fitness() < 50)
|
|
|
+ if (fitness() == 0)
|
|
|
+ {
|
|
|
print();
|
|
|
}
|
|
|
- randSwaps(400);
|
|
|
+ randSwaps(100);
|
|
|
}
|
|
|
free(data);
|
|
|
return 0;
|