# selection.py
# This file handles any population selection operations


# Internal Imports

# External Imports
from scipy.special import softmax
import numpy
import random


'''
----------random----------
- This function performs a random selection on the given population
-----Inputs-----
- population - The list of chromosomes from which to choose a candidate
-----Output-----
- chromosome - The selected candidate chromosome
'''
def roulette_wheel(population, amount):
    return random.choices(population, k = amount)


'''
----------roulette_wheel----------
- This function performs a roulette wheel selection on the given population
-----Inputs-----
- population - The list of chromosomes from which to choose a candidate
-----Output-----
- chromosome - The selected candidate chromosome
'''
def roulette_wheel(population, amount):
    fitnesses = [chromosome.fitness for chromosome in population]
    return random.choices(population, weights = fitnesses, k = amount)
    #-----
    #selection_probs = softmax([chromosome.fitness for chromosome in population])
    #return numpy.random.choice(population, p=selection_probs)
    #return numpy.ndarray.tolist(numpy.array(population)[indices])


'''
----------tournament----------
- This function performs a tournament selection on the given population
-----Inputs-----
- population - The list of chromosomes from which to choose a candidate
- selection_pressure - The selection pressure on the population
-----Output-----
- chromosome - The selected candidate chromosome
'''
def tournament(population, selection_pressure, selection_probability = .6):
    participants = random.choices(population, k = selection_pressure)
    participants = sorted(participants, reverse=True)
    return random.choices(participants, weights=[selection_probability*((1-selection_probability)**i) for i in range(selection_pressure)], k = 1)[0]