Notice
Recent Posts
Recent Comments
Link
«   2024/07   »
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
Tags
more
Archives
Today
Total
관리 메뉴

공hannah부

EV3 - 유전 알고리즘 구현하기(파이썬) 본문

공부/인공지능

EV3 - 유전 알고리즘 구현하기(파이썬)

Hannah0226 2023. 2. 24. 21:22

목표

- EV3 로봇을 활용해 유전학습 구현하기

- 어떻게 하면 가장 효율적으로 그네를 탈 수 있을까?

 

유전알고리즘이란?

- 강화학습의 한 분야로 다윈의 적자생존 이론을 기반으로 한 전역 최적화 기법이다. 많은 집 속에서 주어진 문제를 가장 잘 풀어내는, 혹은 가장 적합한 해를 선택하는 것을 목표로 하며 이 과정에서 자연계의 진화를 본딴 여러 연산을 수행한다.

- 자연선택을 통해 생명체가 진화함을 활용해 랜덤한 유전자들 중 '좋은' 유전자들을 선별해 살아나게끔 설정한다

- 여기서 중요한 점은 유전적 다양성을 지키기 위해 '좋지 않은' 유전자일지라도 세대에 약간의 변동을 주기위해 남겨놓아야 한다!

 

알고리즘(순서도)

 

코드

#!/usr/bin/env pybricks-micropython

from pybricks import ev3brick as brick
from pybricks.ev3devices import (Motor, TouchSensor, ColorSensor,
                                 InfraredSensor, UltrasonicSensor, GyroSensor)
from pybricks.parameters import (Port, Stop, Direction, Button, Color,
                                 SoundFile, ImageFile, Align)
from pybricks.tools import print, wait, StopWatch
from pybricks.robotics import DriveBase
# Write your program here

import random
import copy

# 포트 설정
Bmotor = Motor(Port.B)
Cmotor = Motor(Port.C)
Gsensor = GyroSensor(Port.S2)
Gsensor.reset_angle(0)

# 안될 시 각속도 값을 계산으로 각속도에 따라 가중치 부여 하는 알고리즘으로 변경
# 각속도 배열 선언 
# 유전 단계에서 변이 70
# 유전시 각속도값이 양수면 0 음수 면 1로 유전 
# 1과 0이 흔드는 속도에 따라 뭉치게 될 것이라 예상
# 세대에 따라 변이율 조정
# 최악으로 아예 세대별 확률로 값 설정하고 세대가 올라갈수록 확률을 늘려서 각속도에 맞춰 0 1 로 
# 일정 확률로 움직이게 만들기.


gene = 1                                    # 세대 수
mutation = 10                               # 돌연변이 확률
objects = 10                                # 개체 수
datas = 10                                  # 개체 별 데이터 수
checktime = 20                              # 자이로 체크 주기
point = [0 for col in range(objects)]       # 점수표 
select = [0,0]                              # 우성 개체

# 개체 별 데이터 초기화
sets =  [[0 for col in range(datas)] for row in range(objects)]
new_sets = [[0 for col in range(datas)] for row in range(objects)]

# 개체 별 랜덤 데이터
for i in range(objects):
    for j in range(datas):
        sets[i][j] = random.randint(0,1)

# 유전 학습 시작
while True:
    # 체킹 시스템
    for i in range(objects):
        maxG = 0
        minG = 0
        for j in range(datas):
            state = sets[i][j]
            Bmotor.track_target(((state - 0.5) * 140) + 15)
            Cmotor.track_target(((state - 0.5) * 140) + 15)
            for t in range(checktime):
                angle = Gsensor.angle()
                maxG = max(maxG, angle)
                minG = min(minG, angle)
                wait(10)
        point[i] = maxG - minG
        Gsensor.reset_angle(0)

    #점수 체크
    print(gene,"Gen : ", point)
    print(gene,"Gen sets:")
    for i in range(objects):
        print(sets[i])
    brick.display.text(str(gene) + "Gen : ")
    brick.display.text("[" + str(point[0]) + "," + str(point[1]) + "," + str(point[2]) + "," + str(point[3]) + "," + str(point[4]) + "]")
    brick.display.text("[" + str(point[5]) + "," + str(point[6]) + "," + str(point[7]) + "," + str(point[8]) + "," + str(point[9]) + "]")

    #좋은 세대 탈출
    check = False
    for i in range(objects):
        if point[i] > 200:
            check = True
            break
    if check:
        break

    #우성
    point_check = copy.deepcopy(point)
    point_check.sort(reverse=True)
    for i in range(2):
        for j in range(objects):
            if point_check[i] == point[j]:
                select[i] = j
                break

    #다음세대 제작
    for i in range(objects) :
        for j in range(datas) :
            if random.randint(0, 100) < mutation:
                new_sets[i][j] = random.randint(0,1)
            else:
                new_sets[i][j] = sets[select[random.randint(0,1)]][j]

    #복사 및 다음 세대 
    sets = copy.deepcopy(new_sets)
    gene += 1
    
    #최대 세대수 
    if gene > 1000:
        break

#마무리 세대 및 결과값 출력
brick.display.text(str(gene) + "Gen : ")
brick.display.text("[" + str(point[0]) + "," + str(point[1]) + "," + str(point[2]) + "," + str(point[3]) + "," + str(point[4]) + "]")
brick.display.text("[" + str(point[5]) + "," + str(point[6]) + "," + str(point[7]) + "," + str(point[8]) + "," + str(point[9]) + "]")
print(gene,"Gen point : ", point)
print(gene,"Gen sets:")
for i in range(objects):
    print(sets[i])
print(point, "done")


while True:
    # 완성된 그네 반복
    for i in range(2):
        for j in range(datas):
            state = sets[select[i]][j]
            Bmotor.track_target(((state - 0.5) * 140) + 15)
            Cmotor.track_target(((state - 0.5) * 140) + 15)
            wait(checktime * 10)

 

결과