• Population create

    import random
    from ch3.selection_stochastic_universal_sampling import selection_stochastic_universal_sampling
    from ch3.individual import Individual
     
    POPULATION_SIZE = 5  # 개체군의 크기 설정
    random.seed(1)  # 난수 시드를 고정하여 동일한 난수 생성
     
    # 개체군 생성
    population = Individual.create_random_population(POPULATION_SIZE)
     
    # Stochastic Universal Sampling (SUS) 방식으로 개체 선택
    selected = selection_stochastic_universal_sampling(population)
     
    # 개체군과 선택된 개체 출력
    print(f"Population: {population}")  # 생성된 개체군 출력
    print(f"Selected: {selected}")  # 선택된 개체들 출력
     
    • ch3
      • selection_stochastic_universal_sampling

        import random
         
        def selection_stochastic_universal_sampling(individuals):
            # 개체들을 fitness 값에 따라 내림차순 정렬
            sorted_individuals = sorted(individuals, key=lambda ind: ind.fitness, reverse=True)
         
            # 전체 fitness 값의 합 계산
            fitness_sum = sum([ind.fitness for ind in individuals])
         
            # 거리 계산 (전체 fitness 값 합을 개체 수로 나누기)
            distance = fitness_sum / len(individuals)
         
            # 시작 지점 계산 (랜덤으로 설정)
            shift = random.uniform(0, distance)
         
            # 선택의 경계값들 계산 (각각의 경계에 해당하는 확률값을 계산)
            borders = [shift + i * distance for i in range(len(individuals))]
         
            selected = []
         
            # 경계값을 기준으로 개체를 선택
            for border in borders:
                i = 0
                roulette_sum = sorted_individuals[i].fitness
         
                # 해당 경계값을 넘는 개체를 선택
                while roulette_sum < border:
                    i += 1
                    roulette_sum += sorted_individuals[i].fitness
                
                # 선택된 개체를 추가
                selected.append(sorted_individuals[i])
         
            return selected



  • Visualization

    import random
    import pandas as pd
    import matplotlib.pyplot as plt
    from ch3.individual import Individual
     
    POPULATION_SIZE = 5
    random.seed(9)
     
    # 랜덤한 개체 생성
    unsorted_population = Individual.create_random_population(POPULATION_SIZE)
     
    # 개체를 fitness 값에 따라 내림차순으로 정렬
    population = sorted(unsorted_population, key=lambda ind: ind.fitness, reverse=True)
     
    # 전체 개체군의 fitness 합계 계산
    fitness_sum = sum([ind.fitness for ind in population])
     
    # 개체별 fitness 값을 저장할 딕셔너리 초기화
    fitness_map = {}
    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 값)
     
    # 막대그래프
    # DataFrame을 사용하여 막대그래프를 그리기 위한 데이터 준비
    index = ['Sectors']
    df = pd.DataFrame(fitness_map, index=index)
     
    df.plot.barh(stacked=True)
     
    # 확률적 보편 샘플링을 위한 거리 계산
    distance = fitness_sum / POPULATION_SIZE
    shift = random.random() * distance  # 이동 거리 설정
     
    # 룰렛 휠을 나타내는 세로선 추가
    for i in range(POPULATION_SIZE):
        plt.axvline(x=shift + distance * i, linewidth=5, color='black')
     
    # x축 레이블 숨기기
    plt.tick_params(axis='x', which='both', bottom=False, top=False, labelbottom=False)
     
    # 그래프 출력
    plt.show()
  • Pros, Cons

    장점단점
    편향성 감소, 공정한 선택 가능구현이 약간 복잡함
    개체군 내 다양성 유지개체 간 적합도 차이가 클 때 일부 편향 가능성
    안정적이고 신뢰성 높은 선택최적 개체 유지 보장 안됨
    룰렛 휠의 단점 보완