## Appendix B Algorithm Creation and Applications for Problem-Solving
### Applying Random Search  
Figure A5 shows how to apply the RS algorithm to solve all the aforementioned problem instances, except _SMLGS_ because it was specifically designed to work with _GSGP_. The script exemplifies how a given metaheuristic, such as RS, can be used to solve any type of problem in the scope of this library. The modular implementation allows one to reuse the code of _RandomSearch_ for any type of problem easily by simply providing the algorithm's instance with a problem-specific initialization function. In this sense, the initialization functions generate initial solutions according to the instance's search space \(S\). ```
1 fromgpol.algorithms.random_searchimportRandomSearch
2 fromgpol.operators.initializersimportrnd_vuniform,prm_rnd_vint,rnd_vshuffle,grow
3
4#Definesdemos'computationalresources
5 ps.n_iter=100,20
6#RecomputestheresourcesforRandomSearch
7n_iter_rs=100*20
8#Createsparameters'dictionary
9 pars={\"Rastrigni\":\"p1\":p1_continuous,\"initializer\":rnd_vuniform,
10\"seed\":seed,\"device\":device},
11\"Knapsack01\":{\"pi\":pi_knapsack01,\"initializer\":prm_rnd_vint(),
12\"seed\":seed,\"device\":device},
13\"Knapsack01\":{\"pi\":pi_knapsack04,\"initializer\":prm_rnd_vint(
1400,max_repr1),\"seed\":seed,\"device\":device},
15\"TSP\":{\"pi\":pi_tsp\",\"initializer\":rnd_vshuffle,\"seed\":seed,
15\"device\":device},
16\"Boston\":{\"pi\":pi_small,\"initializer\":grow,\"seed\":seed,
17\"device\":device}}
18#AppliesRandomSearchon5 differentproblemtypes
19 forprob,pars.in_para.items():
20 print(\"Problem:{}\".format(prob))
21 mheuristic=RandomSearch(**pars_i)#createsRandomSearch'sinstance
22 mheuristic.solve(n_iter_rs)
23 print(\"Bestfitness:{.3f}\".format(mheuristic.best_sol.fit.item()))
24 print(\"Bestsolution:\",mheuristic.best_sol.repr_,end=\"\
\")\
\")
25
26?Problem:Rastrigni
27?Bestsolution'sfitness:1.084
28?Bestsolution:tensor([0.0184,-0.9844])
29?Problem:Knapsack01
30?Bestsolution'sfitness:81.624
31?Bestsolution:tensor([0,0,1,0,0,0,0,0,1,1,0,1,0,1,1,1,1],
11)
32?Problem:KnapsackBounded
33?Bestsolution'sfitness:460.080
34?Bestsolution:tensor([1,3,3,2,3,4,0,2,3,0,0,4,2,1,3,4,4])
35
36?Problem:TSP
37?Bestsolution'sfitness:10021.000
38?Bestsolution:tensor([3,2,11,12,8,1,4,6,5,10,9,7])
39?Problem:Boston
40?Bestsolution'sfitness:7.629
41?Bestsolution:[div,11,10]

### Applying Local Search

Figure 14 shows how to use one of the available LS algorithms--the SA--to solve the aforementioned problems; note that the variables defined and used in Figure 15 are assumed to be \"cached\", and thus accessible in the \"enclosing scope\" of this example. Figure 14 shows that the implementation of SA allows one to solve any type of problem easily, if provided the correct problem-specific initialization and neighborhood functions (the latter can accept the some parameters because Python closures were used in their implementation). The dictionary _neighborhood_functions_ defines the problem-specific neighborhood functions that, in the _for_ loop, are appended to the problem-specific dictionary of the algorithm's hyperparameters (_pars_). Once the set of algorithmic parameters is defined, _SimulatedAncealing_'s constructor is provided the necessary parameters' dictionary, and the search is executed for a given number of iterations. Note that a detailed description of the neighborhood functions, along with other operators, can be found in Section 4. ### Applying Genetic Algorithms

Figure 15 shows how to apply the GAs to solve the aforementioned problems. The reason why this example was placed after presenting GP relates to the aforementioned paragraph: the flexible design of the library, and particularly, the class _GeneticAlgorithm_,allows using the GA (and LS) for any kind of representation, including trees. Note that this example follows the variables defined in previous demonstrations, where the reader was shown how to apply RS and SA for solving different types of problems, which are assumed to be cached.