The goal is to find a true magic square. That is the number from 1 to n^2 (n!=2) are
to be arranged within a n*n grid, in such a way that the all sums of all rows,
all sums of all columns and both sums of the diagonals yield the same value S.
// 4x4 magic square
double object_parameters[] = { 1 ,2 ,3 ,4,
5 ,6 ,7 ,8,
9 ,10,11,12,
13,14,15,16 };
double strategy_parameters[] = { 2,2,2,2,
2,2,2,2,
2,2,2,2,
2,2,2,2};
A problem_specific mutation-operator is used. It is based on swapping
object-parameters: For each chromosome to be 'mutated' the following process
is repeated X times (where X is the strategy_parameters value): example:
let all startegy-parameters have a value of 2; => 2 swap-operations
1. swap
let the first selected object-parameter be number 6;
look for second object-parameter within range 4..8={4,5,6,7,8};
let the second selected object-parameter be number 7;
=> swap 6 and 7
2. swap
let the first selected object-parameter be number 16;
look for second object-parameter within range 14..18={14,15,16,17,18};
let the second selected object-parameter be number 15;
=> swap 16 and 15
Note that using recombination with this example will produce 'illegal' magic
squares and should NOT be used (see below: effect of crossover in GA-version) !
// 4x4 magic square numbers 1..16 <-> 10000..00001 i.e. bit-order 01234
[ [11010][10110][00001][10100] // 11 13 16 5
[01100][11100][10000][11000] // 6 7 1 3
[01000][00010][10010][00110] // 2 8 9 12
[01110][00100][11110][01010] ] // 14 4 15 10
A problem-specific crossover-operator is used which could be refered to
as permutation operator. The operator is unary. That is each of the two crossover
partners is handled individually. If m is the number of crossover-points than
the specific crossover operator simply 'swaps' m pairs of values thus producing
another permutation of 1..n^2 (n × n magic square). simple: integer representation of parameter = corresponding number in magic square;
quality=0;
for each row
s=get_sum( row )
quality = quality + (S-s)*(S-s)
for each column
s=get_sum( column )
quality = quality + (S-s)*(S-s)
s=get_sum( first_diagonal )
quality = quality + (S-s)*(S-s)
s=get_sum( second_diagonal )
quality = quality + (S-s)*(S-s)