# Path: gaft/components/binary_individual.py
# class BinaryIndividual(IndividualBase):
#     '''
#     Class for individual in population. Random solution will be initialized
#     by default.
# 
#     :param ranges: value ranges for all entries in solution.
#     :type ranges: tuple list
# 
#     :param eps: decrete precisions for binary encoding, default is 0.001.
#     :type eps: float or float list (with the same length with ranges)
# 
#     .. Note:
# 
#         The decrete precisions for different components in varants may be
#         adjusted automatically (possible precision loss) if eps and ranges
#         are not appropriate.
#     '''
#     def __init__(self, ranges, eps=0.001):
#         super(self.__class__, self).__init__(ranges, eps)
# 
#         # Lengths for all binary sequence in chromsome and adjusted decrete precisions.
#         self.lengths = []
# 
#         for i, ((a, b), eps) in enumerate(zip(self.ranges, self.eps)):
#             length = int(log2((b - a)/eps))
#             precision = (b - a)/(2**length)
#             self.lengths.append(length)
#             self.precisions[i] = precision
# 
#         # The start and end indices for each gene segment for entries in solution.
#         self.gene_indices = self._get_gene_indices()
# 
#         # Initialize individual randomly.
#         self.init()
# 
#     def encode(self):
#         ''' Encode solution to gene sequence in individual using different encoding.
#         '''
#         chromsome = []
#         for var, (a, _), length, eps in zip(self.solution, self.ranges,
#                                             self.lengths, self.precisions):
#             chromsome.extend(self.binarize(var-a, eps, length))
# 
#         return chromsome
# 
#     def decode(self):
#         ''' Decode gene sequence to solution of target function.
#         '''
#         solution =  [self.decimalize(self.chromsome[start: end], eps, lower_bound)
#                      for (start, end), (lower_bound, _), eps in
#                      zip(self.gene_indices, self.ranges, self.precisions)]
#         return solution
# 
#     def _get_gene_indices(self):
#         '''
#         Helper function to get gene slice indices.
#         '''
#         end_indices = list(accumulate(self.lengths))
#         start_indices = [0] + end_indices[: -1]
#         return list(zip(start_indices, end_indices))
# 
#     @staticmethod
#     def binarize(decimal, eps, length):
#         ''' Helper function to convert a float to binary sequence.
# 
#         :param decimal: the decimal number to be converted
#         :type decimal: float
# 
#         :param eps: the decrete precision of binary sequence
#         :type eps: float
# 
#         :param length: the length of binary sequence.
#         :type length: int
#         '''
#         n = int(decimal/eps)
#         bin_str = '{:0>{}b}'.format(n, length)
#         return [int(i) for i in bin_str]
# 
#     @staticmethod
#     def decimalize(binary, eps, lower_bound):
#         ''' Helper function to convert a binary sequence back to decimal number.
# 
#         :param binary: The binary list to be converted
#         :type binary: list of int
# 
#         :param eps: the decrete precision of binary sequence
#         :type eps: float
# 
#         :param lower_bound: the lower bound for decimal number
#         :type lower_bound: float
#         '''
#         bin_str = ''.join([str(bit) for bit in binary])
#         return lower_bound + int(bin_str, 2)*eps
# 
# Path: gaft/operators/crossover/uniform_crossover.py
# class UniformCrossover(Crossover):
#     ''' Crossover operator with uniform crossover algorithm,
#     see https://en.wikipedia.org/wiki/Crossover_(genetic_algorithm)
# 
#     :param pc: The probability of crossover (usaully between 0.25 ~ 1.0)
#     :type pc: float in (0.0, 1.0]
# 
#     :param pe: Gene exchange probability.
#     :type pe: float in range (0.0, 1.0]
#     '''
#     def __init__(self, pc, pe=0.5):
#         if pc <= 0.0 or pc > 1.0:
#             raise ValueError('Invalid crossover probability')
#         self.pc = pc
# 
#         if pe <= 0.0 or pe > 1.0:
#             raise ValueError('Invalid genome exchange probability')
#         self.pe = pe
# 
#     def cross(self, father, mother):
#         ''' Cross chromsomes of parent using uniform crossover method.
# 
#         :param population: Population where the selection operation occurs.
#         :type population: :obj:`gaft.components.Population`
# 
#         :return: Selected parents (a father and a mother)
#         :rtype: list of :obj:`gaft.components.IndividualBase`
#         '''
#         do_cross = True if random() <= self.pc else False
# 
#         if not do_cross:
#             return father.clone(), mother.clone()
# 
#         # Chromsomes for two children.
#         chrom1 = deepcopy(father.chromsome)
#         chrom2 = deepcopy(mother.chromsome)
# 
#         for i, (g1, g2) in enumerate(zip(chrom1, chrom2)):
#             do_exchange = True if random() < self.pe else False
#             if do_exchange:
#                 chrom1[i], chrom2[i] = g2, g1
# 
#         child1, child2 = father.clone(), father.clone()
#         child1.init(chromsome=chrom1)
#         child2.init(chromsome=chrom2)
# 
#         return child1, child2


import unittest
from gaft.components import BinaryIndividual
from gaft.operators.crossover.uniform_crossover import UniformCrossover
#!/usr/bin/env python
# -*- coding: utf-8 -*-

''' Test case for built-in Uniform Crossover operator.
'''



class UniformCrossoverTest(unittest.TestCase):

    def setUp(self):
        self.maxDiff

    def test_cross(self):
        ''' Make sure individuals can be crossed correctly.
        '''
        father = BinaryIndividual(ranges=[(0, 1)]).init(solution=[0.398])

# Path: gaft/components/binary_individual.py
# class BinaryIndividual(IndividualBase):
#     '''
#     Class for individual in population. Random solution will be initialized
#     by default.
# 
#     :param ranges: value ranges for all entries in solution.
#     :type ranges: tuple list
# 
#     :param eps: decrete precisions for binary encoding, default is 0.001.
#     :type eps: float or float list (with the same length with ranges)
# 
#     .. Note:
# 
#         The decrete precisions for different components in varants may be
#         adjusted automatically (possible precision loss) if eps and ranges
#         are not appropriate.
#     '''
#     def __init__(self, ranges, eps=0.001):
#         super(self.__class__, self).__init__(ranges, eps)
# 
#         # Lengths for all binary sequence in chromsome and adjusted decrete precisions.
#         self.lengths = []
# 
#         for i, ((a, b), eps) in enumerate(zip(self.ranges, self.eps)):
#             length = int(log2((b - a)/eps))
#             precision = (b - a)/(2**length)
#             self.lengths.append(length)
#             self.precisions[i] = precision
# 
#         # The start and end indices for each gene segment for entries in solution.
#         self.gene_indices = self._get_gene_indices()
# 
#         # Initialize individual randomly.
#         self.init()
# 
#     def encode(self):
#         ''' Encode solution to gene sequence in individual using different encoding.
#         '''
#         chromsome = []
#         for var, (a, _), length, eps in zip(self.solution, self.ranges,
#                                             self.lengths, self.precisions):
#             chromsome.extend(self.binarize(var-a, eps, length))
# 
#         return chromsome
# 
#     def decode(self):
#         ''' Decode gene sequence to solution of target function.
#         '''
#         solution =  [self.decimalize(self.chromsome[start: end], eps, lower_bound)
#                      for (start, end), (lower_bound, _), eps in
#                      zip(self.gene_indices, self.ranges, self.precisions)]
#         return solution
# 
#     def _get_gene_indices(self):
#         '''
#         Helper function to get gene slice indices.
#         '''
#         end_indices = list(accumulate(self.lengths))
#         start_indices = [0] + end_indices[: -1]
#         return list(zip(start_indices, end_indices))
# 
#     @staticmethod
#     def binarize(decimal, eps, length):
#         ''' Helper function to convert a float to binary sequence.
# 
#         :param decimal: the decimal number to be converted
#         :type decimal: float
# 
#         :param eps: the decrete precision of binary sequence
#         :type eps: float
# 
#         :param length: the length of binary sequence.
#         :type length: int
#         '''
#         n = int(decimal/eps)
#         bin_str = '{:0>{}b}'.format(n, length)
#         return [int(i) for i in bin_str]
# 
#     @staticmethod
#     def decimalize(binary, eps, lower_bound):
#         ''' Helper function to convert a binary sequence back to decimal number.
# 
#         :param binary: The binary list to be converted
#         :type binary: list of int
# 
#         :param eps: the decrete precision of binary sequence
#         :type eps: float
# 
#         :param lower_bound: the lower bound for decimal number
#         :type lower_bound: float
#         '''
#         bin_str = ''.join([str(bit) for bit in binary])
#         return lower_bound + int(bin_str, 2)*eps
# 
# Path: gaft/operators/crossover/uniform_crossover.py
# class UniformCrossover(Crossover):
#     ''' Crossover operator with uniform crossover algorithm,
#     see https://en.wikipedia.org/wiki/Crossover_(genetic_algorithm)
# 
#     :param pc: The probability of crossover (usaully between 0.25 ~ 1.0)
#     :type pc: float in (0.0, 1.0]
# 
#     :param pe: Gene exchange probability.
#     :type pe: float in range (0.0, 1.0]
#     '''
#     def __init__(self, pc, pe=0.5):
#         if pc <= 0.0 or pc > 1.0:
#             raise ValueError('Invalid crossover probability')
#         self.pc = pc
# 
#         if pe <= 0.0 or pe > 1.0:
#             raise ValueError('Invalid genome exchange probability')
#         self.pe = pe
# 
#     def cross(self, father, mother):
#         ''' Cross chromsomes of parent using uniform crossover method.
# 
#         :param population: Population where the selection operation occurs.
#         :type population: :obj:`gaft.components.Population`
# 
#         :return: Selected parents (a father and a mother)
#         :rtype: list of :obj:`gaft.components.IndividualBase`
#         '''
#         do_cross = True if random() <= self.pc else False
# 
#         if not do_cross:
#             return father.clone(), mother.clone()
# 
#         # Chromsomes for two children.
#         chrom1 = deepcopy(father.chromsome)
#         chrom2 = deepcopy(mother.chromsome)
# 
#         for i, (g1, g2) in enumerate(zip(chrom1, chrom2)):
#             do_exchange = True if random() < self.pe else False
#             if do_exchange:
#                 chrom1[i], chrom2[i] = g2, g1
# 
#         child1, child2 = father.clone(), father.clone()
#         child1.init(chromsome=chrom1)
#         child2.init(chromsome=chrom2)
# 
#         return child1, child2


# Path: gaft/tests/uniform_crossover_test.py
import unittest
from gaft.components import BinaryIndividual
from gaft.operators.crossover.uniform_crossover import UniformCrossover

#!/usr/bin/env python
# -*- coding: utf-8 -*-

''' Test case for built-in Uniform Crossover operator.
'''



class UniformCrossoverTest(unittest.TestCase):

    def setUp(self):
        self.maxDiff

    def test_cross(self):
        ''' Make sure individuals can be crossed correctly.
        '''
        father = BinaryIndividual(ranges=[(0, 1)]).init(solution=[0.398])

        mother = BinaryIndividual(ranges=[(0, 1)]).init(solution=[0.298])