-
Caution
- 원서에 있는 코드와 다른 부분이 다소 있음.
-
Main code
import random from ch3.selection_rank_with_elite import selection_rank_with_elite from ch3.selection_proportional_with_elite import selection_proportional_with_elite from ch3.individual import Individual POPULATION_SIZE = 5 # 개체군 크기 설정 random.seed(3) # 난수 시드 고정 (동일한 난수 생성) # 개체군 생성 population = Individual.create_random_population(POPULATION_SIZE) # Rank selection with elite 방식으로 개체 선택 (elite_size=1로 상위 1개 개체는 무조건 선택) selected = selection_rank_with_elite(population, elite_size=1) # Proportinal selection with elite 방식으로 개체 선택 (elite_size=1로 상위 1개 개체는 무조건 선택) selected = selection_proportional_with_elite(population, elite_size=1) # 생성된 개체군과 선택된 개체 출력 print(f"Population: {population}") print(f"Selected: {selected}")
-
Rank selection base
- 순위 선택을 기반으로 한 엘리트 선택
import random def selection_rank_with_elite(individuals, elite_size=0): # elite_size는 상위 몇 개를 엘리트 선택으로 가져올 것인지 결정 # 1. 개체들을 fitness 값에 따라 내림차순으로 정렬 sorted_individuals = sorted(individuals, key=lambda ind: ind.fitness, reverse=True) # 2. 엘리트 선택: 상위 elite_size개의 개체를 먼저 선택 selected = sorted_individuals[0:elite_size] # 3. 엘리트 개체를 제외한 나머지 개체들로 리스트 갱신 del sorted_individuals[0:elite_size] # 4. 순위 선택을 위한 준비 작업 rank_distance = 1 / len(sorted_individuals) # 각 개체 간 순위 점수 차이 계산 ranks = [(1 - i * rank_distance) for i in range(len(sorted_individuals))] # 순위에 따른 가중치 부여 ranks_sum = sum(ranks) # 모든 가중치의 합 계산 # 5. 엘리트 선택에서 제외된 개체들 중에서 순위 선택 방식으로 추가 개체를 선택 shave = random.random() * ranks_sum # 0과 ranks_sum 사이의 랜덤 값 생성 rank_sum = 0 # 누적 가중치 초기화 for i in range(len(sorted_individuals)): rank_sum += ranks[i] # 현재 개체의 가중치를 누적 if rank_sum >= shave: # 누적 가중치가 shave 값을 초과하면 해당 개체 선택 selected.append(sorted_individuals[i]) break # 선택했으므로 반복 종료 # 6. 선택된 개체 리스트 반환 return selected
-
Proportional selection base
- 비례 선택을 기반으로 한 엘리트 선택
import random def selection_proportional_with_elite_1(individuals, elite_size=0): # 1. 개체들을 fitness 값에 따라 내림차순으로 정렬 sorted_individuals = sorted(individuals, key=lambda ind: ind.fitness, reverse=True) # 2. 엘리트 선택: 상위 elite_size개의 개체를 먼저 선택 selected = sorted_individuals[0:elite_size] # 3. 엘리트 개체를 제외한 나머지 개체들로 리스트 갱신 del sorted_individuals[0:elite_size] # 4. 전체 fitness 값의 합을 계산 fitness_sum = sum(ind.fitness for ind in sorted_individuals) # 5-1. 0과 fitness_sum 사이의 무작위 값 생성 (룰렛 휠에서 화살표 역할) shave = random.random() * fitness_sum roulette_sum = 0 # 룰렛 휠의 현재 값 초기화 # 5-2. 룰렛 휠을 돌려 선택 과정 수행 for ind in sorted_individuals: print(shave, roulette_sum) # 디버깅용 출력 (필요 없으면 제거 가능) roulette_sum += ind.fitness # 현재 개체의 fitness 값을 누적 5-3. 누적 fitness 값이 무작위로 선택된 값(shave)을 초과하면 해당 개체 선택 if roulette_sum > shave: selected.append(ind) break # 한 개체를 선택했으므로 반복 종료 # 6. 선택된 개체 리스트 반환 return selected
-
-
Pros, Cons
장점 단점 우수 개체 보존 및 손실 방지 개체 다양성 감소 빠른 수렴 및 빠른 성능 개선 가능 지역 최적화 문제 심화 알고리즘 안정성 증가 과도한 편향 위험 전반적인 알고리즘 성능 향상