Parcourir la source

Update of checkpoint use

Jérôme BUISINE il y a 4 ans
Parent
commit
b434ed13b0

+ 1 - 0
README.md

@@ -10,6 +10,7 @@ Optimisation generic framework built for optimization problem during thesis
 - **evaluator:** example of an evaluation function to use (you have to implement your own evaluation function)
 - **solutions:** solutions used to represent problem data
 - **operators:** mutators, crossovers update of solution. This folder also had `policies` folder to manage the way of update and use solution.
+- **checkpoints:** checkpoints folder where `Checkpoint` class is available for making checkpoint every number of evaluations.
   
 **Note:** you can pass a custom `validator` function to the algorithm in order to check is solution is always correct for your needs after an update.
 

+ 27 - 6
algorithms/Algorithm.py

@@ -18,7 +18,7 @@ class Algorithm():
 
         # other parameters
         self.parent = _parent # parent algorithm if it's sub algorithm
-        self.maxEvalutations = 0 # by default
+        #self.maxEvaluations = 0 # by default
         self.maximise = _maximise
 
         self.initRun()
@@ -52,9 +52,7 @@ class Algorithm():
 
         # keep in memory best known solution (current solution)
         self.bestSolution = self.currentSolution
-
-        self.numberOfEvaluations = 0
-
+        
 
     def increaseEvaluation(self):
         self.numberOfEvaluations += 1
@@ -71,6 +69,16 @@ class Algorithm():
         return self.numberOfEvaluations
 
 
+    def stop(self):
+        """
+        Global stopping criteria (check for inner algorithm too)
+        """
+        if self.parent is not None:
+            return self.parent.numberOfEvaluations >= self.parent.maxEvaluations or self.numberOfEvaluations >= self.maxEvaluations
+            
+        return self.numberOfEvaluations >= self.maxEvaluations
+
+
     def evaluate(self, solution):
         """
         Returns: 
@@ -125,9 +133,22 @@ class Algorithm():
         """
         Run the specific algorithm following number of evaluations to find optima
         """
-        self.maxEvalutations = _evaluations
+
+        self.maxEvaluations = _evaluations
+
         self.initRun()
 
+        # check if global evaluation is used or not
+        if self.parent is not None and self.getGlobalEvaluation() != 0:
+            
+            # init number evaluations of inner algorithm depending of globalEvaluation
+            # allows to restart from `checkpoint` last evaluation into inner algorithm
+            rest = self.getGlobalEvaluation() % self.maxEvaluations
+            self.numberOfEvaluations = rest
+
+        else:
+            self.numberOfEvaluations = 0
+
         logging.info("Run %s with %s evaluations" % (self.__str__(), _evaluations))
 
 
@@ -136,7 +157,7 @@ class Algorithm():
         if self.checkpoint is not None:
             self.checkpoint.run()
 
-        logging.info("-- %s evaluation %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()))
+        logging.info("-- %s evaluation %s of %s (%s%%) - BEST SCORE %s" % (type(self).__name__, self.numberOfEvaluations, self.maxEvaluations, "{0:.2f}".format((self.numberOfEvaluations) / self.maxEvaluations * 100.), self.bestSolution.fitness()))
 
 
     def information(self):

+ 2 - 2
algorithms/IteratedLocalSearch.py

@@ -24,8 +24,8 @@ class IteratedLocalSearch(Algorithm):
             ls.setCheckpoint(self.checkpoint)
 
         # local search algorithm implementation
-        while self.getGlobalEvaluation() < self.maxEvalutations:
-            
+        while not self.stop():
+
             # create and search solution from local search
             newSolution = ls.run(_ls_evaluations)
 

+ 3 - 3
algorithms/LocalSearch.py

@@ -14,8 +14,8 @@ class LocalSearch(Algorithm):
         solutionSize = self.bestSolution.size
 
         # local search algorithm implementation
-        while self.numberOfEvaluations < self.maxEvalutations:
-
+        while not self.stop():
+            
             for _ in range(solutionSize):
 
                 # update solution using policy
@@ -33,7 +33,7 @@ class LocalSearch(Algorithm):
                 logging.info("---- Current %s - SCORE %s" % (newSolution, newSolution.fitness()))
 
                 # stop algorithm if necessary
-                if self.numberOfEvaluations >= self.maxEvalutations:
+                if self.stop():
                     break
             
         logging.info("End of %s, best solution found %s" % (type(self).__name__, self.bestSolution))

+ 14 - 5
checkpoints/BasicCheckpoint.py

@@ -1,6 +1,7 @@
 # main imports
 import os
 import logging
+import numpy as np
 
 # module imports
 from .Checkpoint import Checkpoint
@@ -25,8 +26,16 @@ class BasicCheckpoint(Checkpoint):
 
             logging.info("Checkpoint is done into " + self.filepath)
 
-            cleanSolution =  str(solution.data).replace('[', '').replace(']', '')
-            line = str(currentEvaluation) + ';' + cleanSolution + ';' + str(solution.fitness()) + ';\n'
+            solutionData = ""
+            solutionSize = len(solution.data)
+
+            for index, val in enumerate(solution.data):
+                solutionData += str(val)
+
+                if index < solutionSize - 1:
+                    solutionData += ' '
+
+            line = str(currentEvaluation) + ';' + solutionData + ';' + str(solution.fitness()) + ';\n'
 
             # check if file exists
             if not os.path.exists(self.filepath):
@@ -58,9 +67,9 @@ class BasicCheckpoint(Checkpoint):
 
                 # get best solution data information
                 solutionData = list(map(int, data[1].split(' ')))
-
-                print(solutionData)
-                self.algo.bestSolution.data = solutionData
+                
+                self.algo.bestSolution.data = np.array(solutionData)
                 self.algo.bestSolution.score = float(data[2])
         else:
+            print('No backup found... Start running')
             logging.info("Can't load backup... Backup filepath not valid in Checkpoint")

+ 6 - 1
mainExample.py

@@ -16,6 +16,8 @@ from optimization.operators.crossovers.SimpleCrossover import SimpleCrossover
 
 from optimization.operators.policies.RandomPolicy import RandomPolicy
 
+from optimization.checkpoints.BasicCheckpoint import BasicCheckpoint
+
 # logging configuration
 logging.basicConfig(format='%(asctime)s %(message)s', filename='example.log', level=logging.DEBUG)
 
@@ -27,14 +29,17 @@ def validator(solution):
 def init():
     return BinarySolution([], 30).random(validator)
 
+filepath = "checkpoints.csv"
+
 def main():
 
     operators = [SimpleBinaryMutation(), SimpleMutation(), SimpleCrossover()]
     policy = RandomPolicy(operators)
 
     algo = ILS(init, evaluatorExample, operators, policy, validator, True)
+    algo.addCheckpoint(_class=BasicCheckpoint, _every=5, _filepath=filepath)
 
-    bestSol = algo.run(1000)
+    bestSol = algo.run(425)
 
     print("Found ", bestSol)