/// <summary> /// Apply random mutation using a mutation factor, default is 0.01 /// </summary> public Gene Mutate(Gene gene, float mutationFactor = 0.01f) { var backup = new Gene(gene); for (int i = 0; i < gene.Count; i++) { var mutate = Utility.CheckProbability(mutationFactor); if (mutate) { var randomType = Utility.GetRandomAction(); Action action = null; switch (randomType) { case ActionType.Move: action = new MoveAction(); break; case ActionType.Turn: action = new TurnAction(); break; case ActionType.Look: action = new LookAction(_objectiveAgent, _escapeAgent); break; } gene[i] = action; } } //discard mutation if not valid return(!gene.IsValid() ? backup : gene); }
/// <summary> /// Returns the offspring genes resulting from a single point crossover chosen at random /// </summary> public Gene[] SinglePointCrossover(Gene parent1, Gene parent2) { var crossoverPosition = UnityEngine.Random.Range(0, _geneSize); var offspring1 = new List <Action>(); var offspring2 = new List <Action>(); for (int chromosome = 0; chromosome < _geneSize; chromosome++) { var p1 = parent1[chromosome]; var p2 = parent2[chromosome]; var swap = crossoverPosition >= chromosome; if (swap) { offspring2.Add(p1); offspring1.Add(p2); } else { offspring1.Add(p1); offspring2.Add(p2); } } var child1 = new Gene(offspring1); var child2 = new Gene(offspring2); if (!child1.IsValid() || !child2.IsValid()) { return(SinglePointCrossover(parent1, parent2)); } return(new Gene[] { child1, child2 }); }
/// <summary> /// Returns 2 offsprings using Uniform UniformCrossover, by default using 0.5 ratio /// </summary> public Gene[] UniformCrossover(Gene parent1, Gene parent2, float crossoverRatio = 0.5f) { var offspring1 = new List <Action>(); var offspring2 = new List <Action>(); for (int chromosome = 0; chromosome < _geneSize; chromosome++) { var p1 = parent1[chromosome]; var p2 = parent2[chromosome]; var swap = Utility.CheckProbability(crossoverRatio); if (swap) { offspring2.Add(p1); offspring1.Add(p2); } else { offspring1.Add(p1); offspring2.Add(p2); } } var child1 = new Gene(offspring1); var child2 = new Gene(offspring2); if (!child1.IsValid() || !child2.IsValid()) { return(UniformCrossover(parent1, parent2, crossoverRatio)); } return(new Gene[] { child1, child2 }); }