• No results found

else return

write(x,d)

if

jxj

l

store x] = d

return

original contents of store x]

else

evaluate d

return

0

swap(x,y)

if

jxj

land

jyj

l

exchange contents of store x] and store y]

if

jxj

> l

and

jyj

l

store y] = 0

if

jxj

l

and

jyj

> l

store x] = 0

Loops may not appear inside the third argument of other loops (i.e. no nested loops).

Adf1 must contain at least one loop, which must contain at least one i0.

It would appear to be sensible for code to use its arguments. Where feasible, syntax

checks are used to encourage this. Thus Retrieve, Next, Previous, Adf1, Ins adf, Del adf, Loc adf and Prt adf must contain at least one arg1 terminal and Adf1 must contain at least one FUNC (cf. Table 5.4) primitive.

5.5 Fitness Function

5.5.1 Pareto Optimality and Niches

Pareto tness was described in Section 2.3.8 and used in some queue experiments (cf. Section 4.10.1). Pareto scoring means individuals which make an improvement on any part of the problem tend to be preferred, whereas a scalar tness will tend to require each improvement to match or exceed any deterioration in all other parts of the problem. Whether an improvement is more important than a deterioration is given by scaling pa- rameters within the tness function. Consequently setting them is complex and must be done with care. To some extent Pareto tness avoids this problem.

With Pareto scoring, a single population can contain several hundred dierent tness values (or niches) each of which is the best in the sense of not being dominated by any other member of the population. This encourages crossover between individuals that are good at dierent parts of the problem, which may produce ospring that are relatively t on more of the problem. However unless there is some selection pressure to maintain multiple niches, the population will tend to reduce the number of niches it occupies. This is an aspect of \genetic drift" is particularly important in small populations Horn et al., 1993]. To maintain a large number of niches the tness sharing scheme described in Section 2.3.8 was used.

Where a selection tournament is unable to discriminate between two or more candidates (either because they have identical tness or no tness value dominates all the others) then these candidates are compared with a sample of the rest of the population. The one that is dominated by or has identical tness to the fewest other members of the population wins the tournament. This creates a secondary selection pressure in favour of individuals that occupy relatively unpopulated niches, which tends to prevent the population converging and instead it contains many dierent non-dominated tness niches.

1 10 100 1000 10000 0 100000 200000 300000 400000 500000 600000 700000 800000 900000 1e+06 Number of Individuals Created

Points on pareto surface No. non-dominated progs No comparison set

0 100000 200000 300000 400000 500000 600000 700000 800000 900000 1e+06 Number of Individuals Created

Max passes

Max passes (no comparison set) 51

24

13

Figure 5.2: Evolution of the number of tness niches occupied with and without compari- son with the rest of the population (3indicates run without comparison set). Typical list

runs (starting from identical initial populations). All plots, except the maximum number of tests passed, are plotted on a log scale.

number of non-dominated tness values within the population (i.e. occupied points on the Pareto surface) evolves to be about 100{150, with on average 6{9 programs per niche. In contrast where comparison with the rest of the population is not used the number of non- dominated tness values in the population falls rapidly, stabilising at about 10. However the population eventually converges to a few of these so that they contain about 3

4 of the

population. Without comparison with the rest of the population, the proportion of the population with one of the best tness values is also more erratic.

5.5.2 Fitness Test Case

The tness of each individual is determined by running it on 21 xed test sequences containing in total 538 operations. Tests are grouped into (a total of 167) subsequences which call several operations and cross check the values returned by them. If the checks are passed we increase the program's tness along each dimension corresponding to an operation in the subsequence. However if a check is not passed no further tests from the test sequence are made and the next sequence is started. This has the advantage of reducing run time by reducing the number of operations that are executed but perhaps encourages premature convergence by stressing the tests that occur at the start of each sequence which tend to be easier and possibly susceptible to solution by simple but highly

test specic code.

No preset design or pattern of memory usage is imposed by the tness tests. This undoubtedly makes the problem more dicult but we wish to show an implementation can be automatically generated. This exibility makes testing more complex as often it is impossible to say the answer returned by an operation is correct, until it can be compared with answers returned by other operations (cf. column six in Table 5.2).

As in Chapters 3 and 4, the tests only cover correct operation of the list. I.e. error trapping, such as detecting the deletion of non-existing list elements, is not covered.

Again like Chapters 3 and 4 all storage, i.e. the indexed memory and aux1, is initialized at the start of each test sequence (i.e. 21 times). In half the test sequences the indexed memory is initialized to zero (aux1 is always set to zero). In the other half (unlike Chapters 3 and 4) the indexed memory is initialized to a random but xed data pattern, which is dierent for each test sequence. This is to discourage the GP from evolving partial solutions which exploit the value zero to indicate memory cells are unlikely to have been written to and so are empty. In earlier experiments (cf. Section 4.4.1) such programs had been found, they appeared to work until they inserted zero into the data structure. The random data patterns have the same distribution of values as that inserted into the list. In most other published work indexed memory is initialised to zero (as in Chapters 3 and 4) however Jannink, 1994, page 436] describes a regular non-zero initialization pattern. Crepeau, 1995, page 132] \memory locations (are) initially lled with random 8 bit values" as this makes it \highly probably" that problem specic values needed to solve the problem \are somewhere in memory".