오늘은 교차작업을 하는 함수 crossover()와 돌연변이를 만드는 mutate()함수를 살펴 보겠습니다~~Yeah~~^^*
어머 근데!!
새파란 찬 바람을 불어 주는 동장군이 납신 아침이예요~^^*
겨울의 아침 느낌을 잠시 만끽하고~^^*
크리스마스 20일 남은 것을 설레어 하며~^^*
항가리 무곡으로 아침 스트레칭 하시며~^^* 잠시 쉬고 계셔요~~^^*
공부 정리해서 곧 돌아올게요~^^*
이제 몸이 좀 부드럽게 풀리셨나요~~^^* 그럼 이제 코딩 공부 시작해 볼게요~~^^* Yeah^^*
먼저 교차 작업을 살펴 보겠습니다~^^*
두 DNA 사의의 교차점을 무작위로 선정해 보려고 합니다.
(1) 무작위 수인 n을 교차점을 정하면~^^*
(2) n번째 보다 뒤에 있는 배열 요소에 자신의 DNA의 해당 내용을 넣고
(3) n번째까지 앞부분에 있는 배열 요소에 파트너의 DNA의 해당 내용을 넣어서
(4) child 의 DNA를 완성해 보는 거예요~^^*
그림으로 표현해 보자면요~~^^*

코드로 표현해 보자면요~^^*
crossover(partner) {
let child = new DNA(this.genes.length);
//새로운 DNA 클래스를 생성하여 변수 child에 저장합니다~^^*
let midpoint = floor(random(this.genes.length));
//0과 DNA 길이값 사이의 수를 무작위로 생성하여 정수부분을 변수 midpoint에 저장합니다.
//midpoint는 교차점 역할을 하겠네요~^^*
for (let i = 0; i < this.genes.length; i++) {
if (i > midpoint) child.genes[i] = this.genes[i];
else child.genes[i] = partner.genes[i];
//교차점 midpoint보다 뒷 부분은 this.genes[]의 해당내용을 저장하고
//교차점 midpoint까지 앞부분은 파트너의 해당 DNA내용을 저장합니다.
}
return child;
//완성된 child DNA를 return 반환 합니다.
}
이번엔 돌연변이 생성 작업을 하는 함수 mutate()를 살펴 볼까요~~^^*
미리 지정된 돌연변이률에 따라 child DNA에 돌연변이를 일으키는 것인데요~^^*
child의 DNA인 this,genes[ ]의 각 요소마다 돌연변이률을 적용해서 변이를 생성하면 어떨까요~^^*
이 작업은 코드를 먼저 살펴 보는 것이 이해하기 쉬울 것 같아요~^^*
let mutationRate;
function sepup() {
.
.
.
mutationRate = 0.01;
}
메인 파일인 sketch.js에서 글로벌 변수로 지정한 mutationRate를 클래스 DNA의 내장함수 mutate()에서 사용해 보겠습니다~^^*
mutate(mutationRate) {
for (let i = 0; i < this.genes.length; i++) {
if (random(1) < mutationRate) {
this.genes[i] = newChar();
}
//this.genes의 각 구성요소[i]에 대하여
//0에서 1 사이 수를 무작위로 생성하고, 그 값이 mutationRate보다 작으면
//새로운 character 글자를 무작위로 생성하여 저장합니다.
}
}

와우~^^* 어느덧 우리가 Genetic Algorithm의 대부분의 내용을 다 살펴 본 것 같아요~^^*
굵은 글씨체의 내용이 지금까지 우리가 Genetic Algorithm에 대해 살펴본 내용들이구요~^^*
가는 글씨체의 내용은 결과 평가와 보여주기 등의 작업을 하는 내용들이예요~~^^*
function newChar() {
let c = floor(random(63, 122));
if (c === 63) c = 32;
if (c === 64) c = 46;
return String.fromCharCode(c);
}
class DNA {
constructor(num) {
// The genetic sequence
this.genes = [];
this.fitness = 0;
for (let i = 0; i < num; i++) {
this.genes[i] = newChar(); // Pick from range of chars
}
}
getPhrase() {
return this.genes.join("");
}
calcFitness(target) {
let score = 0;
for (let i = 0; i < this.genes.length; i++) {
if (this.genes[i] == target.charAt(i)) {
score++;
}
}
this.fitness = score / target.length;
}
crossover(partner) {
let child = new DNA(this.genes.length);
let midpoint = floor(random(this.genes.length));
for (let i = 0; i < this.genes.length; i++) {
if (i > midpoint) child.genes[i] = this.genes[i];
else child.genes[i] = partner.genes[i];
}
return child;
}
mutate(mutationRate) {
for (let i = 0; i < this.genes.length; i++) {
if (random(1) < mutationRate) {
this.genes[i] = newChar();
}
}
}
}
class Population {
constructor(p, m, num) {
this.population;
this.matingPool;
this.generations = 0;
this.finished = false;
this.target = p;
this.mutationRate = m;
this.perfectScore = 1;
this.best = "";
this.population = [];
for (let i = 0; i < num; i++) {
this.population[i] = new DNA(this.target.length);
}
this.matingPool = [];
this.calcFitness();
}
calcFitness() {
for (let i = 0; i < this.population.length; i++) {
this.population[i].calcFitness(target);
}
}
naturalSelection() {
this.matingPool = [];
let maxFitness = 0;
for (let i = 0; i < this.population.length; i++) {
if (this.population[i].fitness > maxFitness) {
maxFitness = this.population[i].fitness;
}
}
for (let i = 0; i < this.population.length; i++) {
let fitness = map(this.population[i].fitness, 0, maxFitness, 0, 1);
let n = floor(fitness * 100);
for (let j = 0; j < n; j++) {
// and pick two random numbers
this.matingPool.push(this.population[i]);
}
}
}
generate() {
for (let i = 0; i < this.population.length; i++) {
let a = floor(random(this.matingPool.length));
let b = floor(random(this.matingPool.length));
let partnerA = this.matingPool[a];
let partnerB = this.matingPool[b];
let child = partnerA.crossover(partnerB);
child.mutate(this.mutationRate);
this.population[i] = child;
}
this.generations++;
}
getBest() {
return this.best;
}
evaluate() {
let worldrecord = 0.0;
let index = 0;
for (let i = 0; i < this.population.length; i++) {
if (this.population[i].fitness > worldrecord) {
index = i;
worldrecord = this.population[i].fitness;
}
}
this.best = this.population[index].getPhrase();
if (worldrecord === this.perfectScore) {
this.finished = true;
}
}
isFinished() {
return this.finished;
}
getGenerations() {
return this.generations;
}
getAverageFitness() {
let total = 0;
for (let i = 0; i < this.population.length; i++) {
total += this.population[i].fitness;
}
return total / this.population.length;
}
allPhrases() {
let everything = "";
let displayLimit = min(this.population.length, 50);
for (let i = 0; i < displayLimit; i++) {
everything += this.population[i].getPhrase() + "<br>";
}
return everything;
}
}
let target;
let popmax;
let mutationRate;
let population;
let bestPhrase;
let allPhrases;
let stats;
function setup() {
bestPhrase = createP("Best phrase:");
bestPhrase.class("best");
allPhrases = createP("All phrases:");
allPhrases.position(600, 10);
allPhrases.class("all");
stats = createP("Stats");
stats.class("stats");
target = "To be or not to be.";
popmax = 200;
mutationRate = 0.01;
population = new Population(target, mutationRate, popmax);
}
function draw() {
population.naturalSelection();
population.generate();
population.calcFitness();
population.evaluate();
if (population.isFinished()) {
noLoop();
}
displayInfo();
}
function displayInfo() {
let answer = population.getBest();
bestPhrase.html("Best phrase:<br>" + answer);
let statstext =
"total generations: " + population.getGenerations() + "<br>";
statstext +=
"average fitness: " + nf(population.getAverageFitness()) + "<br>";
statstext += "total population: " + popmax + "<br>";
statstext += "mutation rate: " + floor(mutationRate * 100) + "%";
stats.html(statstext);
allPhrases.html("All phrases:<br>" + population.allPhrases());
}
전체 코드를 다시 파일별로 살펴 보며 프로그램 실행을 한 번 더 해볼까요, 우리~^^*
오늘 저와 함께 DNA 교차 작업과 돌연변이 생성작업을 하는 함수 crossover()와 mutate()를 살펴봐 주셔서 감사합니다~^^*
서로 다른 문화의 개성들이 잘 교차되어 다음 세대의 아름다운 문화를 만들어 내어요~~^^*
내일은 이 모든 내용을 간단하게 복습 정리해 보고 새로운 코드 공부도 시작해 볼까요~^^*
오늘도 점심 맛있게 드시고요!
춥지만 마음은 따순한 낮과 저녁을 보내시고요!
편안하게 코~^^*하는 밤 되시길 바래요~~^^*
우리 내일 또 다시 만나요~~^^*
네~~^^* 꿈은 이루어 집니다~~^^*
댓글 남기기