-
Population create
import random from ch3.selection_rank import selection_rank from ch3.individual import Individual POPULATION_SIZE = 5 # 개체군 크기 설정 random.seed(18) # 난수 시드를 고정하여 동일한 난수 생성 # 개체군 생성 population = Individual.create_random_population(POPULATION_SIZE) # Rank Selection 방식으로 개체 선택 selected = selection_rank(population) # 개체군과 선택된 개체 출력 print(f'Population: {population}') # 생성된 개체군 출력 print(f'Selected: {selected}') # 선택된 개체들 출력
- ch3
-
selection_rank
import random def selection_rank(individuals): # 개체들을 fitness 값에 따라 내림차순 정렬 sorted_individuals = sorted(individuals, key=lambda ind: ind.fitness, reverse=True) # 개체 수에 맞는 순위 간격 계산 rank_distance = 1 / len(individuals) # 각 개체의 순위에 따른 선택 확률 계산 ranks = [(1 - i * rank_distance) for i in range(len(individuals))] # 순위 확률의 총합 계산 ranks_sum = sum(ranks) # 선택된 개체들을 저장할 리스트 selected = [] # 선택된 개체 수만큼 반복 for _ in range(len(sorted_individuals)): # 임의의 선택 지점 (룰렛 휠의 '샤브' 위치) shave = random.random() * ranks_sum rank_sum = 0 # 룰렛 휠을 돌리며 선택 for i in range(len(sorted_individuals)): rank_sum += ranks[i] if rank_sum > shave: # 선택된 개체를 리스트에 추가 selected.append(sorted_individuals[i]) break return selected
-
- ch3
-
Visualization
import random import pandas as pd import matplotlib.pyplot as plt from ch3.individual import Individual # 개체 클래스 불러오기 # 개체군의 크기 설정 POPULATION_SIZE = 5 random.seed(2) # 랜덤한 개체 생성 unsorted_population = Individual.create_random_population(POPULATION_SIZE) population = sorted(unsorted_population, key=lambda ind: ind.fitness, reverse=True) # 전체 개체군의 fitness 합계 계산 fitness_sum = sum([ind.fitness for ind in population]) # 개체별 fitness 값을 저장할 딕셔너리 초기화 fitness_map = {} # 각 개체의 fitness 값에 따라 선택 확률 계산 for i in population: i_prob = round(100 * i.fitness / fitness_sum) # 선택 확률을 백분율(%)로 변환 i_label = f'{i.name} | fitness: {i.fitness}, prob: {i_prob}%' # 개체 정보 문자열 생성 fitness_map[i_label] = i.fitness # 딕셔너리에 저장 (key: 개체 정보, value: fitness 값) # 데이터프레임 생성 (개체별 fitness 값을 저장) proportional_df = pd.DataFrame(fitness_map, index=['Sectors']) # 수평 막대 그래프 생성 (개체들의 fitness 비율을 시각화) proportional_df.plot.barh(stacked=True) plt.tick_params(axis='x', which='both', bottom=False, top=False, labelbottom=False) plt.title('Fitness Proportional Sectors') plt.show() # Rank 선택을 위한 비례 확률 계산 rank_step = 1 / POPULATION_SIZE rank_sum = sum([1 - rank_step * i for i in range(len(population))]) # 각 개체의 rank에 따른 선택 확률 계산 rank_map = {} for i in range(len(population)): i_rank = i + 1 # 개체의 rank (1부터 시작) i_rank_proportion = 1 - i * rank_step # rank에 따른 확률 비율 계산 i_prob = round(100 * i_rank_proportion / rank_sum) # 확률을 백분율(%)로 변환 i_label = f'{population[i].name} | rank: {i_rank}, prob: {i_prob}%' # 개체 정보 문자열 생성 rank_map[i_label] = i_rank_proportion # 딕셔너리에 저장 (key: 개체 정보, value: rank에 따른 확률) # 데이터프레임 생성 (개체별 rank 확률 값을 저장) rank_df = pd.DataFrame(rank_map, index=['Sectors']) # 수평 막대 그래프 생성 (개체들의 rank 비율을 시각화) rank_df.plot.barh(stacked=True) plt.tick_params(axis='x', which='both', bottom=False, top=False, labelbottom=False) plt.title('Rank Proportional Sectors') plt.show()
-
Pros, Cons
장점 단점 다양성 유지에 좋음 매 세대마다 순위 정렬로 인한 추가 비용 조기 수렴 위험 완화 적합도 값의 절대적 차이 무시 안정적인 선택 압력 유지 적합도 동점 처리의 복잡성 존재 스케일링 문제 완화