public void CrossOver(int count, double percent) // 교차 { int lastCount = Populations.Count; for (int i = 0; i < count; i++) { Move_Chromosome chromoA = Populations[MathLibrary.Random.Range(lastCount)]; Move_Chromosome chromoB = Populations[MathLibrary.Random.Range(lastCount)]; Move_Chromosome newChromo = new Move_Chromosome(chromosome_genes); for (int j = 0; j < chromosome_genes; j++) { if (MathLibrary.Random.NextBoolean(percent)) { newChromo[j] = chromoA[j]; } else { newChromo[j] = chromoB[j]; } } Populations.Add(newChromo); } Populations.RemoveRange(0, lastCount); }
public void Mutation(double percent, int mutationMin, int mutationMax, int rangeMin, int rangeMax) // 변이 { for (int i = 0; i < Populations.Count; i++) { Move_Chromosome chromo = Populations[i]; for (int j = 0; j < chromosome_genes; j++) { if (MathLibrary.Random.NextBoolean(percent)) { while (true) { int mutation_num = MathLibrary.Random.Range(mutationMin, mutationMax); if ((chromo[j] + mutation_num) >= 0 && (chromo[j] + mutation_num) < 6) { print("변이 시작"); chromo[j] += MathLibrary.Random.Range(mutationMin, mutationMin); chromo[j] = Math.Max(Math.Min(chromo[j], rangeMax), rangeMin); break; } } } } } }
void DoGenetic() // 유전알고리즘 실행 { double bestFitness = 0; // 최적의 형태 Move_Chromosome bestChromo = null; // 최적의 초기값 상태 int enemy_populations = 20; //print("총 적 인원 : " + enemy_populations); for (int i = 0; i < enemy_populations; i++) // 소환하는 적 수만큼 반복 { //print("적 번호 : " + i); //print("creatures 배열 개수:" + creatures.Count); Creature_enemy creature = creatures[i]; // i번 적군의 이동 폼 지정 Move_Chromosome chromo = GC.Populations[i]; // i번째의 적 이동 폼 유전알고리즘 폼 지정 //print("chromo test : " + chromo.Genes[0]); chromo.Fitness = creature.GetFitness(); // i번째의 얼만큼 살아남았는지 지정 //print(i + "번째 적군 생존시간 : " + chromo.Fitness); //print("최고기록 : " + bestFitness); if (chromo.Fitness > bestFitness) // 지렁이의 제일 최적에 초기값을 구함 { //print("Chromo Fitness Debug : " + chromo.Fitness); bestFitness = chromo.Fitness; // 최적의 블록구조 움직임으로 나간 거리 bestChromo = chromo; // 최적의 블럭구조 움직임 초기 값 //print("best Chromo test : " + bestChromo.Fitness); } } stringBuilder.Length = 0; // 지렁이 몸통블록이 움직이는 순서값 초기화 if (bestChromo.Genes.Length > 0 && bestChromo.Fitness != 0) { for (int i = 0; i < geneCount; i++) // 지렁이 몸통블록이 움직이는 순서값 입력 { //print("best Chromo : " + bestChromo[i]); stringBuilder.Append(bestChromo[i].ToString() + ','); } } string text = string.Format("Generation: {0} - Best: {1:F2}\r\nGene: {2}", GC.Generation, bestFitness, stringBuilder.ToString()); // 현재 세대 수, 최적의 블록 움직임으로 나간 거리, 최적의 블록 움직임 순서 statusText.text = text; // 상태 텍스트에 설정 Debug.Log(text); // 상태 출력 GC.Select(6); // 적합도 선정 GC.CrossOver(enemy_populations, 0.5); // 교차 GC.Mutation(0.01f, -2, 2, 0, 5); // 변이 GC.Generation++; // 다음 세대로 증가 ResetCreatures(); // 이전 데이터값 초기화 //print("유전 알고리즘 실행 끝"); }
private int RouletteWheel() // 적합도 계산 부분(룰렛 휠 선택 방법) { int selected = 0; double total = 0; for (int i = 0; i < Populations.Count; i++) // .Count : 해시 테이블에 들어있는 요소 수를 반환 { Move_Chromosome chromo = Populations[i]; //chromo.Fitness = GetRealFitness(minFitness, maxFitness, chromo.Fitness); total += chromo.Fitness; if (MathLibrary.Random.NextBoolean(chromo.Fitness / total)) { selected = i; } } print("선택한 번호:" + selected); return(selected); }