base.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. """Abstract solution class
  2. """
  3. from abc import abstractmethod
  4. from copy import deepcopy
  5. class Solution():
  6. """Base abstract solution class structure
  7. - stores solution data representation into ndarray `data` attribute
  8. - get size (shape) of specific data representation
  9. - stores the score of the solution
  10. """
  11. def __init__(self, data, size):
  12. """
  13. Abstract solution class constructor
  14. Attributes:
  15. data: {ndarray} -- ndarray of values
  16. size: {int} -- size of ndarray values
  17. score: {float} -- fitness score value
  18. """
  19. self._data = data
  20. self._size = size
  21. self._score = None
  22. def isValid(self, validator):
  23. """
  24. Use of custom function which checks if a solution is valid or not
  25. Args:
  26. validator: {function} -- specific function which validates or not a solution
  27. Returns:
  28. {bool}: `True` is solution is valid
  29. """
  30. return validator(self)
  31. def evaluate(self, evaluator):
  32. """
  33. Evaluate solution using specific `evaluator`
  34. Args:
  35. _evaluator: {function} -- specific function which computes fitness of solution
  36. Returns:
  37. {float}: fitness score value
  38. """
  39. self._score = evaluator.compute(self)
  40. return self._score
  41. @property
  42. def fitness(self):
  43. """
  44. Returns fitness score (by default `score` private attribute)
  45. Returns:
  46. {float}: fitness score value
  47. """
  48. return self._score
  49. @fitness.setter
  50. def fitness(self, score):
  51. """
  52. Set solution score as wished (by default `score` private attribute)
  53. """
  54. self._score = score
  55. @property
  56. def data(self):
  57. """
  58. Returns solution data (by default `data` private attribute)
  59. Returns:
  60. {object}: data values
  61. """
  62. return self._data
  63. @data.setter
  64. def data(self, data):
  65. """
  66. Set solution data (by default `data` private attribute)
  67. """
  68. self._data = data
  69. @staticmethod
  70. def random(size, validator=None):
  71. """
  72. initialise solution using random data with validator or not
  73. Args:
  74. size: {int} -- expected solution size to generate
  75. validator: {function} -- specific function which validates or not a solution (if None, not validation is applied)
  76. Returns:
  77. {:class:`~macop.solutions.base.Solution`}: generated solution
  78. """
  79. return None
  80. def clone(self):
  81. """Clone the current solution and its data, but without keeping evaluated `_score`
  82. Returns:
  83. {:class:`~macop.solutions.base.Solution`}: clone of current solution
  84. """
  85. copy_solution = deepcopy(self)
  86. copy_solution._score = None
  87. return copy_solution
  88. def __str__(self):
  89. print("Generic solution with ", self._data)