Algorithm.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. # main imports
  2. import logging
  3. # Generic algorithm class
  4. class Algorithm():
  5. def __init__(self, _initalizer, _evaluator, _operators, _policy, _validator, _maximise=True):
  6. """
  7. Initialize all usefull parameters for problem to solve
  8. """
  9. self.initializer = _initalizer
  10. self.evaluator = _evaluator
  11. self.operators = _operators
  12. self.validator = _validator
  13. self.policy = _policy
  14. # other parameters
  15. self.maxEvalutations = 0 # by default
  16. self.maximise = _maximise
  17. self.initRun()
  18. def initRun(self):
  19. """
  20. Reinit the whole variables
  21. """
  22. self.currentSolution = self.initializer()
  23. # evaluate current solution
  24. self.currentSolution.evaluate(self.evaluator)
  25. # keep in memory best known solution (current solution)
  26. self.bestSolution = self.currentSolution
  27. self.numberOfEvaluations = 0
  28. def evaluate(self, solution):
  29. """
  30. Returns:
  31. fitness score of solution which is not already evaluated or changed
  32. Note:
  33. if multi-objective problem this method can be updated using array of `evaluator`
  34. """
  35. return solution.evaluate(self.evaluator)
  36. def update(self, solution, secondSolution=None):
  37. """
  38. Apply update function to solution using specific `policy`
  39. Check if solution is valid after modification and returns it
  40. Returns:
  41. updated solution
  42. """
  43. # two parameters are sent if specific crossover solution are wished
  44. sol = self.policy.apply(solution, secondSolution)
  45. if(sol.isValid(self.validator)):
  46. return sol
  47. else:
  48. logging.info("-- New solution is not valid %s" % sol)
  49. return solution
  50. def isBetter(self, solution):
  51. """
  52. Check if solution is better than best found
  53. Returns:
  54. `True` if better
  55. """
  56. # depending of problem to solve (maximizing or minimizing)
  57. if self.maximise:
  58. if self.evaluate(solution) > self.bestSolution.fitness():
  59. return True
  60. else:
  61. if self.evaluate(solution) < self.bestSolution.fitness():
  62. return True
  63. # by default
  64. return False
  65. def run(self, _evaluations):
  66. """
  67. Run the specific algorithm following number of evaluations to find optima
  68. """
  69. self.maxEvalutations = _evaluations
  70. self.initRun()
  71. logging.info("Run %s with %s evaluations" % (self.__str__(), _evaluations))
  72. def progress(self):
  73. logging.info("-- %s evaluation n°%s of %s (%s%%) - BEST SCORE %s" % (type(self).__name__, self.numberOfEvaluations, self.maxEvalutations, "{0:.2f}".format((self.numberOfEvaluations) / self.maxEvalutations * 100.), self.bestSolution.fitness()))
  74. def information(self):
  75. logging.info("-- Best solution %s - SCORE %s" % (self.bestSolution, self.bestSolution.fitness()))
  76. def __str__(self):
  77. return "%s using %s" % (type(self).__name__, type(self.bestSolution).__name__)