Source code for pyleecan.Functions.Optimization.tournamentDCD
from random import sample, choice
[docs]def choseDCD(indiv_1, indiv_2):
"""Chose between two individuals
Parameters
----------
indiv_1 : individual
indiv_2 : individual
Returns
-------
individual selected
"""
if indiv_1.cstr_viol == 0 and indiv_2.cstr_viol > 0: # only indiv_1 feasible
return indiv_1
elif indiv_1.cstr_viol > 0 and indiv_2.cstr_viol == 0: # only indiv_2 feasible
return indiv_2
elif (
indiv_1.cstr_viol > 0 and indiv_2.cstr_viol > 0
): # indiv_1 and indiv_2 unfeasible
# Compare the number of constraint violations
if indiv_1.cstr_viol < indiv_2.cstr_viol:
return indiv_1
elif indiv_1.cstr_viol > indiv_2.cstr_viol:
return indiv_2
else:
return choice([indiv_1, indiv_2])
else: # Both indiv feasible
# Check domination, else check crowding distance, else random choice
if indiv_1.fitness.dominates(indiv_2.fitness):
return indiv_1
elif indiv_2.fitness.dominates(indiv_1.fitness):
return indiv_2
elif indiv_1.fitness.crowding_dist > indiv_2.fitness.crowding_dist:
return indiv_1
elif indiv_1.fitness.crowding_dist < indiv_2.fitness.crowding_dist:
return indiv_2
else:
return choice([indiv_1, indiv_2])
[docs]def tournamentDCD(pop, size):
"""Select individuals from the population with a tournament based on the domination and the crowding distance
This function is inspired by DEAP selTournamentDCD function at https://github.com/DEAP/deap/blob/master/deap/tools/emo.py
Parameters
----------
pop : list
list of individuals created with the DEAP toolbox
size : int
number of individual to select
Returns
-------
selection : list
list of individuals selected
"""
if len(pop) % 4 != 0:
raise ValueError("TournamentDCD: pop length must be a multiple of 4")
if size % 4 != 0:
raise ValueError(
"TournamentDCD: number of individuals to select must be a multiple of 4"
)
# Sample the population
indiv_1 = sample(pop, len(pop))
indiv_2 = sample(pop, len(pop))
selection = []
# Select individuals
for i in range(0, size, 4):
selection.append(choseDCD(indiv_1[i], indiv_1[i + 1]))
selection.append(choseDCD(indiv_2[i], indiv_2[i + 1]))
selection.append(choseDCD(indiv_1[i + 2], indiv_1[i + 3]))
selection.append(choseDCD(indiv_2[i + 2], indiv_2[i + 3]))
return selection