Repository: EC-KitY/EC-KitY (language: python)

Issue:
fixed typo in comment



Discussion / hints:

Fix patch:
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 00000000..ba77eac9
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,6 @@
+{
+    "[python]": {
+        "editor.defaultFormatter": "ms-python.python"
+    },
+    "python.formatting.provider": "none"
+}
\ No newline at end of file
diff --git a/eckity/__init__.py b/eckity/__init__.py
index a908d10c..6c6e5b28 100644
--- a/eckity/__init__.py
+++ b/eckity/__init__.py
@@ -2,4 +2,4 @@
 EC-KitY: Evolutionary Computation Tool Kit in Python
 """
 
-__version__ = '0.3.1'
+__version__ = '0.3.4'
diff --git a/eckity/creators/gp_creators/ramped_hh.py b/eckity/creators/gp_creators/ramped_hh.py
index db8c9b38..6d27e9f2 100644
--- a/eckity/creators/gp_creators/ramped_hh.py
+++ b/eckity/creators/gp_creators/ramped_hh.py
@@ -24,7 +24,7 @@ def __init__(self,
 			a tree creator that creates trees using the grow method
 
 		full_creator: FullCreator
-			a tree creator that creates trees using the grow method
+			a tree creator that creates trees using the full method
 
 		init_depth : (int, int)
 		Min and max depths of initial random trees. The default is None.
diff --git a/eckity/fitness/fitness.py b/eckity/fitness/fitness.py
index 7b097f69..f7bfd5c4 100644
--- a/eckity/fitness/fitness.py
+++ b/eckity/fitness/fitness.py
@@ -34,7 +34,7 @@ def __init__(self,
                  trials=None,
                  is_evaluated=False,
                  is_relative_fitness=False,
-                 should_cache_between_gens=False,
+                 should_cache_between_gens=True,
                  higher_is_better=False):
         self.context = context
         self.trials = trials
@@ -118,8 +118,6 @@ def set_not_evaluated(self):
         """
         Set this fitness score status to be not evaluated
         """
-        if not self.is_fitness_evaluated():
-            raise ValueError('Fitness already not evaluated')
         self._is_evaluated = False
 
     def is_fitness_evaluated(self):
diff --git a/eckity/fitness/simple_fitness.py b/eckity/fitness/simple_fitness.py
index c05bc227..decdbe57 100644
--- a/eckity/fitness/simple_fitness.py
+++ b/eckity/fitness/simple_fitness.py
@@ -36,8 +36,6 @@ def set_fitness(self, fitness):
         fitness: float
             the fitness score to be updated
         """
-        if self._is_evaluated:
-            raise AttributeError('fitness already evaluated and set to', self.fitness)
         self.fitness = fitness
         self._is_evaluated = True
 
diff --git a/eckity/genetic_encodings/ga/bit_string_vector.py b/eckity/genetic_encodings/ga/bit_string_vector.py
index 5bbc2856..623c1ad3 100644
--- a/eckity/genetic_encodings/ga/bit_string_vector.py
+++ b/eckity/genetic_encodings/ga/bit_string_vector.py
@@ -15,24 +15,31 @@ class BitStringVector(Vector):
     Parameters
     ----------
     fitness : Fitness
-        Fitness handler class, responsible of keeping the fitness value of the individual.
+        Fitness handler class.
+        Responsible of keeping the fitness value of the individual.
 
     length : int
         Vector length - the number of cells in the vector.
 
     bounds : tuple or list of tuples
-        Min/Max values for each vector cell (if of length n), or the minimum and maximum (if of length 1).
+        Min/Max values for each vector cell (if of length n),
+        or the minimum and maximum (if of length 1).
     """
 
     def __init__(self,
                  fitness,
                  length,
-                 bounds=(0, 1)):
-        super().__init__(fitness=fitness, length=length, bounds=bounds)
+                 bounds=(0, 1),
+                 vector=None):
+        super().__init__(fitness=fitness,
+                         length=length,
+                         bounds=bounds,
+                         vector=vector)
 
     def get_random_number_in_bounds(self, index):
         """
-        Return a random number of available cell values - 0 or 1, with equal probability.
+        Return a random number of available cell values (0 or 1),
+        with equal probability.
 
         Parameters
         ----------
@@ -44,23 +51,13 @@ def get_random_number_in_bounds(self, index):
         int
             random value according to bounds field
         """
-        # todo check if need to check bounds - is it tuple always?
         return randint(self.bounds[0], self.bounds[1])
 
     def bit_flip(self, index):
         """
-        Return a random number of available cell values - 0 or 1, with equal probability.
-
-        Parameters
-        ----------
-        index : int
-            cell index
-
-        Returns
-        -------
-        int
-            random value according to bounds field
+        Flip the bit in the given index.
         """
-        return self.bounds[1] if self.cell_value(index) == self.bounds[0] else self.bounds[0]
+        return self.bounds[1] \
+            if self.cell_value(index) == self.bounds[0] else self.bounds[0]
 
 # end class bit string vector
diff --git a/eckity/genetic_encodings/ga/float_vector.py b/eckity/genetic_encodings/ga/float_vector.py
index c22e9aa6..64d6d6ee 100644
--- a/eckity/genetic_encodings/ga/float_vector.py
+++ b/eckity/genetic_encodings/ga/float_vector.py
@@ -25,9 +25,10 @@ class FloatVector(Vector):
     """
     def __init__(self,
                  fitness,
-                 length=1,
-                 bounds=(0.0, 1.0)):
-        super().__init__(fitness=fitness, length=length, bounds=bounds)
+                 length,
+                 bounds=(0.0, 1.0),
+                 vector=None):
+        super().__init__(fitness=fitness, length=length, bounds=bounds, vector=vector)
 
     def get_random_number_in_bounds(self, index):
         """
diff --git a/eckity/genetic_encodings/ga/int_vector.py b/eckity/genetic_encodings/ga/int_vector.py
index 91d27f22..39dcd39e 100644
--- a/eckity/genetic_encodings/ga/int_vector.py
+++ b/eckity/genetic_encodings/ga/int_vector.py
@@ -29,8 +29,9 @@ class IntVector(Vector):
     def __init__(self,
                  fitness,
                  length,
-                 bounds=(MIN_BOUND, MAX_BOUND)):
-        super().__init__(fitness, length=length, bounds=bounds)
+                 bounds=(MIN_BOUND, MAX_BOUND),
+                 vector=None):
+        super().__init__(fitness, length=length, bounds=bounds, vector=vector)
 
     def get_random_number_in_bounds(self, index):
         """
diff --git a/eckity/genetic_encodings/ga/vector_individual.py b/eckity/genetic_encodings/ga/vector_individual.py
index 5546481f..00080396 100644
--- a/eckity/genetic_encodings/ga/vector_individual.py
+++ b/eckity/genetic_encodings/ga/vector_individual.py
@@ -27,7 +27,8 @@ class Vector(Individual):
     def __init__(self,
                  fitness,
                  bounds,
-                 length=1):
+                 length,
+                 vector=None):
         super().__init__(fitness)
 
         if (type(bounds) == tuple and len(bounds) != 2) \
@@ -36,7 +37,16 @@ def __init__(self,
 
         self.bounds = bounds
         self.length = length
-        self.vector = []
+        
+        if vector is None:
+            self.vector = []
+        
+        else:
+            if not isinstance(vector, list):
+                raise ValueError(f'Expected vector argument in Vector constructor to be a list, got {type(vector)}')
+            if len(vector) != length:
+                raise ValueError(f'Expected vector argument in Vector constructor to be of length {length}, got {len(vector)}')
+            self.vector = vector
 
     def size(self):
         """
diff --git a/eckity/genetic_operators/genetic_operator.py b/eckity/genetic_operators/genetic_operator.py
index b04ab289..1de64dc2 100644
--- a/eckity/genetic_operators/genetic_operator.py
+++ b/eckity/genetic_operators/genetic_operator.py
@@ -11,6 +11,8 @@ def __init__(self, probability=0.05, arity=0, events=None):
 
     def apply_operator(self, individuals):
         if uniform(0, 1) <= self.probability:
+            for individual in individuals:
+                individual.set_fitness_not_evaluated()
             return self.apply(individuals)
         return individuals
 
diff --git a/examples/vectorga/one_max/one_max_evaluator.py b/examples/vectorga/one_max/one_max_evaluator.py
new file mode 100644
index 00000000..39f82b14
--- /dev/null
+++ b/examples/vectorga/one_max/one_max_evaluator.py
@@ -0,0 +1,19 @@
+from eckity.evaluators.simple_individual_evaluator import SimpleIndividualEvaluator
+
+
+class OneMaxEvaluator(SimpleIndividualEvaluator):
+    def evaluate_individual(self, individual):
+        """
+            Compute the fitness value of a given individual.
+
+            Parameters
+            ----------
+            individual: Vector
+                The individual to compute the fitness value for.
+
+            Returns
+            -------
+            float
+                The evaluated fitness value of the given individual.
+        """
+        return sum(individual.vector)
diff --git a/examples/vectorga/one_max/one_max_problem.py b/examples/vectorga/one_max/one_max_problem.py
index 2feacb18..d75e7b59 100644
--- a/examples/vectorga/one_max/one_max_problem.py
+++ b/examples/vectorga/one_max/one_max_problem.py
@@ -10,23 +10,7 @@
 from eckity.subpopulation import Subpopulation
 from eckity.termination_checkers.threshold_from_target_termination_checker import ThresholdFromTargetTerminationChecker
 
-
-class OneMaxEvaluator(SimpleIndividualEvaluator):
-    def evaluate_individual(self, individual):
-        """
-            Compute the fitness value of a given individual.
-
-            Parameters
-            ----------
-            individual: Vector
-                The individual to compute the fitness value for.
-
-            Returns
-            -------
-            float
-                The evaluated fitness value of the given individual.
-        """
-        return sum(individual.vector)
+from one_max_evaluator import OneMaxEvaluator
 
 
 def main():
@@ -50,7 +34,7 @@ def main():
                       ]
                       ),
         breeder=SimpleBreeder(),
-        max_workers=4,
+        max_workers=1,
         max_generation=500,
 
         termination_checker=ThresholdFromTargetTerminationChecker(optimal=100, threshold=0.0),
diff --git a/examples/vectorga/one_max/one_max_problem_float.py b/examples/vectorga/one_max/one_max_problem_float.py
index 829aad32..c780261b 100644
--- a/examples/vectorga/one_max/one_max_problem_float.py
+++ b/examples/vectorga/one_max/one_max_problem_float.py
@@ -5,30 +5,13 @@
 from eckity.creators.ga_creators.float_vector_creator import GAFloatVectorCreator
 from eckity.evaluators.simple_individual_evaluator import SimpleIndividualEvaluator
 from eckity.genetic_operators.crossovers.vector_k_point_crossover import VectorKPointsCrossover
-from eckity.genetic_operators.mutations.vector_random_mutation import BitStringVectorFlipMutation, \
-    BitStringVectorNFlipMutation, FloatVectorUniformNPointMutation
+from eckity.genetic_operators.mutations.vector_random_mutation import FloatVectorUniformNPointMutation
 from eckity.genetic_operators.selections.tournament_selection import TournamentSelection
 from eckity.statistics.best_average_worst_statistics import BestAverageWorstStatistics
 from eckity.subpopulation import Subpopulation
 from eckity.termination_checkers.threshold_from_target_termination_checker import ThresholdFromTargetTerminationChecker
 
-
-class OneMaxEvaluator(SimpleIndividualEvaluator):
-    def evaluate_individual(self, individual):
-        """
-            Compute the fitness value of a given individual.
-
-            Parameters
-            ----------
-            individual: Vector
-                The individual to compute the fitness value for.
-
-            Returns
-            -------
-            float
-                The evaluated fitness value of the given individual.
-        """
-        return sum(individual.vector)
+from one_max_evaluator import OneMaxEvaluator
 
 
 def main():


Test patch:
diff --git a/eckity/genetic_encodings/ga/tests/__init__.py b/eckity/genetic_encodings/ga/tests/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/eckity/genetic_encodings/ga/tests/test_bit_string_vector.py b/eckity/genetic_encodings/ga/tests/test_bit_string_vector.py
new file mode 100644
index 00000000..7f3a7700
--- /dev/null
+++ b/eckity/genetic_encodings/ga/tests/test_bit_string_vector.py
@@ -0,0 +1,97 @@
+import pytest
+
+from eckity.fitness.simple_fitness import SimpleFitness
+from eckity.genetic_encodings.ga.bit_string_vector import BitStringVector
+
+
+class TestBitStringVector:
+    def test_vector_direct_initialization(self):
+        length = 5
+        cells = [0, 0, 1, 1, 1]
+        vec = BitStringVector(SimpleFitness(),
+                              length=length,
+                              vector=cells)
+        assert len(vec.vector) == length
+        assert vec.vector == cells
+
+    def test_bad_bounds(self):
+        length = 5
+        bounds = [(i, i + 1) for i in range(length)]
+
+        with pytest.raises(ValueError):
+            BitStringVector(SimpleFitness(), bounds=bounds, length=length + 1)
+        with pytest.raises(ValueError):
+            BitStringVector(SimpleFitness(), bounds=bounds, length=length - 1)
+
+    def test_replace_vector_part_bit_index0(self):
+        vec_len = 5
+        vec1 = BitStringVector(SimpleFitness(), length=vec_len)
+        vec1.vector = [0] * vec_len
+
+        vec2 = BitStringVector(SimpleFitness(), length=vec_len)
+        vec2.vector = [1] * vec_len
+
+        replaced_part_sz = 3
+        old_vec1_part = vec1.replace_vector_part(
+            vec2.vector[:replaced_part_sz], 0
+        )
+
+        expected1 = [1] * replaced_part_sz + [0] * (vec_len - replaced_part_sz)
+        assert vec1.vector == expected1
+
+        old_vec2_part = vec2.replace_vector_part(old_vec1_part, 0)
+        assert old_vec2_part == [1] * replaced_part_sz
+
+        expected2 = [0] * replaced_part_sz + [1] * (vec_len - replaced_part_sz)
+        assert vec2.vector == expected2
+
+    def test_replace_vector_part_bit_middle_index(self):
+        vec1 = BitStringVector(SimpleFitness(), length=4)
+        vec1.vector = [0, 1] * 2
+
+        vec2 = BitStringVector(SimpleFitness(), length=4)
+        vec2.vector = [1, 0] * 2
+
+        old_vec1_part = vec1.replace_vector_part(vec2.vector[1:3], 1)
+        assert vec1.vector == [0, 0, 1, 1]
+        assert old_vec1_part == [1, 0]
+
+        old_vec2_part = vec2.replace_vector_part(old_vec1_part, 1)
+        assert old_vec2_part == [0, 1]
+        assert vec2.vector == [1, 1, 0, 0]
+
+    def test_bit_flip(self):
+        vec1 = BitStringVector(SimpleFitness(), length=4)
+        init_vec = [0, 1, 0, 1]
+        vec1.vector = init_vec.copy()
+
+        assert vec1.bit_flip(0) == vec1.bit_flip(2) == 1
+        assert vec1.bit_flip(1) == vec1.bit_flip(3) == 0
+        assert init_vec == vec1.vector
+
+    def test_bit_get_rand_num_single_bounds(self):
+        bounds = (0, 1)
+        vec1 = BitStringVector(SimpleFitness(), bounds=bounds, length=5)
+
+        for _ in range(10 ** 3):
+            num = vec1.get_random_number_in_bounds(0)
+            assert type(num) == int and num == bounds[0] or num == bounds[1]
+
+    def test_get_vector_part_last_cell(self):
+        length = 2
+        v1 = BitStringVector(SimpleFitness(), length, vector=[0, 1])
+        assert v1.get_vector_part(length - 1, length) == [1]
+
+    def test_clone(self):
+        length = 2
+        score = 0.1
+        v1 = BitStringVector(SimpleFitness(), length, vector=[0, 1])
+        v1.fitness.set_fitness(score)
+
+        v2 = v1.clone()
+        assert v2.vector == v1.vector
+
+        # Check that fitness is evaluated and equal to original one
+        assert v2.fitness.get_pure_fitness() == score
+        assert v2.fitness.is_fitness_evaluated()
+
diff --git a/eckity/genetic_encodings/ga/tests/test_float_vector.py b/eckity/genetic_encodings/ga/tests/test_float_vector.py
new file mode 100644
index 00000000..74ee3b22
--- /dev/null
+++ b/eckity/genetic_encodings/ga/tests/test_float_vector.py
@@ -0,0 +1,29 @@
+import pytest
+
+from eckity.fitness.simple_fitness import SimpleFitness
+from eckity.genetic_encodings.ga.float_vector import FloatVector
+
+
+class TestFloatVector:
+	def test_vector_direct_initialization(self):
+		length = 5
+		cells = [0., 0., 1., 1., 1.]
+		vec = FloatVector(SimpleFitness(), length=length,vector=cells)
+		assert len(vec.vector) == length
+		assert vec.vector == cells
+	
+	def test_bad_bounds(self):
+		length = 5
+		bounds = [(i, i + 1) for i in range(length)]
+
+		with pytest.raises(ValueError):
+			FloatVector(SimpleFitness(), bounds=bounds, length=length + 1)
+		with pytest.raises(ValueError):
+			FloatVector(SimpleFitness(), bounds=bounds, length=length - 1)
+
+	def test_get_vector_part_last_cell(self):
+		length = 4
+		vec = FloatVector(SimpleFitness(), length, bounds=(1, 10))
+
+		vec.set_vector(list(range(1, 5)))
+		assert vec.get_vector_part(length - 1, length) == [4]
diff --git a/eckity/genetic_encodings/ga/tests/test_int_vector.py b/eckity/genetic_encodings/ga/tests/test_int_vector.py
new file mode 100644
index 00000000..6b56f694
--- /dev/null
+++ b/eckity/genetic_encodings/ga/tests/test_int_vector.py
@@ -0,0 +1,45 @@
+import pytest
+
+from eckity.fitness.simple_fitness import SimpleFitness
+from eckity.genetic_encodings.ga.int_vector import IntVector
+
+
+class TestIntVector:
+	def test_vector_direct_initialization(self):
+		length = 5
+		cells = [0, 1, 1, 1, 3]
+		vec = IntVector(SimpleFitness(), length=length, vector=cells)
+		assert len(vec.vector) == length
+		assert vec.vector == cells
+	
+	def test_bad_bounds(self):
+		length = 5
+		bounds = [(i, i + 1) for i in range(length)]
+
+		with pytest.raises(ValueError):
+			IntVector(SimpleFitness(), bounds=bounds, length=length + 1)
+		with pytest.raises(ValueError):
+			IntVector(SimpleFitness(), bounds=bounds, length=length - 1)
+
+	def test_int_get_rand_num_single_bounds(self):
+		bounds = (1, 5)
+		vec1 = IntVector(SimpleFitness(), bounds=bounds, length=5)
+
+		for _ in range(10 ** 3):
+			num = vec1.get_random_number_in_bounds(0)
+			assert type(num) == int and bounds[0] <= num <= bounds[1]
+
+	def test_int_get_rand_num_multi_bounds(self):
+		length = 5
+		bounds = [(i, i + 1) for i in range(length)]
+		vec1 = IntVector(SimpleFitness(), bounds=bounds, length=length)
+
+		for i in range(length):
+			num = vec1.get_random_number_in_bounds(i)
+			assert type(num) == int and bounds[i][0] <= num <= bounds[i][1]
+
+	def test_get_vector_part_last_cell(self):
+		length = 4
+		v1 = IntVector(SimpleFitness(), length, bounds=(1, 10))
+		v1.set_vector(list(range(1, 5)))
+		assert v1.get_vector_part(length - 1, length) == [4]
diff --git a/eckity/genetic_operators/crossovers/tests/test_crossover.py b/eckity/genetic_operators/crossovers/tests/test_crossover.py
new file mode 100644
index 00000000..732b3162
--- /dev/null
+++ b/eckity/genetic_operators/crossovers/tests/test_crossover.py
@@ -0,0 +1,24 @@
+import random
+from eckity.genetic_encodings.ga.int_vector import IntVector
+from eckity.genetic_operators.crossovers.vector_k_point_crossover \
+    import VectorKPointsCrossover
+from eckity.fitness.simple_fitness import SimpleFitness
+
+
+class TestCrossover:
+    def test_vector_two_point_crossover(self):
+        random.seed(0)
+        length = 4
+        v1 = IntVector(SimpleFitness(), length, bounds=(1, 10))
+        v1.set_vector(list(range(1, 5)))
+        v2 = IntVector(SimpleFitness(), length, bounds=(1, 10))
+        v2.set_vector(list(range(5, 9)))
+
+        # random sample will return [2, 3]
+        expected_v1 = [5, 6, 3, 8]
+        expected_v2 = [1, 2, 7, 4]
+
+        crossover = VectorKPointsCrossover(k=2)
+        crossover.apply([v1, v2])
+        assert v1.vector == expected_v1
+        assert v2.vector == expected_v2
diff --git a/eckity/genetic_operators/mutations/tests/__init__.py b/eckity/genetic_operators/mutations/tests/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/eckity/genetic_operators/mutations/tests/test_mutations.py b/eckity/genetic_operators/mutations/tests/test_mutations.py
new file mode 100644
index 00000000..3981f36f
--- /dev/null
+++ b/eckity/genetic_operators/mutations/tests/test_mutations.py
@@ -0,0 +1,72 @@
+from eckity.genetic_encodings.ga.float_vector import FloatVector
+from eckity.genetic_operators.mutations.vector_random_mutation \
+    import FloatVectorUniformNPointMutation, \
+    FloatVectorGaussNPointMutation, FloatVectorGaussOnePointMutation
+
+from eckity.fitness.simple_fitness import SimpleFitness
+from collections import Counter
+
+
+class TestMutations:
+    def test_uniform_float_n_point_mut(self):
+        length = 5
+        n_points = 3
+        vec1 = FloatVector(SimpleFitness(0.),
+                           length=length, bounds=(-100.0, 100.0))
+        init_vec = [0.0] * length
+        vec1.vector = init_vec.copy()
+        mut = FloatVectorUniformNPointMutation(n=n_points, probability=1.0)
+
+        mut.apply_operator([vec1])
+        cnt = Counter(vec1.vector)
+
+        assert len(cnt.keys()) == n_points + 1
+        assert cnt[0.0] == length - n_points
+
+    def test_gauss_float_n_point_mut(self):
+        length = 5
+        n_points = 3
+        vec = FloatVector(SimpleFitness(0.),
+                          length=length, bounds=(-100.0, 100.0))
+        init_vec = [0.0] * length
+        vec.vector = init_vec.copy()
+        mut = FloatVectorGaussNPointMutation(n=n_points, probability=1.0)
+
+        mut.apply_operator([vec])
+        cnt = Counter(vec.vector)
+
+        assert vec.vector != init_vec
+        assert len(cnt.keys()) == n_points + 1
+        assert cnt[0.0] == length - n_points
+
+    def test_gauss_mutation_success(self):
+        length = 4
+        vec = FloatVector(SimpleFitness(0.),
+                          length=length, bounds=(-100.0, 100.0))
+        init_vec = [2.0] * length
+        vec.vector = init_vec.copy()
+        mut = FloatVectorGaussOnePointMutation(probability=1.0)
+
+        mut.apply_operator([vec])
+        cnt = Counter(vec.vector)
+
+        assert vec.vector != init_vec
+        assert len(cnt.keys()) == 2
+        assert cnt[2.0] == length - 1
+
+    def test_gauss_mutation_fail(self):
+        length = 4
+        vec = FloatVector(SimpleFitness(0.), length=length, bounds=(-1.0, 1.0))
+        assert vec.fitness.is_fitness_evaluated()
+        
+        init_vec = [1.0] * length
+        vec.vector = init_vec.copy()
+        mut = FloatVectorGaussOnePointMutation(mu=1000, probability=1.0)
+
+        print(vec)
+        mut.apply_operator([vec])
+
+        cnt = Counter(vec.vector)
+
+        assert len(cnt.keys()) == 2
+        assert cnt[1.0] == length - 1
diff --git a/tests/test_vector.py b/tests/test_vector.py
deleted file mode 100644
index 6510d13a..00000000
--- a/tests/test_vector.py
+++ /dev/null
@@ -1,222 +0,0 @@
-from collections import Counter
-
-import pytest
-import random
-
-from eckity.fitness.simple_fitness import SimpleFitness
-from eckity.genetic_encodings.ga.vector_individual import Vector
-from eckity.genetic_encodings.ga.bit_string_vector import BitStringVector
-from eckity.genetic_encodings.ga.float_vector import FloatVector
-from eckity.genetic_encodings.ga.int_vector import IntVector
-from eckity.genetic_operators.mutations.vector_random_mutation import FloatVectorGaussOnePointMutation, \
-	FloatVectorUniformNPointMutation, FloatVectorGaussNPointMutation, IntVectorOnePointMutation, \
-	BitStringVectorNFlipMutation, IntVectorNPointMutation
-from eckity.genetic_operators.crossovers.vector_k_point_crossover import VectorKPointsCrossover
-
-@pytest.fixture(autouse=True)
-def run_before_and_after_tests():
-	"""Fixture to execute asserts before and after a test is run"""
-	# Setup
-	random.seed(0)
-
-	yield # this is where the testing happens
-
-	# Teardown
-	pass
-
-class TestVector:
-	def test_bad_bounds(self):
-		length = 5
-		bounds = [(i, i + 1) for i in range(length)]
-
-		with pytest.raises(ValueError):
-			FloatVector(SimpleFitness(), bounds=bounds, length=length + 1)
-		with pytest.raises(ValueError):
-			FloatVector(SimpleFitness(), bounds=bounds, length=length - 1)
-
-	def test_replace_vector_part_bit_index0(self):
-		vec_len = 5
-		vec1 = BitStringVector(SimpleFitness(), length=vec_len)
-		vec1.vector = [0] * vec_len
-
-		vec2 = BitStringVector(SimpleFitness(), length=vec_len)
-		vec2.vector = [1] * vec_len
-
-		replaced_part_size = 3
-		old_vec1_part = vec1.replace_vector_part(vec2.vector[:replaced_part_size], 0)
-		assert vec1.vector == [1] * replaced_part_size + [0] * (vec_len - replaced_part_size)
-
-		old_vec2_part = vec2.replace_vector_part(old_vec1_part, 0)
-		assert old_vec2_part == [1] * replaced_part_size
-		assert vec2.vector == [0] * replaced_part_size + [1] * (vec_len - replaced_part_size)
-
-	def test_replace_vector_part_bit_middle_index(self):
-		vec1 = BitStringVector(SimpleFitness(), length=4)
-		vec1.vector = [0, 1] * 2
-
-		vec2 = BitStringVector(SimpleFitness(), length=4)
-		vec2.vector = [1, 0] * 2
-
-		old_vec1_part = vec1.replace_vector_part(vec2.vector[1:3], 1)
-		assert vec1.vector == [0, 0, 1, 1]
-		assert old_vec1_part == [1, 0]
-
-		old_vec2_part = vec2.replace_vector_part(old_vec1_part, 1)
-		assert old_vec2_part == [0, 1]
-		assert vec2.vector == [1, 1, 0, 0]
-
-	def test_bit_flip(self):
-		vec1 = BitStringVector(SimpleFitness(), length=4)
-		init_vec = [0, 1, 0, 1]
-		vec1.vector = init_vec.copy()
-
-		assert vec1.bit_flip(0) == vec1.bit_flip(2) == 1
-		assert vec1.bit_flip(1) == vec1.bit_flip(3) == 0
-		assert init_vec == vec1.vector
-
-	def test_gauss_mutation_success(self):
-		length = 4
-		vec1 = FloatVector(SimpleFitness(), length=length, bounds=(-100.0, 100.0))
-		init_vec = [2.0] * length
-		vec1.vector = init_vec.copy()
-		mut = FloatVectorGaussOnePointMutation()
-
-		mut.apply_operator([vec1])
-		cnt = Counter(vec1.vector)
-
-		assert len(cnt.keys()) == 2
-		assert cnt[2.0] == length - 1
-
-	def test_gauss_mutation_fail(self):
-		length = 4
-		vec1 = FloatVector(SimpleFitness(), length=length, bounds=(-1.0, 1.0))
-		init_vec = [1.0] * length
-		vec1.vector = init_vec.copy()
-		mut = FloatVectorGaussOnePointMutation(mu=1000)
-
-		mut.apply_operator([vec1])
-		cnt = Counter(vec1.vector)
-
-		assert len(cnt.keys()) == 2
-		assert cnt[1.0] == length - 1
-
-	def test_float_get_rand_num_single_bounds(self):
-		bounds = (-1.0, 1.0)
-		vec1 = FloatVector(SimpleFitness(), bounds=bounds, length=5)
-
-		for _ in range(10 ** 3):
-			num = vec1.get_random_number_in_bounds(0)
-			assert type(num) == float and bounds[0] <= num <= bounds[1]
-
-	def test_int_get_rand_num_single_bounds(self):
-		bounds = (1, 5)
-		vec1 = IntVector(SimpleFitness(), bounds=bounds, length=5)
-
-		for _ in range(10 ** 3):
-			num = vec1.get_random_number_in_bounds(0)
-			assert type(num) == int and bounds[0] <= num <= bounds[1]
-
-	def test_bit_get_rand_num_single_bounds(self):
-		bounds = (0, 1)
-		vec1 = BitStringVector(SimpleFitness(), bounds=bounds, length=5)
-
-		for _ in range(10 ** 3):
-			num = vec1.get_random_number_in_bounds(0)
-			assert type(num) == int and num == bounds[0] or num == bounds[1]
-
-	def test_float_get_rand_num_multi_bounds(self):
-		length = 5
-		bounds = [(i, i + 1) for i in range(length)]
-		vec1 = FloatVector(SimpleFitness(), bounds=bounds, length=length)
-
-		for i in range(length):
-			num = vec1.get_random_number_in_bounds(i)
-			assert type(num) == float and bounds[i][0] <= num <= bounds[i][1]
-
-	def test_int_get_rand_num_multi_bounds(self):
-		length = 5
-		bounds = [(i, i + 1) for i in range(length)]
-		vec1 = IntVector(SimpleFitness(), bounds=bounds, length=length)
-
-		for i in range(length):
-			num = vec1.get_random_number_in_bounds(i)
-			assert type(num) == int and bounds[i][0] <= num <= bounds[i][1]
-
-	def test_uniform_bit_n_point_mut(self):
-		length = 5
-		n_points = 3
-		vec1 = BitStringVector(SimpleFitness(), length=length)
-		init_vec = [0] * length
-		vec1.vector = init_vec.copy()
-		mut = BitStringVectorNFlipMutation(n=n_points, probability_for_each=1.0)
-
-		mut.apply_operator([vec1])
-		cnt = Counter(vec1.vector)
-
-		assert len(cnt.keys()) == 2
-		assert cnt[0] == length - n_points
-		assert cnt[1] == n_points
-
-	def test_uniform_int_n_point_mut(self):
-		length = 5
-		n_points = 3
-		vec1 = IntVector(SimpleFitness(), length=length, bounds=(-10000, 10000))
-		init_vec = [0] * length
-		vec1.vector = init_vec.copy()
-		mut = IntVectorNPointMutation(n=n_points)
-
-		mut.apply_operator([vec1])
-		cnt = Counter(vec1.vector)
-
-		assert len(cnt.keys()) == n_points + 1
-		assert cnt[0] == length - n_points
-
-	def test_uniform_float_n_point_mut(self):
-		length = 5
-		n_points = 3
-		vec1 = FloatVector(SimpleFitness(), length=length, bounds=(-100.0, 100.0))
-		init_vec = [0.0] * length
-		vec1.vector = init_vec.copy()
-		mut = FloatVectorUniformNPointMutation(n=n_points)
-
-		mut.apply_operator([vec1])
-		cnt = Counter(vec1.vector)
-
-		assert len(cnt.keys()) == n_points + 1
-		assert cnt[0.0] == length - n_points
-
-	def test_gauss_float_n_point_mut(self):
-		length = 5
-		n_points = 3
-		vec1 = FloatVector(SimpleFitness(), length=length, bounds=(-100.0, 100.0))
-		init_vec = [0.0] * length
-		vec1.vector = init_vec.copy()
-		mut = FloatVectorGaussNPointMutation(n=n_points)
-
-		mut.apply_operator([vec1])
-		cnt = Counter(vec1.vector)
-
-		assert len(cnt.keys()) == n_points + 1
-		assert cnt[0.0] == length - n_points
-
-	def test_vector_two_point_crossover(self):
-		length = 4
-		v1 = IntVector(SimpleFitness(), length, bounds=(1, 10))
-		v1.set_vector(list(range(1, 5)))
-		v2 = IntVector(SimpleFitness(), length, bounds=(1, 10))
-		v2.set_vector(list(range(5, 9)))
-		
-		# random sample will return [2, 3]
-		expected_v1 = [5, 6, 3, 8]
-		expected_v2 = [1, 2, 7, 4]
-
-		crossover = VectorKPointsCrossover(k=2)
-		crossover.apply([v1, v2])
-		assert v1.vector == expected_v1
-		assert v2.vector == expected_v2
-
-	def test_get_vector_part_last_cell(self):
-		length = 4
-		v1 = IntVector(SimpleFitness(), length, bounds=(1, 10))
-		v1.set_vector(list(range(1, 5)))
-		assert v1.get_vector_part(length - 1, length) == [4]