@@ -35,8 +35,9 @@ class IndividualException(Exception):
3535
3636
3737class OperationOverIndividualFail (IndividualException ):
38+
3839 def __init__ (self , individual_value , operation_name , cause ):
39- IndividualException .__init__ (self , "Operation '%s' over individual '%s' fail due %s" % (operation_name , individual_value , cause ) )
40+ IndividualException .__init__ (self , "Operation '%s' over individual '%s' fail due %s" % (operation_name , individual_value , cause ))
4041
4142
4243class TreeException (Exception ):
@@ -146,7 +147,10 @@ def crossover(self, other_individual):
146147 # Check if the individual is valid
147148 preev_function = PreevaluationManager .get_callback ()
148149 success = True
149- if preev_function is not None :
150+ if preev_function is None :
151+ success = True
152+ else :
153+ preev_function = PreevaluationManager .get_callback ()
150154 success = preev_function .preev (indiv1 ) and preev_function .preev (indiv2 )
151155
152156 return Individual (new_value_1 ), Individual (new_value_2 ), not success
@@ -206,7 +210,8 @@ def __crossover_tree(self, other_individual):
206210 count += 1
207211
208212 if not correct :
209- raise TreeException ("we could not find a candidate substitution in %s tests" % maxtries )
213+ raise TreeException ("[CROSSOVER] Candidate could not found a "
214+ "substitution {0} tests" .format (maxtries ))
210215
211216 # Replacing subtrees
212217 value_1 = value_1 .replace ('@' , sm2 )
@@ -249,48 +254,65 @@ def __mutate_tree(self, mutation_type):
249254 for i in range (len (config_sensor_list )):
250255 new_individual_value = new_individual_value .replace ("z%d" % i , "S%d" % config_sensor_list [i ])
251256
252- except TreeException :
253- pass
254-
255- # Preevaluate the Individual
256- preev_function = PreevaluationManager .get_callback ()
257- if preev_function is not None :
258- preevok = preev_function .preev (Individual (new_individual_value ))
259- else :
260- preevok = True
257+ # Preevaluate the Individual
258+ preevok = self ._preevaluate_individual (new_individual_value )
259+ else :
260+ raise TreeException ()
261261
262- if not new_individual_value :
263- raise TreeException ("Subtree cannot be generated" )
262+ except TreeException :
263+ raise TreeException ("[MUTATE_TREE] A non subtractable Individual was generated. "
264+ "Individual: {0}" .format (self ._tree .get_expanded_tree_as_string ()))
264265
265266 return new_individual_value
266267
267268 elif mutation_type == Individual .MutationType .REPARAMETRIZATION :
268- return self .__reparam_tree (LispTreeExpr (self .get_value ()))
269+ new_individual_value = None
270+ preevok = False
271+ while not preevok :
272+ new_individual_value = self .__reparam_tree (LispTreeExpr (self .get_value ()))
273+ preevok = self ._preevaluate_individual (new_individual_value )
274+
275+ return new_individual_value
269276
270277 elif mutation_type == Individual .MutationType .HOIST :
271- controls = self ._config .getint ("POPULATION" , "controls" )
272- prob_threshold = 1 / float (controls )
278+ preevok = False
279+ counter = 0
280+ maxtries = self ._config .getint ("GP" , "maxtries" )
281+
282+ while not preevok and counter < maxtries :
283+ counter += 1
284+ controls = self ._config .getint ("POPULATION" , "controls" )
285+ prob_threshold = 1 / float (controls )
273286
274- cl = [stree .to_string () for stree in self .get_tree ().get_root_node ()._nodes ]
287+ cl = [stree .to_string () for stree in self .get_tree ().get_root_node ()._nodes ]
275288
276- changed = False
277- k = 0
289+ changed = False
290+ k = 0
278291
279- for nc in RandomManager .randperm (controls ):
280- k += 1
281- # control law is cropped if it is the last one and no change happend before
282- if (RandomManager .rand () < prob_threshold ) or (k == controls and not changed ):
292+ for nc in RandomManager .randperm (controls ):
293+ k += 1
294+ # control law is cropped if it is the last one and no change happend before
295+ if (RandomManager .rand () < prob_threshold ) or (k == controls and not changed ):
283296
284- try :
285- _ , sm , _ = self .__extract_subtree (LispTreeExpr ('(root ' + cl [nc - 1 ]+ ')' ), mutmindepth + 1 , maxdepth , maxdepth + 1 )
286- cl [nc - 1 ] = sm
287- changed = True
297+ try :
298+ _ , sm , _ = self .__extract_subtree (LispTreeExpr ('(root ' + cl [nc - 1 ] + ')' ),
299+ mutmindepth + 1 ,
300+ maxdepth ,
301+ maxdepth + 1 )
302+ cl [nc - 1 ] = sm
303+ changed = True
288304
289- except TreeException :
290- changed = False
305+ except TreeException :
306+ changed = False
291307
292- return "(root %s)" % " " .join (cl [:controls ])
308+ new_individual_value = "(root %s)" % " " .join (cl [:controls ])
309+ preevok = self ._preevaluate_individual (new_individual_value )
293310
311+ if counter == maxtries :
312+ raise TreeException ("[MUTATE HOIST] Candidate could not found a "
313+ "substitution {0} tests" .format (maxtries ))
314+
315+ return new_individual_value
294316 else :
295317 raise NotImplementedError ("Mutation type %s not implemented" % mutation_type )
296318
@@ -381,7 +403,7 @@ def __generate_indiv_regressive_tree(value, config, indiv_type):
381403 # Check if the seed character is in the string
382404 index = value .find ('@' )
383405 if index == - 1 :
384- return
406+ return None
385407
386408 # Split the value in two strings, not containing the first seed character
387409 begin_str = value [:index ]
@@ -412,7 +434,7 @@ def __generate_indiv_regressive_tree(value, config, indiv_type):
412434 precision = config .get ('POPULATION' , 'precision' )
413435 # Generate a float number between -range and +range with a precision of 'precision'
414436 new_exp = (("%." + precision + "f" ) % (
415- (RandomManager .rand () - 0.5 ) * 2 * range ))
437+ (RandomManager .rand () - 0.5 ) * 2 * range ))
416438 new_value = begin_str + new_exp + end_str
417439 else :
418440 # Create a node
@@ -428,6 +450,13 @@ def __generate_indiv_regressive_tree(value, config, indiv_type):
428450 new_value = Individual .__generate_indiv_regressive_tree (new_value , config , indiv_type )
429451 return new_value
430452
453+ def _preevaluate_individual (self , new_indiv ):
454+ preev_function = PreevaluationManager .get_callback ()
455+ if preev_function is not None :
456+ return preev_function .preev (Individual (new_indiv ))
457+ else :
458+ return True
459+
431460 @staticmethod
432461 def __simplify_and_sensors_tree (value , config ):
433462 sensor_list = ()
@@ -455,4 +484,4 @@ def __cmp__(self, other):
455484 self ._value == other .get_value ()
456485
457486 def __hash__ (self ):
458- return hash (self ._value )
487+ return hash (self ._value )
0 commit comments