mono.py 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. """Mono-objective available algorithms
  2. """
  3. # main imports
  4. import logging
  5. # module imports
  6. from .base import Algorithm
  7. class HillClimberFirstImprovment(Algorithm):
  8. """Hill Climber First Improvment used as quick exploration optimisation algorithm
  9. - First, this algorithm do a neighborhood exploration of a new generated solution (by doing operation on the current solution obtained) in order to find a better solution from the neighborhood space.
  10. - Then replace the current solution by the first one from the neighbordhood space which is better than the current solution.
  11. - And do these steps until a number of evaluation (stopping criterion) is reached.
  12. Attributes:
  13. initalizer: {function} -- basic function strategy to initialize solution
  14. evaluator: {function} -- basic function in order to obtained fitness (mono or multiple objectives)
  15. operators: {[Operator]} -- list of operator to use when launching algorithm
  16. policy: {Policy} -- Policy class implementation strategy to select operators
  17. validator: {function} -- basic function to check if solution is valid or not under some constraints
  18. maximise: {bool} -- specify kind of optimisation problem
  19. currentSolution: {Solution} -- current solution managed for current evaluation
  20. bestSolution: {Solution} -- best solution found so far during running algorithm
  21. callbacks: {[Callback]} -- list of Callback class implementation to do some instructions every number of evaluations and `load` when initializing algorithm
  22. """
  23. def run(self, evaluations):
  24. """
  25. Run the local search algorithm
  26. Args:
  27. evaluations: {int} -- number of Local search evaluations
  28. Returns:
  29. {Solution} -- best solution found
  30. """
  31. # by default use of mother method to initialize variables
  32. super().run(evaluations)
  33. # initialize current solution and best solution
  34. self.initRun()
  35. solutionSize = self._currentSolution._size
  36. # local search algorithm implementation
  37. while not self.stop():
  38. for _ in range(solutionSize):
  39. # update current solution using policy
  40. newSolution = self.update(self._currentSolution)
  41. # if better solution than currently, replace it and stop current exploration (first improvment)
  42. if self.isBetter(newSolution):
  43. self._bestSolution = newSolution
  44. break
  45. # increase number of evaluations
  46. self.increaseEvaluation()
  47. self.progress()
  48. logging.info(f"---- Current {newSolution} - SCORE {newSolution.fitness()}")
  49. # stop algorithm if necessary
  50. if self.stop():
  51. break
  52. # set new current solution using best solution found in this neighbor search
  53. self._currentSolution = self._bestSolution
  54. logging.info(f"End of {type(self).__name__}, best solution found {self._bestSolution}")
  55. return self._bestSolution
  56. class HillClimberBestImprovment(Algorithm):
  57. """Hill Climber Best Improvment used as exploitation optimisation algorithm
  58. - First, this algorithm do a neighborhood exploration of a new generated solution (by doing operation on the current solution obtained) in order to find the best solution from the neighborhood space.
  59. - Then replace the best solution found from the neighbordhood space as current solution to use.
  60. - And do these steps until a number of evaluation (stopping criterion) is reached.
  61. Attributes:
  62. initalizer: {function} -- basic function strategy to initialize solution
  63. evaluator: {function} -- basic function in order to obtained fitness (mono or multiple objectives)
  64. operators: {[Operator]} -- list of operator to use when launching algorithm
  65. policy: {Policy} -- Policy class implementation strategy to select operators
  66. validator: {function} -- basic function to check if solution is valid or not under some constraints
  67. maximise: {bool} -- specify kind of optimisation problem
  68. currentSolution: {Solution} -- current solution managed for current evaluation
  69. bestSolution: {Solution} -- best solution found so far during running algorithm
  70. callbacks: {[Callback]} -- list of Callback class implementation to do some instructions every number of evaluations and `load` when initializing algorithm
  71. """
  72. def run(self, evaluations):
  73. """
  74. Run the local search algorithm
  75. Args:
  76. evaluations: {int} -- number of Local search evaluations
  77. Returns:
  78. {Solution} -- best solution found
  79. """
  80. # by default use of mother method to initialize variables
  81. super().run(evaluations)
  82. # initialize current solution and best solution
  83. self.initRun()
  84. solutionSize = self._currentSolution._size
  85. # local search algorithm implementation
  86. while not self.stop():
  87. for _ in range(solutionSize):
  88. # update current solution using policy
  89. newSolution = self.update(self._currentSolution)
  90. # if better solution than currently, replace it
  91. if self.isBetter(newSolution):
  92. self._bestSolution = newSolution
  93. # increase number of evaluations
  94. self.increaseEvaluation()
  95. self.progress()
  96. logging.info(f"---- Current {newSolution} - SCORE {newSolution.fitness()}")
  97. # stop algorithm if necessary
  98. if self.stop():
  99. break
  100. # set new current solution using best solution found in this neighbor search
  101. self._currentSolution = self._bestSolution
  102. logging.info(f"End of {type(self).__name__}, best solution found {self._bestSolution}")
  103. return self._bestSolution
  104. class IteratedLocalSearch(Algorithm):
  105. """Iterated Local Search used to avoid local optima and increave EvE (Exploration vs Exploitation) compromise
  106. Attributes:
  107. initalizer: {function} -- basic function strategy to initialize solution
  108. evaluator: {function} -- basic function in order to obtained fitness (mono or multiple objectives)
  109. operators: {[Operator]} -- list of operator to use when launching algorithm
  110. policy: {Policy} -- Policy class implementation strategy to select operators
  111. validator: {function} -- basic function to check if solution is valid or not under some constraints
  112. maximise: {bool} -- specify kind of optimisation problem
  113. currentSolution: {Solution} -- current solution managed for current evaluation
  114. bestSolution: {Solution} -- best solution found so far during running algorithm
  115. callbacks: {[Callback]} -- list of Callback class implementation to do some instructions every number of evaluations and `load` when initializing algorithm
  116. """
  117. def run(self, evaluations, ls_evaluations=100):
  118. """
  119. Run the iterated local search algorithm using local search (EvE compromise)
  120. Args:
  121. evaluations: {int} -- number of global evaluations for ILS
  122. ls_evaluations: {int} -- number of Local search evaluations (default: 100)
  123. Returns:
  124. {Solution} -- best solution found
  125. """
  126. # by default use of mother method to initialize variables
  127. super().run(evaluations)
  128. # enable resuming for ILS
  129. self.resume()
  130. # initialize current solution
  131. self.initRun()
  132. # passing global evaluation param from ILS
  133. ls = HillClimberFirstImprovment(self._initializer,
  134. self._evaluator,
  135. self._operators,
  136. self._policy,
  137. self._validator,
  138. self._maximise,
  139. verbose=self._verbose,
  140. parent=self)
  141. # add same callbacks
  142. for callback in self._callbacks:
  143. ls.addCallback(callback)
  144. # local search algorithm implementation
  145. while not self.stop():
  146. # create and search solution from local search
  147. newSolution = ls.run(ls_evaluations)
  148. # if better solution than currently, replace it
  149. if self.isBetter(newSolution):
  150. self._bestSolution = newSolution
  151. # number of evaluatins increased from LocalSearch
  152. # increase number of evaluations and progress are then not necessary there
  153. #self.increaseEvaluation()
  154. #self.progress()
  155. self.information()
  156. logging.info(f"End of {type(self).__name__}, best solution found {self._bestSolution}")
  157. self.end()
  158. return self._bestSolution