Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fine grained tournament selection #687

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion deap/tools/mutation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import random

from itertools import repeat
from past.builtins import xrange
#from past.builtins import xrange

try:
from collections.abc import Sequence
Expand Down
47 changes: 46 additions & 1 deletion deap/tools/selection.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import math
import random
import numpy as np

Expand Down Expand Up @@ -67,6 +68,49 @@ def selTournament(individuals, k, tournsize, fit_attr="fitness"):
chosen.append(max(aspirants, key=attrgetter(fit_attr)))
return chosen

def selTournamentFineGrained(individuals, k, fgtournsize, fit_attr="fitness"):
"""The ratio between exploration and exploitation governs the search process.
Level of exploration(looking for new solutions) and exploitation (using previously
acquired knowledge) is determined by the tournament size.
Very often, the search process converges too slow with smaller tournament size and too fast with bigger tournament size.
Fine Grained Tournament Selection (denoted as FGTS) preserves good features of the tournament selection and
(at the same time) allows that setting of the ratio between exploration and exploitation becomes more precise.
FGTS is controlled by real value parameter *fgtournsize* (the desired average tournament size) instead of
the integer parameter.
Similarly to the tournament selection, an individual is chosen if it is the best individual on the tournament.
However, unlike tournament selection, size of the tournament is not unique in the whole population, i.e., tournaments
with different number of competitors can be held within one step of the selection. (see [Filipovic2003fgts]_)

Procedure selects the best individual among (in average) *fgtournsize* randomly
chosen individuals, *k* times. The list returned contains
references to the input *individuals*.

:param individuals: A list of individuals to select from.
:param k: The number of individuals to select.
:param fgtournsize: The average number of individuals participating in each
tournament.
:param fit_attr: The attribute of individuals to use as selection criterion
:returns: A list of selected individuals.

This function uses the :func:`~random.choice` function from the python base
:mod:`random` module.

.. [Filipovic2003fgts] Filipovic, 2003, Fine-grained Tournament Selection Operator in Genetic Algorithms.
Available from: https://www.cai.sk/ojs/index.php/cai/article/view/452 """
chosen = []
tournsizeminus = int(math.floor(fgtournsize))
tournsizeplus = tournsizeminus + 1
kminus = int(math.ceil(k*(tournsizeplus - fgtournsize)) )
kplus = k - kminus
for i in range(kminus):
aspirants = selRandom(individuals, tournsizeminus)
chosen.append(max(aspirants, key=attrgetter(fit_attr)))
for i in range(kplus):
aspirants = selRandom(individuals, tournsizeplus)
chosen.append(max(aspirants, key=attrgetter(fit_attr)))
return chosen


def selRoulette(individuals, k, fit_attr="fitness"):
"""Select *k* individuals from the input *individuals* using *k*
spins of a roulette. The selection is made by looking only at the first
Expand Down Expand Up @@ -317,6 +361,7 @@ def selAutomaticEpsilonLexicase(individuals, k):


__all__ = ['selRandom', 'selBest', 'selWorst', 'selRoulette',
'selTournament', 'selDoubleTournament', 'selStochasticUniversalSampling',
'selTournament', 'selTournamentFineGrained',
'selDoubleTournament', 'selStochasticUniversalSampling',
'selLexicase', 'selEpsilonLexicase', 'selAutomaticEpsilonLexicase']

13 changes: 13 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[tool.poetry]
name = "deap"
version = "0.2.0"
description = "forked DEAP"
authors = ["Vladimir Filipovic <vladofilipovic@hotmail.com>"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.10"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"