"""Abstract solution class """ from abc import abstractmethod from copy import deepcopy class Solution(): """Base abstract solution class structure - stores solution data representation into ndarray `data` attribute - get size (shape) of specific data representation - stores the score of the solution """ def __init__(self, data, size): """ Abstract solution class constructor Attributes: data: {ndarray} -- ndarray of values size: {int} -- size of ndarray values score: {float} -- fitness score value """ self._data = data self._size = size self._score = None def isValid(self, validator): """ Use of custom function which checks if a solution is valid or not Args: validator: {function} -- specific function which validates or not a solution Returns: {bool}: `True` is solution is valid """ return validator(self) def evaluate(self, evaluator): """ Evaluate solution using specific `evaluator` Args: _evaluator: {function} -- specific function which computes fitness of solution Returns: {float}: fitness score value """ self._score = evaluator.compute(self) return self._score @property def fitness(self): """ Returns fitness score (by default `score` private attribute) Returns: {float}: fitness score value """ return self._score @fitness.setter def fitness(self, score): """ Set solution score as wished (by default `score` private attribute) """ self._score = score @property def data(self): """ Returns solution data (by default `data` private attribute) Returns: {object}: data values """ return self._data @data.setter def data(self, data): """ Set solution data (by default `data` private attribute) """ self._data = data @property def size(self): """ Returns solution size (by default `size` private attribute) Returns: {object}: data size """ return self._size @size.setter def size(self, size): """ Set solution size (by default `size` private attribute) """ self._size = size @staticmethod def random(size, validator=None): """ initialise solution using random data with validator or not Args: size: {int} -- expected solution size to generate validator: {function} -- specific function which validates or not a solution (if None, not validation is applied) Returns: {:class:`~macop.solutions.base.Solution`}: generated solution """ return None def clone(self): """Clone the current solution and its data, but without keeping evaluated `_score` Returns: {:class:`~macop.solutions.base.Solution`}: clone of current solution """ copy_solution = deepcopy(self) copy_solution._score = None return copy_solution def __str__(self): print("Generic solution with ", self._data)