eckity.genetic_encodings.ga.vector_individual

This module implements the vector class.

  1"""
  2This module implements the vector class.
  3"""
  4from abc import abstractmethod
  5from random import randint
  6
  7from eckity.individual import Individual
  8
  9
 10class Vector(Individual):
 11    """
 12    A Vector individual representation for Genetic Algorithms operations.
 13    It is represented by a list of values (integers, floats, etc.)
 14
 15    Parameters
 16    ----------
 17    fitness : Fitness
 18        Fitness handler class, responsible of keeping the fitness value of the individual.
 19
 20    length : int
 21        Vector length - the number of cells in the vector.
 22
 23    bounds : list of tuples
 24        Min/Max values for each vector cell (if of length n), or the minimum and maximum (if of length 1).
 25    """
 26
 27    def __init__(self,
 28                 fitness,
 29                 bounds,
 30                 length,
 31                 vector=None):
 32        super().__init__(fitness)
 33
 34        if (type(bounds) == tuple and len(bounds) != 2) \
 35                or (type(bounds) == list and len(bounds) != length):
 36            raise ValueError(f'Bounds must be either a tuple of size 2 or a list of {length} tuples')
 37
 38        self.bounds = bounds
 39        self.length = length
 40        
 41        if vector is None:
 42            self.vector = []
 43        
 44        else:
 45            if not isinstance(vector, list):
 46                raise ValueError(f'Expected vector argument in Vector constructor to be a list, got {type(vector)}')
 47            if len(vector) != length:
 48                raise ValueError(f'Expected vector argument in Vector constructor to be of length {length}, got {len(vector)}')
 49            self.vector = vector
 50
 51    def size(self):
 52        """
 53        Compute size of vector.
 54
 55        Returns
 56        -------
 57        int
 58            vector size (= number of cells).
 59        """
 60        return len(self.vector)
 61
 62    def get_bounds(self):
 63        """
 64        Get vector bounds
 65
 66        Returns
 67        -------
 68        tuple of (Number, Number)
 69            vector bounds.
 70        """
 71        return self.bounds
 72
 73    def check_if_in_bounds(self):
 74        """
 75        Check if all vector cells are in bounds
 76
 77        Returns
 78        -------
 79        bool
 80            True if all vector cells are in bounds, False otherwise
 81        """
 82        for i in range(self.size()):
 83            if len(self.bounds) == 2:
 84                if (self.vector[i] < self.bounds[0]) or (self.vector[i] > self.bounds[1]):
 85                    return False
 86            else:
 87                if (self.vector[i] < self.bounds[i][0]) or (self.vector[i] > self.bounds[i][1]):
 88                    return False
 89        return True
 90
 91    def add_cell(self, cell):
 92        """
 93        Add a new cell to the vector (and increase its size by 1)
 94
 95        Returns
 96        -------
 97        None
 98        """
 99        self.vector.append(cell)
100        self.length += 1
101
102    def empty_vector(self):
103        """
104        Convert the vector to an empty vector
105
106        Returns
107        -------
108        None
109        """
110        self.vector = []
111        self.length = 0
112
113    def set_vector(self, vector):
114        """
115        Set genome to the given vector genome
116
117        Parameters
118        -------
119        vector: list
120            `other` vector genome
121
122        Returns
123        -------
124        None
125        """
126        self.vector = vector
127        self.length = len(vector)
128
129    def get_vector(self):
130        """
131        Return self vector genome
132
133        Returns
134        -------
135        list
136            vector genome
137        """
138        return self.vector
139
140    def random_vector_part(self):
141        """
142        Get a random part of the vector
143
144        Returns
145        -------
146        list
147            sub-vector genome
148        """
149        # todo add tests to make sure this logic works
150        rnd_i = randint(0, self.size() - 1)
151        end_i = randint(rnd_i, self.size() - 1)
152        return self.vector[rnd_i:end_i + 1]
153
154    def replace_vector_part_random(self, inserted_part):
155        """
156        Replace a given vector part in a random position
157
158        Parameters
159        -------
160        inserted_part: list
161            new vector part to be inserted
162
163        Returns
164        -------
165        list
166            previous vector part of this vector genome
167        """
168        index = randint(0, self.size() - len(inserted_part))  # select a random index
169        end_i = index + len(inserted_part)
170        replaced_part = self.vector[index:end_i]
171        self.vector = self.vector[:index] + inserted_part + self.vector[end_i:]
172        return replaced_part
173
174    def replace_vector_part(self, inserted_part, start_index):
175        """
176        Replace a given vector part in a given position
177
178        Parameters
179        -------
180        inserted_part: list
181            new vector part to be inserted
182
183        start_index: int
184            starting position to insert the new vector part from
185
186        Returns
187        -------
188        list
189            previous vector part of this vector genome
190        """
191        end_i = start_index + len(inserted_part)
192        replaced_part = self.vector[start_index:end_i]
193        self.vector = self.vector[:start_index] + inserted_part + self.vector[end_i:]
194        return replaced_part
195
196    def get_vector_part(self, index, end_i):
197        """
198        Return vector part from `index` to `end_i`
199
200        Parameters
201        -------
202        index: int
203            starting index
204
205        end_i: int
206            end index
207
208        Returns
209        -------
210        list
211            sub-vector genome
212        """
213        return self.vector[index:end_i]
214
215    def cell_value(self, index):
216        """
217        Get vector cell value in a given index
218
219        Parameters
220        -------
221        index: int
222            cell index
223
224        Returns
225        -------
226        object
227            vector cell value
228        """
229        return self.vector[index]
230
231    def set_cell_value(self, index, value):
232        """
233        Set vector cell value in a given index
234
235        Parameters
236        -------
237        index: int
238            cell index
239
240        value: object
241            new cell value
242
243        Returns
244        -------
245        None
246        """
247        self.vector[index] = value
248
249    @abstractmethod
250    def get_random_number_in_bounds(self, index):
251        """
252        Returns a random value in vector bounds
253
254        Parameters
255        -------
256        index: int
257            cell index
258
259        Returns
260        -------
261        object
262            vector cell value
263        """
264        raise NotImplementedError("get_random_number is an abstract method in vector individual")
265
266    def execute(self, *args, **kwargs):
267        """
268        Execute the vector.
269        Input is a numpy array or keyword arguments (but not both).
270
271        Parameters
272        ----------
273        args : arguments
274            A numpy array, this is mostly relevant to GP representation.
275
276        kwargs : keyword arguments
277            Input to program, this is mostly relevant to GP representation.
278
279        Returns
280        -------
281        object
282            Vector (genome) of this individual.
283        """
284        return self.get_vector()
285
286    def show(self):
287        """
288        Print out a simple textual representation of the vector.
289
290        Returns
291        -------
292        None.
293        """
294        print(self.vector)
295
296# end class Vector
class Vector(eckity.individual.Individual):
 11class Vector(Individual):
 12    """
 13    A Vector individual representation for Genetic Algorithms operations.
 14    It is represented by a list of values (integers, floats, etc.)
 15
 16    Parameters
 17    ----------
 18    fitness : Fitness
 19        Fitness handler class, responsible of keeping the fitness value of the individual.
 20
 21    length : int
 22        Vector length - the number of cells in the vector.
 23
 24    bounds : list of tuples
 25        Min/Max values for each vector cell (if of length n), or the minimum and maximum (if of length 1).
 26    """
 27
 28    def __init__(self,
 29                 fitness,
 30                 bounds,
 31                 length,
 32                 vector=None):
 33        super().__init__(fitness)
 34
 35        if (type(bounds) == tuple and len(bounds) != 2) \
 36                or (type(bounds) == list and len(bounds) != length):
 37            raise ValueError(f'Bounds must be either a tuple of size 2 or a list of {length} tuples')
 38
 39        self.bounds = bounds
 40        self.length = length
 41        
 42        if vector is None:
 43            self.vector = []
 44        
 45        else:
 46            if not isinstance(vector, list):
 47                raise ValueError(f'Expected vector argument in Vector constructor to be a list, got {type(vector)}')
 48            if len(vector) != length:
 49                raise ValueError(f'Expected vector argument in Vector constructor to be of length {length}, got {len(vector)}')
 50            self.vector = vector
 51
 52    def size(self):
 53        """
 54        Compute size of vector.
 55
 56        Returns
 57        -------
 58        int
 59            vector size (= number of cells).
 60        """
 61        return len(self.vector)
 62
 63    def get_bounds(self):
 64        """
 65        Get vector bounds
 66
 67        Returns
 68        -------
 69        tuple of (Number, Number)
 70            vector bounds.
 71        """
 72        return self.bounds
 73
 74    def check_if_in_bounds(self):
 75        """
 76        Check if all vector cells are in bounds
 77
 78        Returns
 79        -------
 80        bool
 81            True if all vector cells are in bounds, False otherwise
 82        """
 83        for i in range(self.size()):
 84            if len(self.bounds) == 2:
 85                if (self.vector[i] < self.bounds[0]) or (self.vector[i] > self.bounds[1]):
 86                    return False
 87            else:
 88                if (self.vector[i] < self.bounds[i][0]) or (self.vector[i] > self.bounds[i][1]):
 89                    return False
 90        return True
 91
 92    def add_cell(self, cell):
 93        """
 94        Add a new cell to the vector (and increase its size by 1)
 95
 96        Returns
 97        -------
 98        None
 99        """
100        self.vector.append(cell)
101        self.length += 1
102
103    def empty_vector(self):
104        """
105        Convert the vector to an empty vector
106
107        Returns
108        -------
109        None
110        """
111        self.vector = []
112        self.length = 0
113
114    def set_vector(self, vector):
115        """
116        Set genome to the given vector genome
117
118        Parameters
119        -------
120        vector: list
121            `other` vector genome
122
123        Returns
124        -------
125        None
126        """
127        self.vector = vector
128        self.length = len(vector)
129
130    def get_vector(self):
131        """
132        Return self vector genome
133
134        Returns
135        -------
136        list
137            vector genome
138        """
139        return self.vector
140
141    def random_vector_part(self):
142        """
143        Get a random part of the vector
144
145        Returns
146        -------
147        list
148            sub-vector genome
149        """
150        # todo add tests to make sure this logic works
151        rnd_i = randint(0, self.size() - 1)
152        end_i = randint(rnd_i, self.size() - 1)
153        return self.vector[rnd_i:end_i + 1]
154
155    def replace_vector_part_random(self, inserted_part):
156        """
157        Replace a given vector part in a random position
158
159        Parameters
160        -------
161        inserted_part: list
162            new vector part to be inserted
163
164        Returns
165        -------
166        list
167            previous vector part of this vector genome
168        """
169        index = randint(0, self.size() - len(inserted_part))  # select a random index
170        end_i = index + len(inserted_part)
171        replaced_part = self.vector[index:end_i]
172        self.vector = self.vector[:index] + inserted_part + self.vector[end_i:]
173        return replaced_part
174
175    def replace_vector_part(self, inserted_part, start_index):
176        """
177        Replace a given vector part in a given position
178
179        Parameters
180        -------
181        inserted_part: list
182            new vector part to be inserted
183
184        start_index: int
185            starting position to insert the new vector part from
186
187        Returns
188        -------
189        list
190            previous vector part of this vector genome
191        """
192        end_i = start_index + len(inserted_part)
193        replaced_part = self.vector[start_index:end_i]
194        self.vector = self.vector[:start_index] + inserted_part + self.vector[end_i:]
195        return replaced_part
196
197    def get_vector_part(self, index, end_i):
198        """
199        Return vector part from `index` to `end_i`
200
201        Parameters
202        -------
203        index: int
204            starting index
205
206        end_i: int
207            end index
208
209        Returns
210        -------
211        list
212            sub-vector genome
213        """
214        return self.vector[index:end_i]
215
216    def cell_value(self, index):
217        """
218        Get vector cell value in a given index
219
220        Parameters
221        -------
222        index: int
223            cell index
224
225        Returns
226        -------
227        object
228            vector cell value
229        """
230        return self.vector[index]
231
232    def set_cell_value(self, index, value):
233        """
234        Set vector cell value in a given index
235
236        Parameters
237        -------
238        index: int
239            cell index
240
241        value: object
242            new cell value
243
244        Returns
245        -------
246        None
247        """
248        self.vector[index] = value
249
250    @abstractmethod
251    def get_random_number_in_bounds(self, index):
252        """
253        Returns a random value in vector bounds
254
255        Parameters
256        -------
257        index: int
258            cell index
259
260        Returns
261        -------
262        object
263            vector cell value
264        """
265        raise NotImplementedError("get_random_number is an abstract method in vector individual")
266
267    def execute(self, *args, **kwargs):
268        """
269        Execute the vector.
270        Input is a numpy array or keyword arguments (but not both).
271
272        Parameters
273        ----------
274        args : arguments
275            A numpy array, this is mostly relevant to GP representation.
276
277        kwargs : keyword arguments
278            Input to program, this is mostly relevant to GP representation.
279
280        Returns
281        -------
282        object
283            Vector (genome) of this individual.
284        """
285        return self.get_vector()
286
287    def show(self):
288        """
289        Print out a simple textual representation of the vector.
290
291        Returns
292        -------
293        None.
294        """
295        print(self.vector)

A Vector individual representation for Genetic Algorithms operations. It is represented by a list of values (integers, floats, etc.)

Parameters
  • fitness (Fitness): Fitness handler class, responsible of keeping the fitness value of the individual.
  • length (int): Vector length - the number of cells in the vector.
  • bounds (list of tuples): Min/Max values for each vector cell (if of length n), or the minimum and maximum (if of length 1).
Vector(fitness, bounds, length, vector=None)
28    def __init__(self,
29                 fitness,
30                 bounds,
31                 length,
32                 vector=None):
33        super().__init__(fitness)
34
35        if (type(bounds) == tuple and len(bounds) != 2) \
36                or (type(bounds) == list and len(bounds) != length):
37            raise ValueError(f'Bounds must be either a tuple of size 2 or a list of {length} tuples')
38
39        self.bounds = bounds
40        self.length = length
41        
42        if vector is None:
43            self.vector = []
44        
45        else:
46            if not isinstance(vector, list):
47                raise ValueError(f'Expected vector argument in Vector constructor to be a list, got {type(vector)}')
48            if len(vector) != length:
49                raise ValueError(f'Expected vector argument in Vector constructor to be of length {length}, got {len(vector)}')
50            self.vector = vector
bounds
length
def size(self):
52    def size(self):
53        """
54        Compute size of vector.
55
56        Returns
57        -------
58        int
59            vector size (= number of cells).
60        """
61        return len(self.vector)

Compute size of vector.

Returns
  • int: vector size (= number of cells).
def get_bounds(self):
63    def get_bounds(self):
64        """
65        Get vector bounds
66
67        Returns
68        -------
69        tuple of (Number, Number)
70            vector bounds.
71        """
72        return self.bounds

Get vector bounds

Returns
  • tuple of (Number, Number): vector bounds.
def check_if_in_bounds(self):
74    def check_if_in_bounds(self):
75        """
76        Check if all vector cells are in bounds
77
78        Returns
79        -------
80        bool
81            True if all vector cells are in bounds, False otherwise
82        """
83        for i in range(self.size()):
84            if len(self.bounds) == 2:
85                if (self.vector[i] < self.bounds[0]) or (self.vector[i] > self.bounds[1]):
86                    return False
87            else:
88                if (self.vector[i] < self.bounds[i][0]) or (self.vector[i] > self.bounds[i][1]):
89                    return False
90        return True

Check if all vector cells are in bounds

Returns
  • bool: True if all vector cells are in bounds, False otherwise
def add_cell(self, cell):
 92    def add_cell(self, cell):
 93        """
 94        Add a new cell to the vector (and increase its size by 1)
 95
 96        Returns
 97        -------
 98        None
 99        """
100        self.vector.append(cell)
101        self.length += 1

Add a new cell to the vector (and increase its size by 1)

Returns
  • None
def empty_vector(self):
103    def empty_vector(self):
104        """
105        Convert the vector to an empty vector
106
107        Returns
108        -------
109        None
110        """
111        self.vector = []
112        self.length = 0

Convert the vector to an empty vector

Returns
  • None
def set_vector(self, vector):
114    def set_vector(self, vector):
115        """
116        Set genome to the given vector genome
117
118        Parameters
119        -------
120        vector: list
121            `other` vector genome
122
123        Returns
124        -------
125        None
126        """
127        self.vector = vector
128        self.length = len(vector)

Set genome to the given vector genome

Parameters
  • vector (list): other vector genome
Returns
  • None
def get_vector(self):
130    def get_vector(self):
131        """
132        Return self vector genome
133
134        Returns
135        -------
136        list
137            vector genome
138        """
139        return self.vector

Return self vector genome

Returns
  • list: vector genome
def random_vector_part(self):
141    def random_vector_part(self):
142        """
143        Get a random part of the vector
144
145        Returns
146        -------
147        list
148            sub-vector genome
149        """
150        # todo add tests to make sure this logic works
151        rnd_i = randint(0, self.size() - 1)
152        end_i = randint(rnd_i, self.size() - 1)
153        return self.vector[rnd_i:end_i + 1]

Get a random part of the vector

Returns
  • list: sub-vector genome
def replace_vector_part_random(self, inserted_part):
155    def replace_vector_part_random(self, inserted_part):
156        """
157        Replace a given vector part in a random position
158
159        Parameters
160        -------
161        inserted_part: list
162            new vector part to be inserted
163
164        Returns
165        -------
166        list
167            previous vector part of this vector genome
168        """
169        index = randint(0, self.size() - len(inserted_part))  # select a random index
170        end_i = index + len(inserted_part)
171        replaced_part = self.vector[index:end_i]
172        self.vector = self.vector[:index] + inserted_part + self.vector[end_i:]
173        return replaced_part

Replace a given vector part in a random position

Parameters
  • inserted_part (list): new vector part to be inserted
Returns
  • list: previous vector part of this vector genome
def replace_vector_part(self, inserted_part, start_index):
175    def replace_vector_part(self, inserted_part, start_index):
176        """
177        Replace a given vector part in a given position
178
179        Parameters
180        -------
181        inserted_part: list
182            new vector part to be inserted
183
184        start_index: int
185            starting position to insert the new vector part from
186
187        Returns
188        -------
189        list
190            previous vector part of this vector genome
191        """
192        end_i = start_index + len(inserted_part)
193        replaced_part = self.vector[start_index:end_i]
194        self.vector = self.vector[:start_index] + inserted_part + self.vector[end_i:]
195        return replaced_part

Replace a given vector part in a given position

Parameters
  • inserted_part (list): new vector part to be inserted
  • start_index (int): starting position to insert the new vector part from
Returns
  • list: previous vector part of this vector genome
def get_vector_part(self, index, end_i):
197    def get_vector_part(self, index, end_i):
198        """
199        Return vector part from `index` to `end_i`
200
201        Parameters
202        -------
203        index: int
204            starting index
205
206        end_i: int
207            end index
208
209        Returns
210        -------
211        list
212            sub-vector genome
213        """
214        return self.vector[index:end_i]

Return vector part from index to end_i

Parameters
  • index (int): starting index
  • end_i (int): end index
Returns
  • list: sub-vector genome
def cell_value(self, index):
216    def cell_value(self, index):
217        """
218        Get vector cell value in a given index
219
220        Parameters
221        -------
222        index: int
223            cell index
224
225        Returns
226        -------
227        object
228            vector cell value
229        """
230        return self.vector[index]

Get vector cell value in a given index

Parameters
  • index (int): cell index
Returns
  • object: vector cell value
def set_cell_value(self, index, value):
232    def set_cell_value(self, index, value):
233        """
234        Set vector cell value in a given index
235
236        Parameters
237        -------
238        index: int
239            cell index
240
241        value: object
242            new cell value
243
244        Returns
245        -------
246        None
247        """
248        self.vector[index] = value

Set vector cell value in a given index

Parameters
  • index (int): cell index
  • value (object): new cell value
Returns
  • None
@abstractmethod
def get_random_number_in_bounds(self, index):
250    @abstractmethod
251    def get_random_number_in_bounds(self, index):
252        """
253        Returns a random value in vector bounds
254
255        Parameters
256        -------
257        index: int
258            cell index
259
260        Returns
261        -------
262        object
263            vector cell value
264        """
265        raise NotImplementedError("get_random_number is an abstract method in vector individual")

Returns a random value in vector bounds

Parameters
  • index (int): cell index
Returns
  • object: vector cell value
def execute(self, *args, **kwargs):
267    def execute(self, *args, **kwargs):
268        """
269        Execute the vector.
270        Input is a numpy array or keyword arguments (but not both).
271
272        Parameters
273        ----------
274        args : arguments
275            A numpy array, this is mostly relevant to GP representation.
276
277        kwargs : keyword arguments
278            Input to program, this is mostly relevant to GP representation.
279
280        Returns
281        -------
282        object
283            Vector (genome) of this individual.
284        """
285        return self.get_vector()

Execute the vector. Input is a numpy array or keyword arguments (but not both).

Parameters
  • args (arguments): A numpy array, this is mostly relevant to GP representation.
  • kwargs (keyword arguments): Input to program, this is mostly relevant to GP representation.
Returns
  • object: Vector (genome) of this individual.
def show(self):
287    def show(self):
288        """
289        Print out a simple textual representation of the vector.
290
291        Returns
292        -------
293        None.
294        """
295        print(self.vector)

Print out a simple textual representation of the vector.

Returns
  • None.