base.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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: {[:class:`~macop.operators.base.Operator`]} -- list of selected operators for the algorithm
  11. """
  12. def __init__(self, operators):
  13. """Initialise new Policy instance using specific list of operators
  14. Args:
  15. operators: [{}] -- list of operators to use
  16. """
  17. self.operators = operators
  18. @abstractmethod
  19. def select(self):
  20. """
  21. Select specific operator
  22. Returns:
  23. {:class:`~macop.operators.base.Operator`}: selected operator
  24. """
  25. pass
  26. def apply(self, solution1, solution2=None):
  27. """
  28. Apply specific operator chosen to create new solution, compute its fitness and return solution
  29. Args:
  30. solution1: {:class:`~macop.solutions.base.Solution`} -- the first solution to use for generating new solution
  31. solution2: {:class:`~macop.solutions.base.Solution`} -- the second solution to use for generating new solution (in case of specific crossover, default is best solution from algorithm)
  32. Returns:
  33. {:class:`~macop.solutions.base.Solution`}: new generated solution
  34. """
  35. operator = self.select()
  36. logging.info("---- Applying %s on %s" %
  37. (type(operator).__name__, solution1))
  38. # default value of solution2 is current best solution
  39. if solution2 is None and self.algo is not None:
  40. solution2 = self.algo.result
  41. # avoid use of crossover if only one solution is passed
  42. if solution2 is None and operator._kind == KindOperator.CROSSOVER:
  43. while operator._kind == KindOperator.CROSSOVER:
  44. operator = self.select()
  45. # apply operator on solution
  46. if operator._kind == KindOperator.CROSSOVER:
  47. newSolution = operator.apply(solution1, solution2)
  48. else:
  49. newSolution = operator.apply(solution1)
  50. logging.info("---- Obtaining %s" % (newSolution))
  51. return newSolution
  52. def setAlgo(self, algo):
  53. """Keep into policy reference of the whole algorithm
  54. The reason is to better manage the operator choices (use of rewards as example)
  55. Args:
  56. algo: {:class:`~macop.algorithms.base.Algorithm`} -- the algorithm reference runned
  57. """
  58. self.algo = algo