โจ 5 - Mutation ๋์ฐ๋ณ์ด
A mutation is a random change in genes with the aim of improving an individualโs ability to survive.
๋์ฐ๋ณ์ด(Mutation)๋ ๊ฐ์ฒด์ ์์กด ๋ฅ๋ ฅ์ ํฅ์์ํค๊ธฐ ์ํ ๋ชฉ์ ์ ๊ฐ์ง ์ ์ ์์ ๋ฌด์์์ ์ธ ๋ณํ์
๋๋ค.
A mutation has no direction; it is a simple attempt at introducing a new feature that will give the future individual additional advantages.
๋์ฐ๋ณ์ด๋ ํน์ ํ ๋ฐฉํฅ์ฑ์ด ์์ผ๋ฉฐ, ๋จ์ง ๋ฏธ๋์ ๊ฐ์ฒด์๊ฒ ์ถ๊ฐ์ ์ธ ์ด์ ์ ์ค ์ ์๋ ์๋ก์ด ํน์ฑ์ ๋์
ํ๋ ค๋ ์๋์ผ ๋ฟ์
๋๋ค.
If you look at the history of evolution, it might seem that all mutations of species were strictly directed, and were extremely successful. But this is not right.
์งํ์ ์ญ์ฌ๋ฅผ ๋ณด๋ฉด ๋ชจ๋ ๋์ฐ๋ณ์ด๊ฐ ๋ง์น ๋ช
ํํ ๋ฐฉํฅ์ฑ์ ๊ฐ์ง๊ณ ์์๊ณ , ๋งค์ฐ ์ฑ๊ณต์ ์ด์๋ ๊ฒ์ฒ๋ผ ๋ณด์ผ ์ ์์ง๋ง, ์ด๋ ์ฌ์ค์ด ์๋๋๋ค.
An unsuccessful mutation makes an individual less viable due to which it cannot leave offspring, and therefore pass on its genes.
์ฑ๊ณตํ์ง ๋ชปํ ๋์ฐ๋ณ์ด๋ ๊ฐ์ฒด์ ์์กด ๊ฐ๋ฅ์ฑ์ ๋ฎ์ถ์ด ํ์์ ๋จ๊ธฐ์ง ๋ชปํ๊ฒ ํ๋ฉฐ, ๋ฐ๋ผ์ ์์ ์ ์ ์ ์๋ฅผ ์ ๋ฌํ์ง ๋ชปํฉ๋๋ค.
Consequently, individuals and species with unsuccessful mutations do not exist for a long time, which means they do not leave a significant trace in the evolutionary chain.
๊ฒฐ๊ณผ์ ์ผ๋ก, ์คํจํ ๋์ฐ๋ณ์ด๋ฅผ ๊ฐ์ง ๊ฐ์ฒด๋ ์ข
์ ์ค๋ ์กด์ฌํ์ง ๋ชปํ๊ณ , ์ด๋ ๊ณง ์งํ์ ํ๋ฆ์ ๋์ ๋๋ ํ์ ์ ๋จ๊ธฐ์ง ์๋๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
The mechanism of mutations is the driving force of evolution; it helps species to improve, as well as to adapt to environmental conditions.
๋์ฐ๋ณ์ด์ ๋ฉ์ปค๋์ฆ์ ์งํ์ ์๋๋ ฅ์ด๋ฉฐ, ์ข
์ด ํฅ์๋๊ณ ํ๊ฒฝ ์กฐ๊ฑด์ ์ ์ํ ์ ์๋๋ก ๋์ต๋๋ค.
โจ 5 - Structure ๊ตฌ์กฐ
The mechanisms of mutation are simpler than the mechanisms of selection and crossing.
๋์ฐ๋ณ์ด์ ๋ฉ์ปค๋์ฆ์ ์ ํ๊ณผ ๊ต์ฐจ์ ๋ฉ์ปค๋์ฆ๋ณด๋ค ๋ ๋จ์ํฉ๋๋ค.
In this chapter, we will look at the following main ones:
์ด๋ฒ ์ฅ์์๋ ๋ค์๊ณผ ๊ฐ์ ์ฃผ์ ๋์ฐ๋ณ์ด ๋ฐฉ์๋ค์ ์ดํด๋ด
๋๋ค:
- Random deviation mutation
์์ ํธ์ฐจ ๋์ฐ๋ณ์ด - Exchange mutation
๊ตํ ๋์ฐ๋ณ์ด - Shift mutation
์ด๋ ๋์ฐ๋ณ์ด - Bit flip mutation
๋นํธ ๋ฐ์ ๋์ฐ๋ณ์ด - Inversion mutation
๊ตฌ๊ฐ ๋ฐ์ ๋์ฐ๋ณ์ด - Shuffle mutation
์ ํ ๋์ฐ๋ณ์ด - Fitness driven mutation
์ ํฉ๋ ๊ธฐ๋ฐ ๋์ฐ๋ณ์ด
โจ 5 - Objectives ๋ชฉํ
Understand basic principles of mutation
๋์ฐ๋ณ์ด์ ๊ธฐ๋ณธ ์๋ฆฌ๋ฅผ ์ดํดํฉ๋๋ค.
Introduce main mutation methods
์ฃผ์ ๋์ฐ๋ณ์ด ๋ฐฉ๋ฒ๋ค์ ์๊ฐํฉ๋๋ค.
โจ 5.1 Random deviation mutation ๋ฌด์์ ํธ์ฐจ ๋ณ์ด
Random deviation mutation is mainly applied to a real set of genes.
๋ฌด์์ ํธ์ฐจ ๋ณ์ด๋ ์ฃผ๋ก ์ค์(real number) ์งํฉ์ผ๋ก ์ด๋ฃจ์ด์ง ์ ์ ์์ ์ ์ฉ๋ฉ๋๋ค.
A random variable is added to the gene with a certain probability, usually with an average of 0. Refer to the following figure.
์ ์ ์์ ์ผ์ ํ๋ฅ ๋ก ํ๊ท ์ด 0์ธ ๋ฌด์์ ๋ณ์๋ฅผ ๋ํ๋ ๋ฐฉ์์
๋๋ค. ๋ค์ ๊ทธ๋ฆผ์ ์ฐธ๊ณ ํด ์ฃผ์ธ์.
Random deviation mutation can be implemented by adding the random variable with normal distribution (average = 0 and sigma = 1).
๋ฌด์์ ํธ์ฐจ ๋ณ์ด๋ ํ๊ท ์ด 0์ด๊ณ ํ์คํธ์ฐจ๊ฐ 1์ธ ์ ๊ท๋ถํฌ๋ฅผ ๋ฐ๋ฅด๋ ๋์๋ฅผ ๋ํ๋ ๋ฐฉ์์ผ๋ก ๊ตฌํํ ์ ์์ต๋๋ค.
Import part
import copy
import randomRandom deviation mutation
def mutation_random_deviation(ind, mu, sigma, p):
mut = copy.deepcopy(ind)
for i in range(len(mut)):
if random.random() < p:
mut[i] = mut[i] + random.gauss(mu, sigma)
return mutExample
random.seed(0)
ind = [random.uniform(0, 10) for _ in range(2)]
mut = mutation_random_deviation(ind, 0, 1, 0.3)
print(f'Original: {ind}')
print(f'Mutated: {mut}')Result
Original: [8.444218515250482, 7.579544029403024]
Mutated: [8.444218515250482, 7.579544029403024]โจ 5.2 Exchange mutation ๊ตํ ๋ณ์ด
Exchange mutation is mainly applied to a binary or ordered set of genes.
๊ตํ ๋ณ์ด๋ ์ฃผ๋ก ์ด์ง(binary) ๋๋ ์์ํ(ordered) ์ ์ ์ ์งํฉ์ ์ ์ฉ๋ฉ๋๋ค.
A pair of genes are exchanged from randomly selected positions. Please refer to the following figure.
๋ฌด์์๋ก ์ ํ๋ ๋ ์์น์ ์ ์ ์๋ฅผ ์๋ก ๊ตํํ๋ ๋ฐฉ์์
๋๋ค. ๋ค์ ๊ทธ๋ฆผ์ ์ฐธ๊ณ ํด ์ฃผ์ธ์.
In concrete implementation, we pick two random indices in the list of genes, and change their values.
๊ตฌ์ฒด์ ์ธ ๊ตฌํ์์๋ ์ ์ ์ ๋ชฉ๋ก์์ ๋ ๊ฐ์ ๋ฌด์์ ์ธ๋ฑ์ค๋ฅผ ์ ํํ๊ณ , ํด๋น ์์น์ ๊ฐ์ ์๋ก ๋ฐ๊ฟ๋๋ค.
Import part
import copy
import randomExchange mutation
def mutation_exchange(ind):
mut = copy.deepcopy(ind)
pos = random.sample(range(0, len(mut)), 2)
g1 = mut[pos[0]]
g2 = mut[pos[1]]
mut[pos[1]] = g1
mut[pos[0]] = g2
return mutExample
random.seed(1)
ind = list(range(1, 7))
mut = mutation_exchange(ind)
print(f'Original: {ind}')
print(f'Mutated: {mut}')Result
Original: [1, 2, 3, 4, 5, 6]
Mutated: [1, 5, 3, 4, 2, 6]โจ 5.3 Shift mutation ์ด๋ ๋ณ์ด
Shift mutation is moving a gene from a randomly selected position by a random number of positions to the left or right.
์ด๋ ๋ณ์ด๋ ๋ฌด์์๋ก ์ ํ๋ ์ ์ ์๋ฅผ ์ผ์ชฝ ๋๋ ์ค๋ฅธ์ชฝ์ผ๋ก ๋ฌด์์ ๊ฐ์๋งํผ ์ด๋์ํค๋ ๋ฐฉ์์
๋๋ค.
The content of all intermediate genes is shifted by one position.
์ด๋ ์ค๊ฐ์ ์์นํ ์ ์ ์๋ค์ ํ ์นธ์ฉ ๋ฐ๋ ค๋ฉ๋๋ค.
This mutation method is applied to a binary or ordered set of genes. Refer to the following figure.
์ด ๋ณ์ด ๋ฐฉ์์ ์ด์ง ๋๋ ์์ํ ์ ์ ์ ์งํฉ์ ์ ์ฉ๋ฉ๋๋ค. ๋ค์ ๊ทธ๋ฆผ์ ์ฐธ๊ณ ํด ์ฃผ์ธ์.
There are three different approaches of shift mutation implementation:
์ด๋ ๋ณ์ด๋ ๊ตฌํ ๋ฐฉ์์ ๋ฐ๋ผ ์ธ ๊ฐ์ง๋ก ๋๋ฉ๋๋ค:
-
Bounded shifting:
์ ์ ์๊ฐ ๋ฆฌ์คํธ ๊ฒฝ๊ณ๋ฅผ ๋์ง ์๋๋ก ์ ํํฉ๋๋ค. ์:[1, 2, 3, 4, 5]์์ ์ ์ ์3์ ์ธ๋ฑ์ค0์ผ๋ก ์ด๋ โ[3, 1, 2, 4, 5] -
Unbounded shifting:
์ ์ ์๊ฐ ๋ฆฌ์คํธ ๊ฒฝ๊ณ๋ฅผ ๋์ด ์ด๋ํ ์ ์๋๋ก ํ์ฉํฉ๋๋ค. ์:[1, 2, 3, 4, 5]์์3์ ์ธ๋ฑ์ค0์ผ๋ก ์ด๋ ์ โ[3, 2, 4, 5, 1]
Import part
import copy
import random
from math import copysignShift mutation (bounded shifting approach)
def mutation_shift(ind):
mut = copy.deepcopy(ind)
pos = random.sample(range(0, len(mut)), 2)
g1 = mut[pos[0]]
dir = int(copysign(1, pos[1] - pos[0]))
for i in range(pos[0], pos[1], dir):
mut[i] = mut[i + dir]
mut[pos[1]] = g1
return mutExample
random.seed(21)
ind = list(range(1, 6))
mut = mutation_shift(ind)
print(f'Original: {ind}')
print(f'Mutated: {mut}')Result
Original: [1, 2, 3, 4, 5]
Mutated: [1, 3, 4, 2, 5]โจ 5.4 Bit flip mutation ๋นํธ ๋ฐ์ ๋ณ์ด
This type of mutation is applied to the binary gene set.
๋นํธ ๋ฐ์ ๋ณ์ด๋ ์ด์ง(binary) ์ ์ ์ ์งํฉ์ ์ ์ฉ๋ฉ๋๋ค.
Random gene is selected, and bit flipping is provoked, from 1 to 0 or from 0 to 1.
๋ฌด์์๋ก ์ ํ๋ ์ ์ ์์ ๋นํธ๋ฅผ ๋ฐ์ ์์ผ 1์ 0์ผ๋ก, ๋๋ 0์ 1๋ก ๋ฐ๊พธ๋ ๋ฐฉ์์
๋๋ค.
Letโs take a look at the following figure.
๋ค์ ๊ทธ๋ฆผ์ ์ฐธ๊ณ ํด ์ฃผ์ธ์.
To realize this method, we pick a random gene and apply addition of 1 modulo 2.
์ด ๋ฐฉ์์ ๋ฌด์์๋ก ์ ํ๋ ์ ์ ์์ 1์ ๋ํ ํ, mod 2 ์ฐ์ฐ์ ํตํด ๊ตฌํ๋ฉ๋๋ค.
Import part
import copy
import randomBit flip mutation
def mutation_bit_flip(ind):
mut = copy.deepcopy(ind)
pos = random.randint(0, len(ind) - 1)
g1 = mut[pos]
mut[pos] = (g1 + 1) % 2
return mutExample
random.seed(21)
ind = [random.randint(0, 1) for _ in range(0, 5)]
mut = mutation_bit_flip(ind)
print(f'Original: {ind}')
print(f'Mutated: {mut}')Result
Original: [1, 1, 1, 0, 0]
Mutated: [1, 1, 1, 1, 0]โจ 5.5 Inversion mutation ์ญ์ ๋ณ์ด
Inversion mutation picks a random subrange and changes the order of the values in it.
์ญ์ ๋ณ์ด๋ ์ ์ ์์์ ๋ฌด์์๋ก ํ๋์ ๊ตฌ๊ฐ์ ์ ํํ์ฌ, ํด๋น ๊ตฌ๊ฐ์ ์์๋ฅผ ๋ฐ์ ์ํค๋ ๋ฐฉ์์
๋๋ค.
This mutation method is applied to a binary or ordered set of genes.
์ด ๋ณ์ด ๋ฐฉ์์ ์ด์ง ๋๋ ์์ํ ์ ์ ์ ์งํฉ์ ์ ์ฉ๋ฉ๋๋ค.
Refer to the following figure.
๋ค์ ๊ทธ๋ฆผ์ ์ฐธ๊ณ ํด ์ฃผ์ธ์.
There are two different approaches of implementation of inversion mutation:
์ญ์ ๋ณ์ด ๊ตฌํ ๋ฐฉ์์ ๋ค์ ๋ ๊ฐ์ง๊ฐ ์์ต๋๋ค:
-
Unbounded subrange:
๋ฆฌ์คํธ ๋์ ๋์ด๊ฐ๋ ๊ตฌ๊ฐ ์ ํ ํ์ฉ. ์:[1,2,3,4,5]์์[3:1]์ ์ ํํ๋ฉด ๊ฒฐ๊ณผ๋[5,4,3,2,1]. -
Bounded subrange:
๋ฆฌ์คํธ ๊ฒฝ๊ณ๋ฅผ ๋์ง ์์ผ๋ฉฐ, ํญ์ ์ ์ธ๋ฑ์ค < ๋ค ์ธ๋ฑ์ค๋ฅผ ๋ง์กฑํ๋ ๊ตฌ๊ฐ๋ง ์ ํ.
์๋๋ bounded ๋ฐฉ์์ ๊ตฌํ ์์์ ๋๋ค.
Import part
import copy
import randomInversion mutation
def mutation_inversion(ind):
mut = copy.deepcopy(ind)
temp = copy.deepcopy(ind)
pos = sorted(random.sample(range(0, len(mut)), 2))
for i in range(0, (pos[1] - pos[0]) + 1):
mut[pos[0] + i] = temp[pos[1] - i]
return mutExample
random.seed(5)
ind = list(range(1, 6))
mut = mutation_inversion(ind)
print(f'Original: {ind}')
print(f'Mutated: {mut}')Result
Original: [1, 2, 3, 4, 5]
Mutated: [1, 4, 3, 2, 5]โจ 5.6 Shuffle mutation ์ ํ ๋ณ์ด
Shuffle mutation, like inversion mutation, picks a random subrange, but instead of changing the order of the values in it, it just shuffles the values.
์
ํ ๋ณ์ด๋ ์ญ์ ๋ณ์ด์ ์ ์ฌํ๊ฒ ๋ฌด์์ ๊ตฌ๊ฐ์ ์ ํํ์ง๋ง, ์์๋ฅผ ์ญ์ ํ๋ ๋์ ํด๋น ๊ตฌ๊ฐ์ ๊ฐ๋ค์ ๋ฌด์์๋ก ์๋ ๋ฐฉ์์
๋๋ค.
This mutation method is applied to a binary or ordered set of genes.
์ด ๋ณ์ด ๋ฐฉ์์ ์ด์ง ๋๋ ์์ํ ์ ์ ์ ์งํฉ์ ์ ์ฉ๋ฉ๋๋ค.
Refer to the following figure.
๋ค์ ๊ทธ๋ฆผ์ ์ฐธ๊ณ ํด ์ฃผ์ธ์.
Similar to the inversion mutation, there are two different approaches of shuffle mutation:
-
Unbounded subrange:
๋ฆฌ์คํธ ๋์ ๋์ด๊ฐ๋ ๊ตฌ๊ฐ๋ ํ์ฉํฉ๋๋ค. -
Bounded subrange:
๋ฆฌ์คํธ ๊ฒฝ๊ณ๋ฅผ ๋์ง ์๊ณ , ํญ์ ์ ์ธ๋ฑ์ค < ๋ค ์ธ๋ฑ์ค์ธ ๊ตฌ๊ฐ๋ง์ ์ฌ์ฉํฉ๋๋ค.
์๋๋ bounded ๋ฐฉ์์ ๊ตฌํ ์์์ ๋๋ค.
Import part
import copy
import randomShuffle mutation
def mutation_shuffle(ind):
mut = copy.deepcopy(ind)
pos = sorted(random.sample(range(0, len(mut)), 2))
subrange = mut[pos[0]:pos[1] + 1]
random.shuffle(subrange)
mut[pos[0]:pos[1] + 1] = subrange
return mutExample
random.seed(13)
ind = list(range(1, 6))
mut = mutation_shuffle(ind)
print(f'Original: {ind}')
print(f'Mutated: {mut}')Result
Original: [1, 2, 3, 4, 5]
Mutated: [1, 2, 4, 3, 5]โจ 5.7 Fitness driven mutation ์ ํฉ๋ ๊ธฐ๋ฐ ๋ณ์ด
Fitness driven mutation, like the fitness driven crossover, is an approach that tries to obtain only positive changes.
์ ํฉ๋ ๊ธฐ๋ฐ ๋ณ์ด๋ ์ ํฉ๋ ๊ธฐ๋ฐ ๊ต์ฐจ์ ์ ์ฌํ๊ฒ, ์ค์ง ๊ธ์ ์ ์ธ ๋ณํ๋ฅผ ์ป๊ธฐ ์ํ ๋ฐฉ์์
๋๋ค.
We run several mutations and pick the best one; if all mutations are worse than the original individual, then we leave the original without a mutation.
์ฌ๋ฌ ๋ฒ ๋ณ์ด๋ฅผ ์ํํ ๋ค ๊ฐ์ฅ ์ข์ ๊ฒฐ๊ณผ๋ฅผ ์ ํํ๋ฉฐ, ๋ชจ๋ ๋ณ์ด ๊ฒฐ๊ณผ๊ฐ ์๋ ๊ฐ์ฒด๋ณด๋ค ๋์๋ฉด ๋ณ์ด๋ฅผ ์ ์ฉํ์ง ์์ต๋๋ค.
Refer to the following figure.
๋ค์ ๊ทธ๋ฆผ์ ์ฐธ๊ณ ํด ์ฃผ์ธ์.
NOTE: You have to make only a finite number of mutation tries.
์ฃผ์: ๋ฐ๋์ ์ ํํ ํ์์ ๋ณ์ด ์๋๋ง ํ์ฉํด์ผ ํฉ๋๋ค.
It is unacceptable to make an infinite loop trying to find any positive mutation.
๊ธ์ ์ ์ธ ๋ณ์ด๋ฅผ ์ฐพ๊ธฐ ์ํด ๋ฌดํ ๋ฃจํ๋ฅผ ๋๋ ๊ฒ์ ๋ฐ๋์งํ์ง ์์ต๋๋ค.
Because there can be a situation when youโre trying to mutate the best individual, and each mutation makes it worse than it is now.
์๋ฅผ ๋ค์ด ์ต๊ณ ์ ํฉ๋์ ๊ฐ์ฒด๋ฅผ ๋ณ์ด์ํค๋ ๊ฒฝ์ฐ, ์คํ๋ ค ์ฑ๋ฅ์ด ์ ํ๋ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค.
Thus, your genetic algorithm will get stuck, trying to improve something that is already perfect.
์ด๋ก ์ธํด ์ด๋ฏธ ์๋ฒฝํ ๊ฐ์ฒด๋ฅผ ๊ฐ์ ํ๋ ค๋ค ์๊ณ ๋ฆฌ์ฆ์ด ๋ฉ์ถฐ๋ฒ๋ฆด ์ ์์ต๋๋ค.
Following are the two different approaches of fitness driven mutation:
๋ค์์ ์ ํฉ๋ ๊ธฐ๋ฐ ๋ณ์ด์ ๋ ๊ฐ์ง ๊ตฌํ ๋ฐฉ์์
๋๋ค.
-
Pick first positive:
์ฒ์์ผ๋ก ์ ํฉ๋๊ฐ ์ฆ๊ฐํ ๋ณ์ด๋ฅผ ์ฐพ์ผ๋ฉด ๊ทธ ์ฆ์ ์ ํํ๋ ๋ฐฉ์์ ๋๋ค.This approach generates mutations one by one, and stops when first positive mutation is found.
๋ณ์ด๋ฅผ ํ๋์ฉ ์์ฑํ๋ฉฐ ์ฒ์์ผ๋ก ์ฑ๋ฅ์ด ํฅ์๋ ๊ฒฝ์ฐ์ ๋ฉ์ถฅ๋๋ค.This approach is better in terms of the algorithm speed.
์ด ๋ฐฉ์์ ์๊ณ ๋ฆฌ์ฆ ์๋ ์ธก๋ฉด์์ ๋ ํจ์จ์ ์ ๋๋ค. -
Pick best positive:
๋ชจ๋ ๋ณ์ด๋ฅผ ์์ฑํ ํ, ๊ทธ ์ค ๊ฐ์ฅ ์ข์ ๊ฒ์ ์ ํํ๋ ๋ฐฉ์์ ๋๋ค.This approach generates all mutations, then picks the best one.
์ฌ๋ฌ ๊ฐ์ ๋ณ์ด๋ฅผ ์์ฑํ ๋ค ๊ฐ์ฅ ์ข์ ๊ฒฐ๊ณผ๋ฅผ ์ ํํฉ๋๋ค.This approach can improve population better but is worse in terms of the algorithm speed.
์ธ๊ตฌ ๊ฐ์ ์ธก๋ฉด์์๋ ๋ ํจ๊ณผ์ ์ด์ง๋ง, ์๋๋ ๋๋ฆฝ๋๋ค.
Fitness driven mutation can be based on any other mutation technique.
์ ํฉ๋ ๊ธฐ๋ฐ ๋ณ์ด๋ ๋ค๋ฅธ ๋ชจ๋ ๋ณ์ด ๊ธฐ๋ฒ ์์ ์ ์ฉ๋ ์ ์์ต๋๋ค.
Here we have the implementation of random deviation picking the first positive fitness driven mutation.
์ฌ๊ธฐ์๋ ๋ฌด์์ ํธ์ฐจ(random deviation)๋ฅผ ์ฌ์ฉํ ์ฒ์ ๊ธ์ ์ ํ ๋ฐฉ์์ ๊ตฌํ์ ์๊ฐํฉ๋๋ค.
Import part
import copy
import random
from math import sin
from typing import ListFitness function
def func(x):
return sin(x) - 0.2 * abs(x)Individual
class Individual:
def __init__(self, gene_list: List[float]) -> None:
self.gene_list = gene_list
self.fitness = func(self.gene_list[0])
def __str__(self):
return f'x: {self.gene_list[0]}, fitness: {self.fitness}'Fitness driven random deviation mutation (pick first positive)
def mutation_fitness_driven_random_deviation(ind, mu, sigma, p, max_tries=3):
for t in range(max_tries):
mut_genes = copy.deepcopy(ind.gene_list)
for i in range(len(mut_genes)):
if random.random() < p:
mut_genes[i] = mut_genes[i] + random.gauss(mu, sigma)
mut = Individual(mut_genes)
if ind.fitness < mut.fitness:
return mut
return indExample
random.seed(14)
ind = Individual([random.uniform(-10, 10)])
mut = mutation_fitness_driven_random_deviation(ind, 0, 1, 0.3)
print(f'Original: ({ind})')
print(f'Mutated: ({mut})')Result
Original: (x: -6.228264870789683, fitness: -0.5436606638121143)
Mutated: (x: -6.563361314086153, fitness: -0.5795202996943434)โจ Conclusion ๊ฒฐ๋ก
Just as in nature, in computational problems, the mutation is usually more important than crossing.
์์ฐ์์ ๊ทธ๋ ๋ฏ, ๊ณ์ฐ ๋ฌธ์ ์์๋ ๋ณ์ด๋ ๊ต์ฐจ๋ณด๋ค ๋ ์ค์ํ ์ญํ ์ ํฉ๋๋ค.
Yes, it is possible to construct successive GA algorithm architecture without crossing, but with a mutation.
์ค์ ๋ก ๋ณ์ด๋ง ์ฌ์ฉํ๊ณ ๊ต์ฐจ ์์ด๋ ์ ์ ์๊ณ ๋ฆฌ์ฆ ๊ตฌ์กฐ๋ฅผ ๊ตฌ์ฑํ ์ ์์ต๋๋ค.
But architecture without mutation is impossible in principle.
ํ์ง๋ง ๋ณ์ด ์์ด ๊ตฌ์ฑ๋ ๊ตฌ์กฐ๋ ์์น์ ์ผ๋ก ๋ถ๊ฐ๋ฅํฉ๋๋ค.
In the wild, some species reproduce themselves by simple cloning with mutation, and this approach ensures their development and survival.
์์ฐ๊ณ์์๋ ์ผ๋ถ ์ข
๋ค์ด ๋จ์ ๋ณต์ ์ ๋ณ์ด๋ง์ผ๋ก ๋ฒ์ํ๋ฉฐ, ์ด๋ ์งํ์ ์์กด์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
And so, we ended up with the basic operations performed by the GA.
์ด๋ก์จ ์ ์ ์๊ณ ๋ฆฌ์ฆ์์ ์ํ๋๋ ๊ธฐ๋ณธ ์ฐ์ฐ๋ค์ ์ดํด๋ณด์์ต๋๋ค.
In the next chapter, we will look at how you can compare and evaluate different genetic operations with each other so that you can choose the best architecture of the GA for a specific problem.
๋ค์ ์ฅ์์๋ ๋ค์ํ ์ ์ ์ฐ์ฐ๋ค์ ์ด๋ป๊ฒ ๋น๊ตํ๊ณ ํ๊ฐํ ์ ์๋์ง, ๊ทธ๋ฆฌ๊ณ ํน์ ๋ฌธ์ ์ ๊ฐ์ฅ ์ ํฉํ ๊ตฌ์กฐ๋ฅผ ์ ํํ๋ ๋ฐฉ๋ฒ์ ๋ํด ๋ค๋ฃฐ ์์ ์
๋๋ค.
โจ Points to remember ๊ผญ ๊ธฐ์ตํ ์
Mutation has to add light changes to individual genes.
๋ณ์ด๋ ๊ฐ๋ณ ์ ์ ์์ ๊ฐ๋ฒผ์ด ๋ณํ๋ฅผ ์ฃผ์ด์ผ ํฉ๋๋ค.
The mutation which changes genes drastically is very dangerous, and can ruin all positive experience which was accumulated by an individual, and even the whole population.
์ ์ ์๋ฅผ ๊ณผ๋ํ๊ฒ ๋ณํ์ํค๋ ๋ณ์ด๋ ๋งค์ฐ ์ํํ๋ฉฐ, ๊ฐ์ฒด๊ฐ ์ถ์ ํ ๊ธ์ ์ ์ธ ํน์ฑ์ ๋ฌผ๋ก , ์ ์ฒด ๊ฐ์ฒด๊ตฐ์ ๋ง์น ์ ์์ต๋๋ค.
There is no predetermined list of mutation methods.
๋ณ์ด ๋ฐฉ์์ ๋ฏธ๋ฆฌ ์ ํด์ง ๋ชฉ๋ก์ด ์กด์ฌํ์ง ์์ต๋๋ค.
You can implement your own mutation method for specific task.
ํน์ ์์
์ ๋ง์ถฐ ์์ ๋ง์ ๋ณ์ด ๋ฐฉ์์ ๊ตฌํํ ์ ์์ต๋๋ค.
Mutation is absolutely random process, and there is no guarantee that the mutation will improve an individual.
๋ณ์ด๋ ๋ณธ์ง์ ์ผ๋ก ๋ฌด์์์ ์ธ ๊ณผ์ ์ด๋ฉฐ, ๊ทธ๊ฒ์ด ๊ฐ์ฒด๋ฅผ ํฅ์์ํฌ ๊ฒ์ด๋ผ๋ ๋ณด์ฅ์ ์์ต๋๋ค.
โจ 5 - Multiple choice questions ๊ฐ๊ด์ ๋ฌธ์
Question 1
In population, we have the best individual and this individual is very valuable to us.
๊ฐ์ฒด๊ตฐ ๋ด์ ๊ฐ์ฅ ๋ฐ์ด๋ ๊ฐ์ฒด๊ฐ ์์ผ๋ฉฐ, ์ด ๊ฐ์ฒด๋ ๋งค์ฐ ์์คํฉ๋๋ค.
We want to save it or get an improved version in the next generation. What GA architecture should we choose?
์ฐ๋ฆฌ๋ ์ด ๊ฐ์ฒด๋ฅผ ๋ค์ ์ธ๋์๋ ์ ์งํ๊ฑฐ๋ ๋ ๋์ ๋ฒ์ ์ผ๋ก ๋ฐ์ ์ํค๊ณ ์ ํฉ๋๋ค. ์ด๋ค ์ ์ ์๊ณ ๋ฆฌ์ฆ ๊ตฌ์กฐ๋ฅผ ์ ํํด์ผ ํ ๊น์?
-
Rank selection, uniform crossover, fitness driven mutation
๋ญํฌ ์ ํ, ๊ท ๋ฑ ๊ต์ฐจ, ์ ํฉ๋ ๊ธฐ๋ฐ ๋ณ์ด -
Elite selection, fitness driven crossover, fitness driven mutation
์๋ฆฌํธ ์ ํ, ์ ํฉ๋ ๊ธฐ๋ฐ ๊ต์ฐจ, ์ ํฉ๋ ๊ธฐ๋ฐ ๋ณ์ด -
โ Elite selection, one-point crossover, fitness driven mutation
โ ์๋ฆฌํธ ์ ํ, ๋จ์ผ ์ง์ ๊ต์ฐจ, ์ ํฉ๋ ๊ธฐ๋ฐ ๋ณ์ด
Question 2
We have the following gene set (0,1,1,0) and fitness function (bโ,bโ,bโ,bโ) = bโ + bโ + bโ + bโ, i.e., fitness(0,1,1,0) = 2.
์ ์ ์ ์งํฉ (0,1,1,0)๊ณผ ์ ํฉ๋ ํจ์ (bโ,bโ,bโ,bโ) = bโ + bโ + bโ + bโ, ์ฆ fitness(0,1,1,0) = 2 ๊ฐ ์ฃผ์ด์ก์ต๋๋ค.
We apply bit flip mutation to individual (0,1,1,0). What fitness function of mutated individual can be?
๊ฐ์ฒด (0,1,1,0)์ ๋นํธ ๋ฐ์ ๋ณ์ด๋ฅผ ์ ์ฉํ ๋, ๋ณ์ด๋ ๊ฐ์ฒด์ ์ ํฉ๋๋ ์ด๋ป๊ฒ ๋ ์ ์์๊น์?
-
โ 1 with 50% probability, 3 with 50% probability
โ 1์ผ ํ๋ฅ 50%, 3์ผ ํ๋ฅ 50% -
1 with 90% probability, 3 with 10% probability
1์ผ ํ๋ฅ 90%, 3์ผ ํ๋ฅ 10% -
1 with 25% probability, 2 with 50% probability, 3 with 25% probability
1์ผ ํ๋ฅ 25%, 2์ผ ํ๋ฅ 50%, 3์ผ ํ๋ฅ 25%
โจ 4 - Questions ์ง๋ฌธ
1. In random deviation mutation, we pick random variable with average = 0. Why is it unacceptable to pick random variable with average = 1?
๋๋ค ํธ์ฐจ ๋ณ์ด์์ ํ๊ท ์ด 0์ธ ํ๋ฅ ๋ณ์๋ฅผ ์ฌ์ฉํ๋๋ฐ, ์ ํ๊ท ์ด 1์ธ ํ๋ฅ ๋ณ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋ฐ๋์งํ์ง ์์๊น์?
โ๏ธ ํ๊ท ์ด 1์ธ ํ๋ฅ ๋ณ์๋ฅผ ์ฌ์ฉํ๋ฉด, ๋ณ์ด ๋ฐฉํฅ์ด ํญ์ ํ์ชฝ(์์ ๋ฐฉํฅ)์ผ๋ก ์น์ฐ์น๊ฒ ๋์ด ํ์์ ํธํฅ์ด ์๊ธฐ๊ณ , ์ ์ฒด ํด ๊ณต๊ฐ์ ๊ณ ๋ฅด๊ฒ ํ์ํ์ง ๋ชปํ๊ฒ ๋ฉ๋๋ค. ์ด๋ ์ง์ญ ์ต์ ์ ์ ๋น ์ง ๊ฐ๋ฅ์ฑ์ ๋์ด๊ณ ์ ์ญ ์ต์ ์ ์ ์ฐพ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋ญ๋๋ค.
2. Say we are trying to find the maxima of the multivariable function f(x,y,z) with genetic algorithm. Will it be a successful approach to use the shuffle mutation in this case?
f(x, y, z)๋ผ๋ ๋ค๋ณ์ ํจ์์ ์ต๋๊ฐ์ ์ ์ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ์ฐพ๊ณ ์ ํ ๋, ์
ํ ๋ณ์ด๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ํจ๊ณผ์ ์ธ ๋ฐฉ๋ฒ์ผ๊น์?
โ๏ธ ์๋์. ์ ํ ๋ณ์ด๋ ์์ํ ์ ์ ์์ ์ ํฉํ ๋ณ์ด ๋ฐฉ์์ผ๋ก, ์ค์ํ ์ ์ ์์ฒ๋ผ ๊ฐ ๊ทธ ์์ฒด๊ฐ ์ค์ํ ๊ฒฝ์ฐ์๋ ์ ์ ํ์ง ์์ต๋๋ค. f(x, y, z) ๋ฌธ์ ์ฒ๋ผ ์ค์ ์ต์ ํ ๋ฌธ์ ์์๋ ๋ณดํต ์ฐ์์ ์ธ ๋ณ์ด(์: ๋๋ค ํธ์ฐจ ๋ณ์ด)๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ํจ๊ณผ์ ์ ๋๋ค.