CS 1103-01 - AY2023-T2 - Lab 7 Unit 4

Download as pdf or txt
Download as pdf or txt
You are on page 1of 5

12/3/22, 4:19 PM CS 1103-01 - AY2023-T2: Lab 7 Unit 4

CS 1103-01 Programming 2 - AY2023-T2


Dashboard / My courses / CS 1103-01 - AY2023-T2 / 1 December - 7 December / Lab 7 Unit 4

Lab 7 Unit 4

Lab 7: Genetic Programming

The lab for this week is a continuation of last week's lab. (You probably want to save a copy of the work that you did for that lab before you
start modifying it.) The programming will be rather complicated.

Last week, you generated random expressions and tested them to see how closely they would reproduce a set of sample data. Essentially,
you were doing a random search through the space of all possible expressions and keeping track of the best one that you happened to find.
For many problems, there is a better way to search for a solution in a very large space of possible solutions. The genetic algorithm imitates
some ideas from biological evolution to search more effectively than a purely random search. In outline, the genetic algorithm works like this:

1. Choose the initial population (by creating random individuals).


2. Evaluate the fitness of each individual in the population.
3. Repeat until termination: (time limit or sufficient fitness achieved)

a. Select best-ranking individuals to reproduce.


b. Breed the new generation through crossover and/or mutation (genetic operations) to create offspring.
c. Evaluate the individual fitnesses of the offspring.
d. Replace lower-ranked part of the population with offspring.

Mutation refers to making some random change to one individual. Crossover means combining parts (or traits) of two individuals to produce
a new individual. The genetic algorithm does not work well for all problems, but for some, it can give much better results than a random
search.

Two files of sample output from others’ implementations of this program are available in the code directory: For the first file, the genetic
algorithm ran for a large number of generations; every time a new best expression was found, I output the generation number, RMS error,
and the expression. For the second file, the random search algorithm was compared to the genetic programming search: Each algorithm was
allowed to run for 60 seconds, then the best RMS error and expression were printed out. That process was repeated, keeping track of the
average best fitness for both algorithms.

An old Genetic Algorithms demonstration applet can be found at http://math.hws.edu/xJava/GA.

Genetic programming is a variant of the genetic algorithm in which the individuals that are being evolved are computer programs, and their
fitness is determined by how well they perform some specified task. Genetic programming often works with the LISP programming language,
which has a particularly simple syntax. LISP programs can be represented as a certain kind of tree, and almost any such tree is a syntactically
legal program. There are fairly easy ways to do mutation and crossover on trees. For mutation, just take a random node in the tree and make
some random changes to it. To do a crossover between individuals A and B, pick random branches in A and B, and swap the selected branch
in A with the selected branch in B.

Although we aren't working with LISP programs, our expressions can be thought of as a simple kind of program, and we can try to apply

https://my.uopeople.edu/mod/page/view.php?id=328386 1/5
12/3/22, 4:19 PM CS 1103-01 - AY2023-T2: Lab 7 Unit 4

genetic programming to them. This is an experimental lab. You cannot predict what results you will get, and your results will depend
very much on the details of your implementation. There are many ways to "tune" a genetic algorithm, and many decisions to be
made. You will just have to see what happens.

Here are some ideas. You will find that you need to be able to sort an array of expressions according to their fitness values. (The fitness here
is the RMSError.) In order to do this, it's useful to store the computed fitness value along with the expression. For this, you can use a class:

static class Individual {


ExpNode exp;
double fitness;
}

The population is then an array of individuals, and you can use the following methods to sort the array into an order of increasing fitness by
calling quickSort(population, 0, population.length-1). (This assumes that none of the individuals have fitness that is infinite or NaN.)

static void quickSort(Individual[] array, int lo, int hi) {


int mid = quickSortStep(array, lo, hi);
if (mid - 1 > lo)
quickSort(array, lo, mid - 1);
if (mid + 1 < hi)
quickSort(array, mid + 1, hi);
}

static int quickSortStep(Individual[] array, int lo, int hi {


Individual temp = array[lo];
while (true) {
while (hi > lo && array[hi].fitness > temp.fitness)
hi--;
if (hi == lo)
break;
array[lo] = array[hi];
lo++;
while (hi > lo && array[lo].fitness < temp.fitness)
lo++;
if (hi == lo)
break;
array[hi] = array[lo];
hi--;
}
array[lo] = temp;
return lo;
}

Here is an outline of one way to implement the algorithm, using a population size of 1000. (The population size would be a constant in your
program.) Make an array that is big enough to hold two or three times as many individuals as the population size (because you will be
discarding some after breeding). Fill the first 1000 spaces in the array with randomly created expressions, and compute their fitnesses,
making sure that the fitness is an actual number (that does not satisfy Double.isNaN(fitness) || Double.isInfinite(fitness)).

You will then go into the basic evolutionary loop: Breed the individuals in locations 0 through 999 of the array to fill the rest of the array. To
do this, choose two random individuals for that range. Do a crossover between those two individuals. Then possibly apply mutation to the
new individuals. (Too much mutation can be bad. You can experiment with the mutation probability.) Compute each new individual's fitness
and place it into the array, but only if its fitness is an actual number. (You might also find it necessary to throw away individuals that have

https://my.uopeople.edu/mod/page/view.php?id=328386 2/5
12/3/22, 4:19 PM CS 1103-01 - AY2023-T2: Lab 7 Unit 4

gotten too complex, to avoid having really huge expressions. To implement this, you can add a height() function to ExpNodes to compute the
height of the expression.) Once you've filled the array, you can sort the array by fitness, so the fittest individuals are in the first part of the
array. The next time through the loop, you will only use the first 1000 individuals for reproduction, and you will replace the other individuals
in the array, which are less fit.

The hardest part is probably implementing mutation and crossover. There are several ways to implement this. For example... For mutation,
you can select a random node in the expression and modify it. You can do this recursively: For constant nodes, you can change the constant;
for operator nodes, you can change the operator or you can mutate one of the operands (or possibly even replace one of the operands with
an entirely new random expression); and for variable nodes, you really can't do anything to mutate them. For crossover of two expressions,
you could randomly select an operator node from each expression, and swap one of the operands of one node with one of the operands of
the other node. If an expression has no operator nodes, you can't really do a crossover with it.)

The following functions could be used to test your mutate and crossover functions:

static void testMutate() {


int changed = 0;
int unchanged = 0;
for (int i = 0; i < 100; i++) {
ExpNode e = randomExpression(6);
ExpNode f = copy(e);
System.out.println(e);
mutate(f);
System.out.println(f);
System.out.println(f.equals(e) ? "equal" : "changed");
System.out.println();
if (f.equals(e))
unchanged++;
else
changed++;
}
System.out.println(changed + " changed; " + unchanged + " unchanged");
}

static void testCrossover() {


int changed1 = 0, changed2 = 0;
for (int i = 0; i < 100; i++) {
ExpNode e1 = randomExpression(6);
ExpNode e2 = randomExpression(6);
ExpNode f1 = copy(e1);
ExpNode f2 = copy(e2);
cross(e1,e2);
System.out.println(f1);
System.out.println(f2);
System.out.println(e1);
System.out.println(e2);
System.out.println();
if (!e1.equals(f1))
changed1++;
if (!e2.equals(f2))
changed2++;
}
System.out.println("crossover changed first expreesion " + changed1 + " times");
System.out.println("crossover changed second expreesion " + changed2 + " times");
}

https://my.uopeople.edu/mod/page/view.php?id=328386 3/5
12/3/22, 4:19 PM CS 1103-01 - AY2023-T2: Lab 7 Unit 4

For the ".equals" tests to work properly, you have to define the equals method in all your classes. Like toString, the equals method is defined
in class Object, where it is just defined to do the same comparison as "==". Classes often need to redefine the equals method. For example,
here is the equals method from my BinOpNode class:

public boolean equals(Object o) {


return (o instanceof BinOpNode)
&& ((BinOpNode)o).op == op
&& ((BinOpNode)o).left.equals(left)
&& ((BinOpNode)o).right.equals(right);
}

In the previous lab, the expression that was used to make the test data was fairly easy for a random process to guess, especially if you made
your random expressions with integers. To make it harder, you could change "double y = 2.5*x*x*x - x*x/3 + 3*x;" to "double y = 2.5345*x*x*x
- x*x/3.112009 + 3.237*x;" or something even messier.

Last modified: Wednesday, 13 May 2020, 1:13 PM

UoPeople Clock (GMT-5)

All activities close on Wednesdays at 11:55 PM, except for Learning Journals/Portfolios which close on Thursdays at 11:55 PM always
following the clock at the top of the page.

Due dates/times displayed in activities will vary with your chosen time zone, however you are still bound to the 11:55 PM GMT-5
deadline.

◄ Code Unit 4

Jump to...

Lab 8 Unit 4 ►

Disclaimer Regarding Use of Course Material - Terms of Use


University of the People is a 501(c)(3) not for profit organization. Contributions are tax deductible to the extent permitted by law.
Copyright © University of the People 2021. All rights reserved.

You are logged in as Thin San (Log out)


 www.uopeople.edu


 
 
 
 

Resources
UoPeople Library
Orientation Videos
LRC
Syllabus Repository
Career Resource Center
Honors Lists
Links
About Us

https://my.uopeople.edu/mod/page/view.php?id=328386 4/5
12/3/22, 4:19 PM CS 1103-01 - AY2023-T2: Lab 7 Unit 4

Policies
University Catalog
Support
Student Portal
Instructors
Instructor Portal
CTE Center for Teaching Excellence
Office 365
Tipalti
Contact us
English (‎en)‎
English (‎en)‎
‫ العربية‬‎(ar)‎

Data retention summary


Get the mobile app

https://my.uopeople.edu/mod/page/view.php?id=328386 5/5

You might also like