Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 1
Evolving EfficientList Search Algorithms
Kfir Wolfson
Moshe Sipper
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 2
Agenda
Introduction Evolutionary Setup Results Less Knowledge – More Automation Related Work Conclusions and Future Work
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 3
Introduction Algorithm design is important task in CS Evolutionary algorithms have been applied to many areas,
but limited research on software engineering and algorithmic design
We introduce the notion “Algorithmic design through Darwinian evolution”
Begin with a benchmark case – List Search Algorithms:1. Can evolution be applied to finding a search algorithm?
2. Can evolution be applied to finding an efficient search algorithm?
We employ Genetic Programming (GP) to the task and show the answer to both questions is affirmative
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 4
Agenda
Introduction Evolutionary Setup Results Less Knowledge – More Automation Related Work Conclusions and Future Work
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 5
Evolutionary Setup
RepresentationPhenotypeGenotype
GP ParametersFitness Function GP Operators
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 6
Representation Phenotype
Array search algorithm Searches for a key in a 1-dimentional array
Java static function:
public static int search(int[] arr, int KEY) { int n = arr.length; int M0 = 0; int M1 = n-1; int INDEX = 0;
for (int ITER = 0; ITER < iterations; ITER++) {
-> PLUG IN EVOLVING GENOTYPE HERE <- } return INDEX;}
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 7
Representation
public static int search(int[] arr, int KEY) { int n = arr.length; int M0 = 0; int M1 = n-1; int INDEX = 0;
for (int ITER = 0; ITER < iterations; ITER++) {
-> PLUG IN EVOLVING GENOTYPE HERE <- } return INDEX;}
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 8
Representationpublic static int search(int[] arr, int KEY) { int n = arr.length; int M0 = 0; int M1 = n-1; int INDEX = 0;
for (int ITER = 0; ITER < iterations; ITER++) {
-> PLUG IN EVOLVING GENOTYPE HERE <- } return INDEX;}
Set to:• n for linear search• log2 n for sublinearArray index returned
(might be “illegal”)
global variables
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 9
Representation Genotype
Koza-style genetic programming Evaluation trees
Strongly typed More understandable algorithms
Function and Terminal sets Same for evolution of both linear and
sublinear search algorithms
If
=
Array[INDEX]
KEY
NOPINDEX:=
ITER
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 10
Representationpublic static int search(int[] arr, int KEY) { int n = arr.length; int M0 = 0; int M1 = n-1; int INDEX = 0;
for (int ITER = 0; ITER < iterations; ITER++) { -> PLUG IN EVOLVING GENOTYPE HERE <- } return INDEX;}
-> PLUG IN EVOLVING GENOTYPE HERE <-
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 11
Representation-> PLUG IN EVOLVING GENOTYPE HERE <-
Function or Terminal
ArgumentsReturn Type
Description
INDEXnoneintCurrent pointer into array
INDEX:=intvoidSet the value of INDEX
Array[INDEX]noneintElement at location INDEX in the input array, or 0 if INDEX is not in [0, n-1]
KEYnoneintThe element we are searching for
ITERnoneintCurrent iteration number
1718233460Array =
KEY = 18
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 12
Representation
Function or Terminal
ArgumentsReturn Type
Description
Ifbool, void, voidvoid
Conditional branching: if the 1st argument evaluates to true, execute 2nd argument, otherwise execute 3rd argument
>, <, =int, intbool
Returns true iff1st argument >, < or = 2nd argument
TRUE, FALSEvoidboolBoolean terminals
PROGN2void, voidvoidSequence
NOPvoidvoidDoes nothing
-> PLUG IN EVOLVING GENOTYPE HERE <-
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 13
Representation
Function or Terminal
ArgumentsReturn Type
Description
M0, M1noneintGetters to global variables, at the algorithm's disposal
M0:=, M1:=intvoidSetters to global variables
[M0+M1]/2noneintAverage of M0, M1
(truncated to nearest integer)
The [M0+M1]/2 terminal• Embodies human intuition about the problem to facilitate the solution• Still requires crucial algorithmic insight to be derived via evolution• Later we re-examine this terminal, repealing it altogether.
-> PLUG IN EVOLVING GENOTYPE HERE <-
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 14
Representation - Example An example correct solution to linear search problem:
LISP:(If (= Array[INDEX] KEY) NOP INDEX:= ITER)))
If
=
Array[INDEX]
KEY
NOPINDEX:=
ITER
Let’s plug into
the phenotype frame…if (arr[INDEX] == KEY) ;else INDEX = ITER;
Equivalent Java:
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 15
Representation - Example An example correct solution to linear search problem:
public static int search(int[] arr, int KEY) { int n = arr.length; int M0 = 0; int M1 = n-1; int INDEX = 0; for (int ITER = 0; ITER < iterations; ITER++) { if (arr[INDEX] == KEY) ; else INDEX = ITER; } return INDEX;}
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 16
Representation
search call: Always halts
No loop functions Only read access to ITER Number of iterations is limited
Inherently deals with keys not in the array With wrapper function
No early termination when key is found Harder problem:
Evolved algorithm will have to learn to retain correct index.
int search(int[] arr, int KEY) { int n = arr.length; int M0 = 0; int M1 = n-1; int INDEX = 0; for (int ITER=0; ITER < iterations; ITER++) { -> PLUG IN GENOTYPE HERE <- } return INDEX;}Why?
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 17
Evolutionary Setup
RepresentationPhenotypeGenotype
GP ParametersFitness Function GP Operators
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 18
Fitness Function How do we rate a solution?
Present the individual with many random input arrays Use search method to search for all keys in all arrays Reward individual for closeness of returned indexes
Training set includes arrays of all sizes in [minN, maxN] Array of size n contains: Linear case: random permutation of [1000, 1000+n-1] Sublinear case: sorted unique numbers from [n, 100n] Note key range disjoint from index range
Discourage “cheating”
1539
117118123…560
…
minN=2
maxN=100
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 19
Fitness Function Define error per single key search as the distance
between the correct index of KEY and the index returned by search(arr,KEY)
Elements are unique No ambiguity in error definition
1718233460arr =key = 18
correct search(arr,key)
error=2
01234
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 20
Fitness Function Define hit as the finding of the precise location of KEY
1718233460arr =key = 18
correct search(arr,key)
error=0
01234
Hit !
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 21
Fitness Function The fitness value of an individual is defined as:
This gives a 0.5% bonus reduction for every 1% of correct hits For example, if an individual scored 300 hits in 1000 search calls,
its fitness will be the average error per call, reduced by 15%
This bonus encourages perfect answers (“almost” is bad…), increases fitness variation in population
calls
hitserroraveragefitness 5.01 _
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 22
Generality Test The best solution of each run was subjected to a stringent
generality test, by running it on random arrays of all lengths in the range [2, 5000] ([2, 500] for linear case).
Kinnear (1993) noted that:“For any algorithm... that operates on an infinite domain of data, no amount of testing can ever establish generality. Testing can only increase confidence.”
We included analysis by hand for selected solutions.
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 23
GP Operators and Parameters
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 24
Agenda
Introduction Evolutionary Setup Results Less Knowledge – More Automation Related Work Conclusions and Future Work
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 25
Results - Linear It turned out that evolving a linear-time search algorithm
was quite easy with the function and terminal sets we designed.
46 out of 50 runs (92%) produced perfect solutions, passing the generality testing of arrays up to length 500.
Our representation rendered the problem easy enough for a perfect individual to appear in the randomly generated generation 0 in three of the runs.
Search space was small enough for random search.
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 26
Results - Linear An example evolved solution:
LISP:
(If (= Array[INDEX] KEY) (M1:= [M0+M1]/2) INDEX:= ITER)))
If
=
Array[INDEX]
KEY
M1:=
[M0+M1]/2
INDEX:=
ITER
if (arr[INDEX] == KEY) M1 = (M0+M1)/2;else INDEX = ITER;
Equivalent Java:
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 27
Results - Linear An example evolved solution:
public static int search(int[] arr, int KEY) { int n = arr.length; int M0 = 0; int M1 = n-1; int INDEX = 0; for (int ITER = 0; ITER < iterations; ITER++) { if (arr[INDEX] == KEY) M1 = (M0+M1)/2; else INDEX = ITER; } return INDEX;}
Irrelevant but does not effect output index
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 28
Sublinear Search We set iterations to log2n,
and proceeded to evolve sublinear search algorithms.
public static int search(int[] arr, int KEY) { int n = arr.length; int M0 = 0; int M1 = n-1; int INDEX = 0;
for (int ITER = 0; ITER < iterations; ITER++) { -> PLUG IN EVOLVING GENOTYPE HERE <- } return INDEX;}
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 29
Results - Sublinear Unsurprisingly, this case proved a harder problem, but it
was also solved by the evolution. 35 out of 50 runs (70%) produced perfect solutions,
passing the generality testing of arrays up to length 5,000.
Solutions emerged between generation 22 and 3,632 Solution sizes varied between 42 and 244 nodes
Runtime: between 2 hours and 2 days on CS grid 7 runs (14%) produced near-perfect solutions, which failed on a
single key in the input arrays (99.96% hits on the generality test)
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 30
Results – Sublinear An example simplified evolved solution:
LISP: Equivalent Java:
Simplified by hand from a tree of 50 nodes down to 14
(PROGN2 (INDEX:= [M0+M1]/2) (If (> KEY Array[INDEX]) (PROGN2 (M0:= [M0+M1]/2) (INDEX:= M1)) (M1:= [M0+M1]/2))))
INDEX = (M0+M1)/2 ;if (KEY > arr[INDEX]){ M0 = (M0+M1)/2 ; INDEX = M1;}else M1 = (M0+M1)/2 ;
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 31
Results - Sublinearpublic static int search(int[] arr, int KEY) { int n = arr.length; int M0 = 0; int M1 = n-1; int INDEX = 0; for (int ITER = 0; ITER < iterations; ITER++) { INDEX = (M0+M1)/2 ; if (KEY > arr[INDEX]){ M0 = (M0+M1)/2 ; INDEX = M1; } else M1 = (M0+M1)/2 ; } return INDEX;}
This is a form ofBinary Search
(with a small twist)
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 32
Agenda
Introduction Evolutionary Setup Results Less Knowledge – More Automation Related Work Conclusions and Future Work
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 33
Less Knowledge – More Automation
Re-examining representation: Most terminals and functions are either
General-purpose or Problem-specific
However, one terminal stands out: [M0+M1]/2 Solution-specific
We proceed to Remove [M0+M1]/2 terminal Add an automatically defined function (ADF)
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 34
Adding ADFPROGN2
INDEX:=
Array[INDEX]
>
KEY
M0:= M1:=
M1M0
INDEX
< =
ITER
TRUE FALSENOP
[M0+M1]/2
INDEX:=
PROGN2PROGN2
INDEX:=
Array[INDEX]
KEY
M0:= M1:=
M1
[M0+M1]/2
>
If [M0+M1]/2[M0+M1]/2If ADF0
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 35
Adding ADFPROGN2
INDEX:=
Array[INDEX]
>
KEY
M0:= M1:=
M1M0
INDEX
< =
ITER
TRUE FALSENOP
INDEX:=
PROGN2PROGN2
INDEX:=
Array[INDEX]
KEY
M0:= M1:=
M1
>
IfIf ADF0
-
ADF0
ADF Functions & Terminals
+
*
/ 0 1
2
M0
M1
+ /
- *
1 M0
M1
ADF0ADF0
TRUE
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 36
GP Parameters – with ADF Array size was increased to:
minN = 200 maxN = 300
To avoid non-general solutions example to follow
Different function set for main and ADF trees Crossover is tree-wise
Mutation performed better than crossover Especially for ADF tree
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 37
GP Parameters – with ADF Same as previous setup, with the following changes:
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 38
Results – Sublinear with ADF The sublinear search problem with an ADF naturally proved
more difficult than with the [M0+M1]/2 terminal 12 out of 50 runs (24%) produced perfect solutions,
passing the generality testing of arrays up to length 5,000 (later passed all test up to size 20,000)
Solutions emerged between generation 54 and 4,557 Solution sizes varied between 53 and 244 nodes
Runtime: between 4 hours and 2 weeks on CS grid
An additional run produced a non-standard solution – will be discussed later
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 39
Results – Sublinear with ADF Analysis revealed all perfect solutions to be variations of
binary search
The algorithmic idea can be deduced by inspecting the ADFs, all of which turned out to be equivalent to one of the following (all fractions truncated):
which are reminiscent of the [M0+M1]/2 terminal we dropped
(M0+M1)/2 (M0+M1+1)/2 M0/2+(M1+1)/2
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 40
Results – Sublinear with ADF An example simplified evolved solution:
LISP: Equivalent Java:
Simplified by hand from a tree of 58 nodes down to 26
(PROGN2 (PROGN2 (if (< Array[INDEX] KEY) (INDEX:= ADF0) NOP) (if (< Array[INDEX] KEY) (M0:= INDEX) (M1:= INDEX))) (INDEX:= ADF0)))
ADF0:(/ (+ (+ 1 M0) M1) 2)
if (arr[INDEX] < KEY) INDEX = ((1+M0)+M1)/2;if (arr[INDEX] < KEY) M0 = INDEX;else M1 = INDEX;INDEX = ((1+M0)+M1)/2;
(Before simplification: slide 60)
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 41
Results – Sublinear with ADFpublic static int search(int[] arr, int KEY) { int n = arr.length; int M0 = 0; int M1 = n-1; int INDEX = 0; for (int ITER = 0; ITER < iterations; ITER++) { if (arr[INDEX] < KEY) INDEX = ((1+M0)+M1)/2; if (arr[INDEX] < KEY) M0 = INDEX; else M1 = INDEX; INDEX = ((1+M0)+M1)/2; } return INDEX;}
This is another form ofBinary Search
(with a different twist)
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 42
Interesting Results
Interesting to mention some of the other evolved solutions With minN=2, maxN=100 and main-tree max-depth = 17
linear search algorithms had evolved, failing on longer arrays
How is this possible (in log2n iterations)? An O(logn) solution has a constant factor, i.e. algorithm
does klogn operations. We set a limit to number of iterations, where each iteration
the full genotype code is executed. A linear search could evolve, by taking advantage of the
constant factor k
1718233460636775798287889296
Skip to next solution
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 43
Interesting Results
Linear solution ADF: ADF0=(M0+1) Main tree included 16 occurrences of:
For array of size n=100: logn=7, for k=16: klogn=167>100 (enough to traverse all the array)
We proceeded to increase minN, maxN (to 200, 300), decrease maximum k, by lowering max-depth to 10
(If (= Array[INDEX] KEY) NOP (PROGN2 (M0:= ADF0) (INDEX:= M0)))
If key is found, do nothing
else increment INDEX by 1
1718233460636775798287889296
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 44
Interesting Results
One more interesting solution has evolved Returns correct results (100% hits) up to array length ~6,640
Analyzing it revealed an interesting algorithm
which makes a series of jumps in exponentially increasing size in the form of 2i from 1 to 256 every iteration
Thus was able to handle array sizes n such that (roughly), n ≤ 512 x log2n n ≤ 6656
1718233460636775798287889296
1248256 ….
Skip
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 45
Interesting Results
ADF0 = 2*M1-M0-1 Main tree included 7-8 occurrences similar to:
Difference grows by factor of 2
(PROGN2 (if (> Array[INDEX] KEY) (M1:= ADF0) NOP) (INDEX:= ADF0))
M1 2*M1-M0-1
M1’ 2*M1 -M0-1
M1’’ 2*M1’ -M0-1------------------M1’’-M1’ = 2(M1’-M1)
1718233460636775798287889296
1248256 ….
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 46
Agenda
Introduction Evolutionary Setup Results Less Knowledge – More Automation Related Work Conclusions and Future Work
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 47
Related Work No previous work on evolving list search algorithms
“Closest”: sorting algorithms Loosely related – in both cases, solutions have to be 100% correct
We found 10-15 works on evolving sorting algorithms
Most works have been able to evolve O(n2) sorting algorithms One work evolved an O(nlogn) algorithm
albeit with a highly specific setup
Skip
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 48
Related Work Kinnear (1993) evolved an O(n2) bubble sort using koza-style
GP. He tried a number of function sets, all quite specific, including
double-for, swap, who-is-bigger functions
Showed that the difficulty in evolving a solution increases as the functions become less problem-specific (order x y) vs. (if-lt x y work) and (swap x y)
Noted that adding parsimony increased likelihood of evolving a general solution
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 49
Related Work Withall et. al. (2009) developed a new GP representation
fixed-length blocks of genes, representing single program statements. The phenotype is a PERL program.
They showed improvement over previous linear-GP representations, in similarity between child and parent, i.e, propagation of characteristics (building blocks) through multiple generations.
A number of list algorithms were evolved sum-of-elements, max-element, reverse, sort using problem-specific functions for each algorithm
Functions included for loop function double function – a highly specific double-for nested loop.
With these specialized structures they evolved an O(n2) bubble sort algorithm.
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 50
Related Work An O(nlogn) solution was evolved by Agapitos et. al. (2006-7)
The evolutionary setup was based on their object-oriented genetic programming system.
They compared five different fitness functions based on various measures of array disorder.
To avoid non-terminating programs they defined an upper bound on recursive calls, based on their hand-coded implementation.
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 51
Related Work In original work (2006), set up two recursive configurations:
Sort-Filter – with a hand-tailored filter function in the function set. evolved an approximated O(nlogn) solution
Sort-ADF – with a general static ADF evolved an approximated O(n2) solution
Runtime evaluated empirically as the number of method invocations
In later work (2007) defined Evolvable Class which contains Evolvable Methods that may call each other. Increased search space An O(n2) modular recursive solution was evolved
Agapitos et al. noted that mutation performed better than crossover in their problem domain We noticed this as well for the setup with ADF
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 52
Agenda
Introduction Evolutionary Setup Results Less Knowledge – More Automation Related Work Conclusions and Future Work
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 53
Conclusions We showed that algorithmic design of efficient list search
algorithms is possible. high-level fitness function
encouraging correct answers within a given number of iterations
Linear search was very simple with our setup.Sublinear much more challenging.
Knuth (The Art of Computer Programming): “Although the basic idea of binary search is comparatively
straightforward, the details can be somewhat tricky, and many good programmers have done it wrong the first few times they tried.”
Evolution produced many variations of correct binary search, and some nearly-correct solutions erring on a mere handful of extreme cases (which one might expect, according to Knuth).
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 54
Future Work We would like to explore the coevolution of individual main
trees and ADFs, as in the work of Ahluwalia (2001) Our phenotypes are not Turing complete
e.g., because they always halt. It would be interesting to use a Turing-complete GP system to
evolve search algorithms.
We also plan to delve into related areas interpolation search
Understanding and simplifying solutions Tree Alignment algorithms Joint work with Michal Ziv-Ukelson and Shay Zakov
Ultimately, we wish to find an algorithmic innovation not yet invented by humans.
example
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 55
Thank You!
Questions?
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 56
BACKUP
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 57
Evolved solution before simplification w/ ADF (run #1001):Size: 245 nodes
(for ITER=0..MAX, do (PROGN2 (PROGN2 (PROGN2 (PROGN2 (PROGN2 (INDEX:= ADF0) (PROGN2 (INDEX:= ADF0) NOP)) (if (> Array[INDEX] KEY) (PROGN2 (M1:= ADF0) (INDEX:= ADF0)) (INDEX:= KEY))) (PROGN2 (if (> Array[INDEX] KEY) (PROGN2 (PROGN2 NOP (M1:= ADF0)) (PROGN2 (INDEX:= Array[INDEX]) (INDEX:= ADF0))) NOP) (if (> Array[INDEX] KEY) (if (> Array[INDEX] KEY) (PROGN2 (M1:= ADF0) (INDEX:= ADF0)) (INDEX:= ADF0)) NOP))) (PROGN2 (PROGN2 (if (> Array[INDEX] KEY) (PROGN2 (M1:= ADF0) (INDEX:= ADF0)) NOP) (if (> Array[INDEX] KEY) (PROGN2 (M1:= ADF0) (PROGN2 (INDEX:= ADF0) NOP)) NOP)) (PROGN2 (if (> Array[INDEX] KEY) (PROGN2 (PROGN2 NOP (M1:= ADF0)) (PROGN2 (INDEX:= ITER) (if FALSE NOP NOP))) (PROGN2 (INDEX:= ADF0) (INDEX:= ITER))) (if FALSE (PROGN2 (M1:= ADF0) (INDEX:= ADF0)) (if (= KEY Array[INDEX]) (M1:= INDEX) (INDEX:= ITER)))))) (PROGN2 (PROGN2 (PROGN2 (INDEX:= ADF0) (if (> Array[INDEX] KEY) (PROGN2 (PROGN2 NOP (M1:= ADF0)) (PROGN2 (INDEX:= ADF0) (PROGN2 NOP NOP))) (if (= KEY Array[INDEX]) (PROGN2 (PROGN2 NOP NOP) NOP) (M0:= ADF0)))) (PROGN2 (if (> Array[INDEX] KEY) (PROGN2 (M1:= ADF0) (PROGN2 (INDEX:= ADF0) (PROGN2 NOP NOP))) NOP) (if (> Array[INDEX] KEY) (PROGN2 (M1:= ADF0) (PROGN2 (INDEX:= ADF0) NOP)) NOP))) (PROGN2 (PROGN2 (if (> Array[INDEX] KEY) (PROGN2 (PROGN2 NOP (M1:= ADF0)) (PROGN2 (INDEX:= ADF0) (if TRUE NOP NOP))) NOP) (if (> Array[INDEX] KEY) (PROGN2 (M1:= ADF0) (INDEX:= ADF0)) NOP)) (PROGN2 (if (> Array[INDEX] KEY) (PROGN2 (PROGN2 NOP (M1:= ADF0)) (PROGN2 (INDEX:= ITER) (if FALSE NOP NOP))) (INDEX:= ADF0)) (if (> Array[INDEX] KEY) (PROGN2 (INDEX:= ITER) NOP) (if (= KEY Array[INDEX]) (M1:= INDEX) (INDEX:= M1))))))))
ADF0:(- M1 (/ (- M1 M0) 2))
(for ITER=0..MAX, do (PROGN2 (PROGN2 (PROGN2 (PROGN2 (PROGN2 (INDEX:= ADF0) (PROGN2 (INDEX:= ADF0) NOP)) (if (> Array[INDEX] KEY) (PROGN2 (M1:= ADF0) (INDEX:= ADF0)) (INDEX:= KEY))) (PROGN2 (if (> Array[INDEX] KEY) (PROGN2 (PROGN2 NOP (M1:= ADF0)) (PROGN2 (INDEX:= Array[INDEX]) (INDEX:= ADF0))) NOP) (if (> Array[INDEX] KEY) (if (> Array[INDEX] KEY) (PROGN2 (M1:= ADF0) (INDEX:= ADF0)) (INDEX:= ADF0)) NOP))) (PROGN2 (PROGN2 (if (> Array[INDEX] KEY) (PROGN2 (M1:= ADF0) (INDEX:= ADF0)) NOP) (if (> Array[INDEX] KEY) (PROGN2 (M1:= ADF0) (PROGN2 (INDEX:= ADF0) NOP)) NOP)) (PROGN2 (if (> Array[INDEX] KEY) (PROGN2 (PROGN2 NOP (M1:= ADF0)) (PROGN2 (INDEX:= ITER) (if FALSE NOP NOP))) (PROGN2 (INDEX:= ADF0) (INDEX:= ITER))) (if FALSE (PROGN2 (M1:= ADF0) (INDEX:= ADF0)) (if (= KEY Array[INDEX]) (M1:= INDEX) (INDEX:= ITER)))))) (PROGN2 (PROGN2 (PROGN2 (INDEX:= ADF0) (if (> Array[INDEX] KEY) (PROGN2 (PROGN2 NOP (M1:= ADF0)) (PROGN2 (INDEX:= ADF0) (PROGN2 NOP NOP))) (if (= KEY Array[INDEX]) (PROGN2 (PROGN2 NOP NOP) NOP) (M0:= ADF0)))) (PROGN2 (if (> Array[INDEX] KEY) (PROGN2 (M1:= ADF0) (PROGN2 (INDEX:= ADF0) (PROGN2 NOP NOP))) NOP) (if (> Array[INDEX] KEY) (PROGN2 (M1:= ADF0) (PROGN2 (INDEX:= ADF0) NOP)) NOP))) (PROGN2 (PROGN2 (if (> Array[INDEX] KEY) (PROGN2 (PROGN2 NOP (M1:= ADF0)) (PROGN2 (INDEX:= ADF0) (if TRUE NOP NOP))) NOP) (if (> Array[INDEX] KEY) (PROGN2 (M1:= ADF0) (INDEX:= ADF0)) NOP)) (PROGN2 (if (> Array[INDEX] KEY) (PROGN2 (PROGN2 NOP (M1:= ADF0)) (PROGN2 (INDEX:= ITER) (if FALSE NOP NOP))) (INDEX:= ADF0)) (if (> Array[INDEX] KEY) (PROGN2 (INDEX:= ITER) NOP) (if (= KEY Array[INDEX]) (M1:= INDEX) (INDEX:= M1))))))))
back
Evolutionary Computation and Aritficial Life (ECAL) cousre - CS BGU - July 8th, 2009 58
Evolved solution before simplification w/ ADF (run #1020):Size: 58 nodes
Tree 0: (for ITER=0..MAX, do (PROGN2 (PROGN2 (if (< Array[INDEX] KEY) (INDEX:= ADF0) (if FALSE (if FALSE NOP (INDEX:= ITER)) NOP))...
... (if (< Array[INDEX] KEY) (if FALSE (M1:= INDEX) (M0:= INDEX)) (PROGN2 (PROGN2 (if TRUE (M1:= INDEX) NOP) (if FALSE NOP (INDEX:= ITER))) (if (< Array[INDEX] KEY) (INDEX:= ADF0) (if FALSE (INDEX:= ITER) NOP)))))(INDEX:= ADF0)))
ADF0:(/ (+ (+ 1 M0) M1) 2)