forked from m20210989/CIFO-Sudoku-GA-Group-D
-
Notifications
You must be signed in to change notification settings - Fork 0
/
selection.py
107 lines (92 loc) · 3.76 KB
/
selection.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import random
from random import choice, uniform, random, sample
from operator import attrgetter
# #### FSP (or Roulette Wheel Selection)
# - **Obs**: added code for minimization.
def fps(population):
"""Fitness proportionate selection implementation.
Args:
population (Population): The population we want to select from.
Returns:
Individual: selected individual.
"""
if population.optim == "max":
# Sum total fitness
total_fitness = sum([i.fitness for i in population])
# Get a 'position' on the wheel
spin = uniform(0, total_fitness)
position = 0
# Find individual in the position of the spin
for individual in population:
position += individual.fitness
if position > spin:
return individual
elif population.optim == "min":
# Sum total fitness
total_fitness = sum([1 / (i.fitness) for i in population])
# Get a 'position' on the wheel
spin = uniform(0, total_fitness)
position = 0
# Find individual in the position of the spin
for individual in population:
position += 1 / individual.fitness
if position > spin:
return individual
else:
raise Exception("No optimization specified (min or max).")
# Ranking Selection
# **Obs**: implemented code for both maximization and minimization.
def ranking(population):
"""Ranking selection implementation.
Args:
populattion(Population): The population we want to select from.
Returns:
Individual: best fitness?
"""
if population.optim == 'max':
# sort population according to their fitness value
sorted_fitnesses = sorted(population, key=attrgetter('fitness'), reverse=False)
# Sum of fitness - using Gaussian sum
total_fitness = (len(population) + 1) * len(population) / 2
ranked_scores = [i/total_fitness for i in range(0, len(population))]
spin = uniform(0, sum(ranked_scores))
position = 0
# Find individual in the position of the spin
for index, rank in enumerate(ranked_scores):
position += rank
if position > spin:
return sorted_fitnesses[index]
elif population.optim == 'min':
# sort population according to their fitness value
sorted_fitnesses = sorted(population, key=attrgetter('fitness'), reverse=True)
# Sum of fitness - using Gaussian sum
total_fitness = (len(population) + 1) * len(population) / 2
ranked_scores = [i/total_fitness for i in range(0, len(population))]
spin = uniform(0, sum(ranked_scores))
position = 0
# Find individual in the position of the spin
for index, rank in enumerate(ranked_scores):
position += rank
if position > spin:
return sorted_fitnesses[index]
else:
raise Exception("No optimization specified (min or max).")
# Tournament Selection
# **Obs**: Nothing was modified since the code was fully implemented in class.
def tournament(population, size=10):
"""Tournament selection implementation.
Args:
population (Population): The population we want to select from.
size (int): Size of the tournament.
Returns:
Individual: Best individual in the tournament.
"""
# Select individuals based on tournament size
tournament = [choice(population.individuals) for i in range(size)]
# Check if the problem is max or min
if population.optim == 'max':
return max(tournament, key=attrgetter("fitness"))
elif population.optim == 'min':
return min(tournament, key=attrgetter("fitness"))
else:
raise Exception("No optimization specified (min or max).")