I'm trying to write a genetic algorithm that will take a list of lists of reals in interval [0,1], my "starting population", "score" them according to a fitness function, append the mean and max of these results to a new list, then perform operations to modify the lists and apply the fitness function. This should be for at least 1000 iterations. The code below shows the best attempt I've made so far. First, the input
mystartpop=Table[RandomReal[{0, 1}, 71], 100];
then the algorithm
generator[startingpopulation_ (*e.g., mystartpop*), duration_ (*corresponds to the
listlength
of random reals -1, so in this case input is 70*)] := Module[
{fitnessmeanlist, fitnessmaxlist, i, pop, split, parents, family,
mutated, fitscoremax, fitscoremean},
i = 0;
fitnessmeanlist = {};
fitnessmaxlist = {};
pop[0] = startingpopulation;
split[i_] := split[i] = selectionGen[pop[i], duration];
parents[i_] := parents[i] = parentsGen[split[i], 2, 25];
family[i_] := family[i] = crossover[parents[i]];
mutated[i_] := mutated[i] = mutateChromosome[family[i], 0.025];
pop[i_] := pop[i] = mutated[i - 1];
fitscoremax[i] := fitscoremax[i] = score[#, 70] & /@ pop[i] // Max;
fitscoremean[i] :=
fitscoremean[i] = score[#, 70] & /@ pop[i] // Mean;
While[i < 10,
fitscoremax[i];
fitscoremean[i];
AppendTo[fitnessmaxlist, fitscoremax[i]];
AppendTo[fitnessmeanlist, fitscoremean[i]];
split[i];
parents[i];
family[i];
mutated[i];
i++
];
Return[{fitnessmaxlist, fitnessmeanlist}];
]
with the below output
{{-1.29383, fitscoremax$709196[1], fitscoremax$709196[2],
fitscoremax$709196[3], fitscoremax$709196[4], fitscoremax$709196[5],
fitscoremax$709196[6], fitscoremax$709196[7],
fitscoremax$709196[8], fitscoremax$709196[9]}, {-20.8473,
fitscoremean$709196[1], fitscoremean$709196[2],
fitscoremean$709196[3], fitscoremean$709196[4],
fitscoremean$709196[5], fitscoremean$709196[6],
fitscoremean$709196[7], fitscoremean$709196[8],
fitscoremean$709196[9]}}
Why are the fitscoremean and fitscoremax not evaluating for i>0? Is it because split[i], parents[i] etc. aren't working in the While loop? Any solutions are welcomed
EDIT: It seems from further testing that it is split[i] etc. that aren't working, though they work when I run them manually. In words, they should run like this: fitscoremean/max applies a fitness function to 100 lists of 71 reals, determining a fitness value for each, then returning the mean/max value
pop[i] assigns to pop the i-1th output of mutated, or in the 0th iteration it is mystartpop
split[i] returns the top 50% of lists from pop[i], according to their fitness score
parents[i] randomly matches 25 pairs of lists together, with the likelihood of their being selected for pairing determined by their fitness score (repetition is allowed between pairs)
family[i] is a crossover module which converts each list to a single binary string, and randomly chops and pastes it at a crossover point in the string with its paired string, e.g.
{1001001,0101010}
with crossover point at 3 returns
{1001010,0101001}
and finally returns a list including all crossover "children" and all "parents"
mutated[i] randomly changes digits (i.e. "flips" 1s to 0s and vice-versa) in these binary strings, according to a specified probability (e.g. 0.025) then converts lists back to 71 real number elements and returns these lists, which are the values for pop[i+1]
Any help to get this working, and speedily, is appreciated
fitscoremax[i_] := fitscoremax[i] = score[#, 70] & /@ pop[i] // Max
and similar for fitscoremean.; $\endgroup$