base.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. """Abstract classes for Operator Selection Strategy
  2. """
  3. import logging
  4. from abc import abstractmethod
  5. from macop.operators.base import KindOperator
  6. # define policy to choose `operator` function at current iteration
  7. class Policy():
  8. """Abstract class which is used for applying strategy when selecting and applying operator
  9. Attributes:
  10. operators: {[Operator]} -- list of selected operators for the algorithm
  11. """
  12. def __init__(self, operators):
  13. self._operators = operators
  14. @abstractmethod
  15. def select(self):
  16. """
  17. Select specific operator
  18. Returns:
  19. {Operator} -- selected operator
  20. """
  21. pass
  22. def apply(self, solution1, solution2=None):
  23. """
  24. Apply specific operator chosen to create new solution, compute its fitness and return solution
  25. Args:
  26. solution1: {Solution} -- the first solution to use for generating new solution
  27. solution2: {Solution} -- the second solution to use for generating new solution (in case of specific crossover, default is best solution from algorithm)
  28. Returns:
  29. {Solution} -- new generated solution
  30. """
  31. operator = self.select()
  32. logging.info("---- Applying %s on %s" %
  33. (type(operator).__name__, solution1))
  34. # default value of solution2 is current best solution
  35. if solution2 is None and self._algo is not None:
  36. solution2 = self._algo._bestSolution
  37. # avoid use of crossover if only one solution is passed
  38. if solution2 is None and operator._kind == KindOperator.CROSSOVER:
  39. while operator._kind == KindOperator.CROSSOVER:
  40. operator = self.select()
  41. # apply operator on solution
  42. if operator._kind == KindOperator.CROSSOVER:
  43. newSolution = operator.apply(solution1, solution2)
  44. else:
  45. newSolution = operator.apply(solution1)
  46. logging.info("---- Obtaining %s" % (newSolution))
  47. return newSolution
  48. def setAlgo(self, algo):
  49. """Keep into policy reference of the whole algorithm
  50. The reason is to better manage the operator choices (use of rewards as example)
  51. Args:
  52. algo: {Algorithm} -- the algorithm reference runned
  53. """
  54. self._algo = algo