1+ import numpy as np
2+ from typing import Callable
3+
4+
5+ class RandomLocalSearch :
6+ def __init__ (
7+ self ,
8+ objective : Callable ,
9+ seed : int ,
10+ n_steps : int = 10 , # todo: should this be dependent on the number of parameters?
11+ permissible_values : np .ndarray = np .logspace (start = 0 , stop = 7 , num = 8 , base = 2 , dtype = int ),
12+ ) -> None :
13+ self .objective = objective
14+ self .seed = seed
15+ self .n_steps = n_steps
16+ self .permissible_values = permissible_values
17+
18+ def __call__ (self , ind ) -> None :
19+ rng = np .random .RandomState (self .seed )
20+
21+ params_values , params_names = ind .parameters_to_numpy_array (only_active_nodes = True )
22+
23+ if len (params_values ) > 0 :
24+ for _ in range (self .n_steps ):
25+ # sample a new set of parameter values randomly
26+ params_sampled = [rng .choice (self .permissible_values ) for param_value in params_values ]
27+ # write the parameters into a clone of individual
28+ new_ind = ind .clone ()
29+ new_ind .update_parameters_from_numpy_array (params = params_sampled , params_names = params_names )
30+ # evaluate fitness
31+ self .objective (new_ind )
32+ # if fitness improved: replace parameter values and fitness
33+ if new_ind .fitness >= ind .fitness : # todo: should this be >= or > ??
34+ ind .update_parameters_from_numpy_array (params = params_sampled , params_names = params_names )
35+ ind .fitness = new_ind .fitness
36+
37+
38+ if __name__ == "__main__" :
39+ import cgp
40+
41+ def objective (ind ):
42+ params_values , _ = ind .parameters_to_numpy_array (only_active_nodes = True )
43+ ind .fitness = np .sum (params_values )
44+ return ind
45+
46+ seed = 12345
47+ genome = cgp .Genome (primitives = (cgp .Add , cgp .Sub , cgp .Mul , cgp .Parameter ), n_inputs = 1 )
48+ genome .randomize (rng = np .random .RandomState (seed = seed ))
49+ ind = cgp .IndividualSingleGenome (genome = genome )
50+
51+ objective (ind )
52+ print (f'Node parameters before local search { ind .parameters_to_numpy_array (only_active_nodes = True )} \n ' )
53+
54+ rls = RandomLocalSearch (objective = objective , seed = seed , n_steps = 1000 )
55+ rls (ind )
56+ print (f'Node parameters after local search { ind .parameters_to_numpy_array (only_active_nodes = True )} \n ' )
0 commit comments