/// <summary> /// Tree_traverses the specified parent. /// </summary> /// <param name="parent">The parent.</param> /// <param name="start_point">The start_point.</param> /// <returns></returns> public int tree_traverse(Indevidual parent, int start_point) { //holds the trees legth from point given int counter = 1; int len = 1; for (int i = 0; len != 0; i++) { //add byte to sub tree1 array //subtree[i] = (byte)parent.Program[buffer]; counter++; start_point++; if (parent.Program[start_point] < Terminal_set_Start && parent.Program[start_point] > Terminal_set_End) { //if the node is a functional node then trase the sub tree if (parent.Program[start_point] >= Functional_set_Start && parent.Program[start_point] <= Functional_set_End) { len++; //increase the length } else if (parent.Program[start_point] == End) { len--; //decrease the length } } //if the node is a terminal node it will be //counted on the next loop round } return(counter); }
/// <summary> /// Selection_torniments the specified torniment_size. /// </summary> /// <param name="torniment_size">The torniment_size.</param> /// <returns></returns> public Indevidual selection_torniment(int torniment_size) { Random rnd = new Random(Guid.NewGuid().GetHashCode()); Indevidual best = null; //choose and indevidual at randome Indevidual first = Generation[rnd.Next(0, population_Size)]; //uses tornimnt size to search x number of indeviduals //increases selection pressure (higher pressure fitter indeviduals) //equivalent to copetitive challange for (int i = 0; i < torniment_size; i++) { //choose second randome indevidual to compare with Indevidual second = Generation[rnd.Next(0, population_Size)]; //if the first indevidual is fitter than the second //then return the first if (first.Fitness > second.Fitness) { best = first; } else { //else return the second best = second; } } gw.ListEventsAlgorithm.Add(":: Indevidual: " + best + " chosen through Torniment selection ::"); //return best Indevidual return(best); }
/// <summary> /// Setups this instance. /// </summary> public void setup() { //add to generation counter GenCounter++; gw.ListEventsAlgorithm.Add("::Genetic programming SETUP::"); gw.ListEventsAlgorithm.Add("::Generation: " + GenCounter + " ::"); //generate a generation of specified size for (int i = 0; i != population_Size; i++) { Indevidual ind = new Indevidual(); gw.ListEventsAlgorithm.Add(":: New Indevidual created for Generation ::"); Grow(); ind.TreeNo = i + 1; ind.Program = GrownProgram; ind.Tree = GetInterpTree(ind.Program); ind.TreeString = Draw_tree(ind.Program); gw.ListEventsAlgorithm.Add(":: indevidual " + treeCounter + " added to Generation ::"); //ind.Fitness = ; //will have to guage trees fitness treeCounter++; //add tree to inital generation Generation.Add(ind); } }
/// <summary> /// Fitness functions gives a tree its fitness rating. /// </summary> /// <param name="total_Damage">The total_ damage.</param> /// <param name="indevidual">The indevidual.</param> public void fitness_function(int total_Damage, Indevidual indevidual) { //here the fitness of an indevidual will be set // as the game intends to evaluate the AI's tree based on performace // this method will be used to update the fitnesses of the trees //in the list rather than evaluate them here directly int fitness = (total_Damage / indevidual.Program.Length); indevidual.Fitness = fitness; gw.ListEventsAlgorithm.Add(" ::Fitness calculated:: "); gw.ListEventsAlgorithm.Add(indevidual.ToString()); }
/// <summary> /// Sub_tree_or_node_selection from the specified parent. /// </summary> /// <param name="parent">The parent.</param> /// <param name="xoPoint">The xo point.</param> /// <param name="rnd">The random.</param> /// <param name="subtree">The subtree.</param> /// <returns></returns> public List <byte> sub_tree_or_node_selection(Indevidual parent, int xoPoint, Random rnd, List <byte> subtree) { //if the vale at that index is a functional node //then go about tracing the sub tree if (parent.Program[xoPoint] >= Functional_set_Start && parent.Program[xoPoint] <= Functional_set_End) { //lengh of the sub tree found int len = 1; subtree.Add((byte)parent.Program[xoPoint]); xoPoint++; for (int i = 0; len != 0; i++) { //if the node is a functional node then trase the sub tree if (parent.Program[xoPoint] >= Functional_set_Start && parent.Program[xoPoint] <= Functional_set_End) { subtree.Add((byte)parent.Program[xoPoint]); len++; //increase the length } else if (parent.Program[xoPoint] >= Terminal_set_Start && parent.Program[xoPoint] <= Terminal_set_End) { subtree.Add((byte)parent.Program[xoPoint]); } else if (parent.Program[xoPoint] == End) { subtree.Add((byte)parent.Program[xoPoint]); len--; //decrease the length } //add byte to sub tree1 array //subtree.Add((byte)parent.Program[xoPoint]); xoPoint++; } } else if (parent.Program[xoPoint] >= Terminal_set_Start && parent.Program[xoPoint] <= Terminal_set_End) { //if the node is a terminal node (leaf node) just add //it to the array subtree.Add(parent.Program[xoPoint]); } //return what has been selected return(subtree); }
/// <summary> /// Evolves the mating pool of this instance. /// </summary> public void evolve() { Indevidual parent1, parent2, childInd; gw.ListEventsAlgorithm.Add(":: Evolve ::"); for (int i = 0; i != population_Size; i++) { treeCounter++; //take from the current generation using torniment parent1 = selection_torniment(torniment_size); parent2 = selection_torniment(torniment_size); //based on the mutation rate //crossover byte[] child = crossover_subtree(parent1, parent2); //mutation child = mutation_bit_flip(child); //create new indevidual for the mating pool childInd = new Indevidual(); childInd.TreeNo = treeCounter; //childInd.Fitness childInd.Program = child; childInd.Tree = GetInterpTree(childInd.Program); childInd.TreeString = Draw_tree(childInd.Program); //add to the maiting pool mating_pool.Add(childInd); //crossover thouse in the mating pool and read to //generation for more evaluation } //add to the generation conter GenCounter++; //create a new list to copy the next generation into Generation = new List <Indevidual>(mating_pool); //clear mating pool mating_pool.Clear(); }
/// <summary> /// Crossover_subtrees the specified parent1. /// </summary> /// <param name="parent1">The parent1.</param> /// <param name="parent2">The parent2.</param> /// <returns>byte[] offspring</returns> public byte[] crossover_subtree(Indevidual parent1, Indevidual parent2) { //brings back length of list but take one away to access last element //(indexed from 0) int xoPoint1 = parent1.Program.Length - 1, //xoPoint1End, xoPoint2 = parent2.Program.Length - 1; //xoPoint2End; //byte[] //parent1start = new byte[], //subtree1 = null, //parent1end = null, //parent2start = null, //subtree2 = null; //parent2end = null; List <byte> parent1start = new List <byte>(), subtree1 = new List <byte>(), parent1end = new List <byte>(), parent2start = new List <byte>(), subtree2 = new List <byte>(), parent2end = new List <byte>(); Random rnd = new Random(Guid.NewGuid().GetHashCode()); //first random point is index of tree parent 1 //keep generating untill its not an end node for (int k = 0; parent1.Program[xoPoint1] == End; k++) { xoPoint1 = rnd.Next(1, parent1.Program.Length - 1); } //second random point is index of tree parent 2 //keep generating untill its not an end node for (int j = 0; parent2.Program[xoPoint2] == End; j++) { xoPoint2 = rnd.Next(1, parent2.Program.Length - 1); } //get first section of parent tree 1 //add it to first section array for (int i = 0; i != xoPoint1; i++) { parent1start.Add(parent1.Program[i]); } //collect the sub tree or node from parent 1 subtree1 = sub_tree_or_node_selection(parent1, xoPoint1, rnd, subtree1); //collect the sub tree or node from parent 2 subtree2 = sub_tree_or_node_selection(parent2, xoPoint2, rnd, subtree2); //get the last section from parent tree 1 //for offspring int point = (parent1start.Count + subtree1.Count); for (int i = point; i < parent1.Program.Length; i++) { parent1end.Add(parent1.Program[i]); //+1? to points } //create child of the right size byte[] child = new byte[parent1start.Count + subtree2.Count + parent1end.Count]; parent1start.CopyTo(child, 0); subtree2.CopyTo(child, parent1start.Count); parent1end.CopyTo(child, parent1start.Count + subtree2.Count); //add events to list gw.ListEventsAlgorithm.Add(":: Crossover Sub Tree / Node ::"); gw.ListEventsAlgorithm.Add(":: parent1: " + Draw_tree(parent1.Program) + " ::"); gw.ListEventsAlgorithm.Add(":: Mutation " + Draw_tree(parent2.Program) + " ::"); gw.ListEventsAlgorithm.Add(":: offspring: " + Draw_tree(child) + " ::"); return(child); }