The next example illustrates some of the strengths and weaknesses of the arithmetic and heuristic crossover operators. The objective function to be minimized is
start sin_obj(x) global(xopt); r = abs(sin(sum(abs(x-xopt)))); return(r); finish;
This function obviously has a minimum at x=xopt, and is not differentiable at all points. The following program sets xopt= 0 and specifies constant boundary constraints such that the optimum is in the interior of the search space, and specifies the heuristic crossover operator:
proc iml;
/* objective function, has minimum of 0 at x = xopt */
start sin_obj(x) global(xopt);
r = abs(sin(sum(abs(x-xopt))));
return(r);
finish;
xopt = { 0 0 0 };
optimum = xopt;
optval = sin_obj(optimum);
id = gasetup(1, /* 1-> fixed-length floating point vector encoding */
3, /* 3-> length of solution vectors */
1234 /* 0-> initial random seed */
);
call gasetobj(id,0,"sin_obj"); /* 0->minimize a user module,
* "sin_obj" is name of module */
call gasetcro(id, 0.9, 4); /* crossover probabilty 0.9,
* 4-> heuristic crossover operator */
call gasetmut(id,0.05,2,0.01); /* mutation probability 0.05,
* 2-> delta mutation operator
* 0.01 is delta value */
call gasetsel(id, 5, 1, 0.95); /* carry best 5 solutions over
* to the next generation, dual
* tournment with 0.95 best-player
* wins probability */
bounds = {-1 -1 -1, 1 1 1};
call gainit(id,200,bounds); /* initialize population with
* 200 members, "bounds" gives
* upper and lower bounds for
* components of randomly
* randomly generated vectors */
summary = j(20,2);
mattrib summary [c = {"bestValue", "avgValue"}];
call gagetval(value, id);
summary[1,1] = value[1];
summary[1,2] = value[:];
do i = 2 to 20;
call garegen(id);
call gagetval(value, id); /* get all objective values of
* the population */
summary[i,1] = value[1];
summary[i,2] = value[:];
end;
iteration = t(1:20);
print iteration summary;
call gaend(id);
The output results are
SUMMARY
ITERATION bestValue avgValue
1 0.894517 0.8926763
2 0.894517 0.752227
3 0.1840732 0.6087493
4 0.14112 0.4848342
5 0.14112 0.3991614
6 0.14112 0.3539561
7 0.0481937 0.3680798
8 0.0481937 0.3243406
9 0.0481937 0.3027395
10 0.0481937 0.2679123
11 0.0481937 0.2550643
12 0.0481937 0.2582514
13 0.0481937 0.2652337
14 0.0481937 0.2799655
15 0.0383933 0.237546
16 0.0383933 0.3008743
17 0.0383933 0.2341022
18 0.0383933 0.1966969
19 0.0383933 0.2778152
20 0.0383933 0.2690036
To show the convergence of the overall population, the average value of the objective function for the whole population is printed out as well as the best value. The optimum value for this formulation is 0, and the optimum solution is (0 0 0). The output shows the convergence of the GA to be slow, especially as the solutions get near the optimum. This is the result of applying the heuristic crossover operator to an ill-behaved objective function. If you change the crossover to the arithmetic operator by changing the GASETCRO call to
call gasetcro(id, 0.9, 3); /* 3-> arithmetic crossover operator */
you get the following output:
SUMMARY
ITERATION bestValue avgValue
1 0.894517 0.8926763
2 0.894517 0.8014329
3 0.1840732 0.6496871
4 0.1705931 0.4703868
5 0.0984926 0.2892114
6 0.076859 0.1832358
7 0.0287965 0.1123732
8 0.0273074 0.0720792
9 0.018713 0.0456323
10 0.0129708 0.0309648
11 0.0087931 0.0240822
12 0.0087931 0.0172102
13 0.0050753 0.0128258
14 0.0019603 0.0092872
15 0.0016225 0.0070575
16 0.0016225 0.0051149
17 0.0012465 0.0036445
18 0.0011895 0.002712
19 0.0007646 0.0023329
20 0.0007646 0.0020842
For this case, the arithmetic operator shows improved convergence. Suppose you change the problem characteristics again by changing the constraints so that the optimum lies on a boundary. The following statement moves the optimum to a boundary:
bounds = {0 0 0, 1 1 1};
The output using the arithmetic operator is
SUMMARY
ITERATION bestValue avgValue
1 0.8813497 0.8749132
2 0.8813497 0.860011
3 0.3721446 0.8339357
4 0.3721446 0.79106
5 0.3721446 0.743336
6 0.3721446 0.7061592
7 0.3721446 0.6797346
8 0.3721446 0.6302206
9 0.3721446 0.5818008
10 0.3721446 0.5327339
11 0.3721446 0.5149562
12 0.3721446 0.48525
13 0.3721446 0.4708617
14 0.3721446 0.4582203
15 0.3721446 0.433538
16 0.3721446 0.4256162
17 0.3721446 0.4236062
18 0.3721446 0.4149336
19 0.3721446 0.4135214
20 0.3721446 0.4078068
In this case, the algorithm fails to converge to the true optimum, given the characteristic of the arithmetic operator to converge on interior points. However, if you switch back to the heuristic crossover operator the results are
SUMMARY
ITERATION bestValue avgValue
1 0.8813497 0.8749132
2 0.8813497 0.7360591
3 0.3721446 0.5465098
4 0 0.3427185
5 0 0.2006271
6 0 0.0826017
7 0 0.0158228
8 0 0.0002602
9 0 0.00005
10 0 0.00065
11 0 0.0003
12 0 0.0002
13 0 0.0002
14 0 0.000285
15 0 0.0005
16 0 0.0002952
17 0 0.0002
18 0 0.0001761
19 0 0.00035
20 0 0.00035
These results show a rapid convergence to the optimum. This example illustrates how the results of a GA are very operator-dependent. For complicated problems with unknown solution, you might need to try a number of different combinations of parameters in order to have confidence that you have converged to a true global optimum.