일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- geth
- ethers
- blockchain
- 블록체인
- truffle
- erc
- git
- Python
- solidity
- tcp
- JavaScript
- MySQL
- 스마트 컨트랙트
- Ethereum
- web3.js
- github
- web
- Docker
- 이더리움
- erc721
- 트랜잭션
- NFT
- ERC165
- ERC20
- 네트워크
- 제어의역전
- server
- Programming
- 솔리디티
- web3
- Today
- Total
멍개의 연구소
유전 알고리즘 본문
간단하게 유전알고리즘을 구현을 해보자.
최종 유전자는 111111이다.
랜덤으로 30개의 유전자를 생성을 하여 111111에 가장 가까운 유전자 2개를 남기고 모두 지운다.
gene.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class Genes(): def __init__(self, status): self.status = status self.similar = 0 self.what_similar() def what_similar(self): ''' 111111 6자리 ''' for i in str(self.status): if i == '1': self.similar += 1 def __del__(self): print(self.status, '사망') | cs |
해당 유전가자 111111에 얼마나 비슷한지
echo.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | from gene import Genes as G from random import random class Ecosystem: def __init__(self, ge): self.generation = ge self.gene_list = self.initialize_gene() self.parents = [] self.who_parents() self.none_parents_delete() #유전자 생성 def initialize_gene(self): gene_list = [] for i in range(30): while True: temp = int(random()*1000000) if len(str(temp)) == 6: g = G(temp) gene_list.append(g) break return gene_list #부모 유전자 선택 def who_parents(self): for i in range(2): temp = G(0) for j in range(30): if temp.similar < self.gene_list[j].similar and not self.gene_list[j] in self.parents : temp = self.gene_list[j] self.parents.append(temp) #부모 유전자를 제외하고 제거 def none_parents_delete(self): for index, item in enumerate(self.gene_list): del item self.gene_list[index] = None self.gene_list = [] | cs |
g.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | from random import random from echo import Ecosystem as Echo if __name__ == "__main__": print(0, '번째') echo = Echo(0) for i in echo.gene_list: if i is not None: print(i.status, i.similar) print('0세대 상위 유전자') print(echo.parents[0].status, echo.parents[0].similar) print(echo.parents[1].status, echo.parents[1].similar) print('=========================================') | cs |
$ python g.py 0 번째 0 사망 0 사망 829402 사망 597979 사망 434582 사망 754965 사망 350844 사망 943519 사망 255545 사망 695438 사망 775939 사망 868224 사망 180944 사망 733226 사망 394287 사망 326435 사망 131053 사망 800439 사망 502259 사망 898596 사망 458853 사망 215984 사망 814521 사망 774371 사망 533304 사망 585691 사망 855598 사망 425682 사망 305393 사망 524938 사망 0세대 상위 유전자 182981 2 115467 2
30개의 유전자중 가장 강한 유전자 2개만 남겨두고 모두 죽었다. 이제 교차와 변이를 통해서 다시 유전자를 생성을 해보자.
echo.py를 다음 세대로 넘어가는 부분을 추가해보자
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #다음 세대 def next_generation(self): self.match() self.who_parents() self.none_parents_delete() #상위 유전자 교배 def match(self): temp = '' for o in range(30): for i in range(6): r =random() if r > 0.5 : temp += str(self.parents[0].status)[i] else: temp += str(self.parents[1].status)[i] g = G(int(temp)) # print(temp) temp = '' self.gene_list.append(g) print(g.status, g.similar) | cs |
0.5의 확률로 첫번째 부모 유전자나 두번째 부모의 유전자를 물려 받아서 유전자를 30개를 또다시 생성을 한후 이 중에서 다시 상위 유전자를 선택을 한다.
p.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | from random import random from echo import Ecosystem as Echo if __name__ == "__main__": echo = Echo(0) for i in range(3): print(str(echo.generation) +'세대 유전자들') print(echo.parents[0].status, echo.parents[0].similar) print(echo.parents[1].status, echo.parents[1].similar) echo.next_generation() print(str(echo.generation) +'세대 유전자') for i in echo.parents: print(i.status, i.similar) | cs |
$ python g.py ...중략... 111604 3 111604 3 1세대 상위 유전자 111604 3 111604 3 2세대 유전자들 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 111604 3 2세대 상위 유전자 111604 3 111604 3 ...
어느 순간부터 상위 유전자가 일치해진다
해결 방법은 유전자 교차를 할 때 일정 확률로 유전자 변이를 일으키면 된다.
(근데 숫자 자릿수가 짧아서 그런지 몇세대 안돌아도 금방 된느듯 하네 ㅋㅋ)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #상위 유전자 교배 def match(self): temp = '' for o in range(30): for i in range(6): r =random() mutation_rate = random() if mutation_rate < 0.2 : print(int(mutation_rate * 100)%10) temp += str(int(mutation_rate * 100)%10) else : if r > 0.5 : temp += str(self.parents[0].status)[i] else: temp += str(self.parents[1].status)[i] g = G(int(temp)) # print(temp) temp = '' self.gene_list.append(g) print(g.status, g.similar) | cs |
match 부분을 살짝 수정을 하여 0.2의 확률로 변이를 일으켰다.
변이가 정상적으로 작동하는지 테스트를 위해 높은 확률을 주었다.
$ python g.py ...중략... 118110 4 111111 6 2세대 상위 유전 111111 6 111111 6
결과가 나온다.
이제 마지막으로 모든 유전자가 111111인지 확인하는 부분을 추가해주자.
echo.py
중간 중간 수정을 한 부분이 있다.
g.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | from random import random from echo import Ecosystem as Echo import time if __name__ == "__main__": option1 = { "gene_count" : 30, "gene_length" : 6, "mutation_probability" : 0.1 } echo = Echo(option1) while echo.is_continue(): print('=======================') print(str(echo.generation) +'세대 유전자들') echo.next_generation() print(str(echo.generation - 1) +'세대 상위 유전자') for parent in echo.parents: print(parent.status, parent.similar) print('=======================\n\n') time.sleep(1) | cs |
유전자의 총 갯수 유전자 길이등을 설정하는 인자를 넘길수 있게 수정을 하였다.
(디버깅 할때 편하게 하려고 sleep을 추가해 주었다)
프로그램이 끝이나면 모든 유전자는 사망을한다.
(테스트 진행중에는 평균적으로 10~20정도에 완료가 됬는데 6번만에 끝났네 ㅋㅋㅋㅋㅋ)
Gends 클래스에
1 2 | def __del__(self): print(self.status, '사망') | cs |
추가만 해주면 된다.
그냥 글 보고 그대로 짜긴 했는데
아직은 잘 모르겠다.
보니깐 교차방법 변이방법이 종류가 다양하던데 ㅋㅋㅋㅋㅋ 심심할때 짜긴 좋은거 같긴하다.
먼가 코드가 맘에 안들면 수정해서 알려주십쇼~~ ㅋㅋ
https://github.com/pjt3591oo/python-gene
'컴퓨터 공학(Computer Science & Engineering)) > 알고리즘' 카테고리의 다른 글
스네이크 게임 알고리즘 (0) | 2017.04.29 |
---|---|
탐욕 알고리즘 (0) | 2017.04.29 |