## 2 Materials and Methods  
Many AI optimization algorithms for searching a function maximum (or minimum) value work in a finite domain, consider multiple constraints on the solution set, and have issues if the objective function has multiple local maxima or non-linearity trends [21]. In particular, these algorithms require an unacceptable amount of time to reach the optimal solution. Hence, the attention moves towards heuristic algorithms, which can guarantee sub-optimum solutions to the problem in a reasonable time. Effective heuristic algorithms are Evolutionary Algorithms (EA), which have their fundamentals in [PERSON]'s evolutionary theory, particularly Genetic Programming (GP). GP emulates the evolution of a population's individuals through genetic operators such as crossover and mutation [22]. The individuals represent the possible solutions belonging to the population, and their strength is evaluated by a fitness function, which expresses their ability to adapt to the environment. Thus, only individuals with high fitness function values survive during the construction process. The main steps of GP can be summarized as follows [23]:  
1. First, an initial population of individuals is randomly generated
2. Then, the following steps are performed until a specific termination criterion is met  
1. A fitness value is assigned to each individual
2. The individuals with the best fitness value are selected and reproduced for the next generation
3. A new population is created through genetic operators
4. The result of genetic operators represents a possible solution to the generation  
Typical termination criteria are the fitness function threshold and the number of generations. Genetic operators for individuals' evolution are reproduction, crossover, and mutation. The reproduction operator consists of copying an individual (chosen for his fitness score) into the new population without any transformation. The crossover operator introduces variation in the population by creating offspring that includes some parts of their parents, chosen by a selection method. The mutation operator is a stochastic alteration of one or more genes. It introduces the exploration of new spaces on the fitness surface to avoid the premature convergence of the program. Each operator is realized with a certain probability. In particular, the probability of the mutation operator \(P_{m}\) cannot be greater than 0.1. Between the operators' probabilities, the following relation is held:  
\[P_{r}+P_{c}+P_{m}=1\]where \(P_{r},\ P_{c},\ P_{m}\) represent the probability of reproduction, crossover, and mutation, respectively. At each iteration, the GP creates a program that can have a tree-based representation. The nodes represent the function set, which contains all the operator types, e.g., mathematical, arithmetic, Boolean, conditionals, and looping. Typical elements of the function set are summarized in Table 1[24]. The tree's leaves represent the terminal set, which includes the variables to combine with the operators and sometimes constant values. Other essential parameters of GP are the generation gap, which is defined as the percentage of the population that survives from one generation to another, and the parents' selection methods, often chosen between tournament selection and roulette-wheel selection [25]. Genetic Programming for feature construction is receiving significant attention because of its flexibility and adaptability in different contexts [26]. According to data scientists, a feature set constructed through GP may significantly increase classification or clustering performances depending on the formulated fitness function. In the case of classification, the fitness function mainly includes genetic algorithms [27]. In the case of clustering, the fitness function can include different measures, such as the connectedness [28] or the silhouette coefficient [29]. A clustering algorithm is embedded into the GP algorithm to get data partitions in both cases.