Source code for surrogate.selection.selTournamentDCD
# Copyright 2016 Quan Pan
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Author: Quan Pan <quanpan302@hotmail.com>
# License: Apache License, Version 2.0
# Create: 2016-12-02
import random
[docs]def selTournamentDCD(individuals, k):
"""Tournament selection based on dominance (D) between two individuals, if
the two individuals do not interdominate the selection is made
based on crowding distance (CD). The *individuals* sequence length has to
be a multiple of 4. Starting from the beginning of the selected
individuals, two consecutive individuals will be different (assuming all
individuals in the input list are unique). Each individual from the input
list won't be selected more than twice.
This selection requires the individuals to have a :attr:`crowding_dist`
attribute, which can be set by the :func:`assignCrowdingDist` function.
:param individuals: A list of individuals to select from.
:param k: The number of individuals to select.
:returns: A list of selected individuals.
"""
def tourn(ind1, ind2):
if ind1.fitness.dominates(ind2.fitness):
return ind1
elif ind2.fitness.dominates(ind1.fitness):
return ind2
if ind1.fitness.crowding_dist < ind2.fitness.crowding_dist:
return ind2
elif ind1.fitness.crowding_dist > ind2.fitness.crowding_dist:
return ind1
if random.random() <= 0.5:
return ind1
return ind2
individuals_1 = random.sample(individuals, len(individuals))
individuals_2 = random.sample(individuals, len(individuals))
chosen = []
for i in xrange(0, k, 4):
chosen.append(tourn(individuals_1[i], individuals_1[i + 1]))
chosen.append(tourn(individuals_1[i + 2], individuals_1[i + 3]))
chosen.append(tourn(individuals_2[i], individuals_2[i + 1]))
chosen.append(tourn(individuals_2[i + 2], individuals_2[i + 3]))
return chosen