## 4 Algorithm
### Local Search: Variable Neighborhood Descent (VND)  
Variable neighborhood descent (VND) is the local search method within our memetic algorithm. Inherent to the VND methodology, it applies a predetermined set of neighborhood structures, or \"movements\", to refine solutions iteratively. The full procedure is described in Algorithm 3. The basic idea is to perform local searches on increasingly larger neighborhoods and switch to a smaller neighborhood when an improvement is found. This process is repeated until no improvement can be found in the largest neighborhood. At this point, the current solution is considered a local optimum for the defined set of neighborhoods. This search strategy has proven effective in handling combinatorial optimization problems like JSSP due to its flexibility and ability to escape local optima [51]. The following pseudocode in Algorithm 3 illustrates the procedure:  
```
1. Define initial solution \(\gets s\)
2. Define set of neighborhoods \(\leftarrow N\)
3. i = 1
4. While i \(\leq\) number of neighborhoods
5. \(s^{*}\)-neighboring solution of s initilteighborhood
6. If\(s^{\prime}\) is better than \(s\)
7. \(s\gets s^{*}\)
8. \(i\) = 1
9. Else
10. \(i\) = \(i\) + 1
11. End If
12. End While
13. Return s
```  
**Algorithm 3**Variable neighborhood descent (VND). The VND implemented in this work encompasses five movements: maintenance activity, insertion job swapping, maintenance activity position swapping, maintenance activity deletion, and maintenance block swapping. Each movement reflects possible modifications to a solution's structure, thus exploring different regions in the solution space. To establish the order of these movements, we conducted a series of tests, applying each movement once to every solution generated by our initial population method for 30 instances of the problem. Each instance consisted of 10 machines and 25 jobs. We observed the mean computational time (Figure 4), the frequency of solution improvement (Figure 5), and the magnitude of improvement in the objective function value (Figure 6) for each movement. Figure 4: Movement’s mean running time. Below, we detail each movement and the reasoning behind its position in the sequence:  
1. Maintenance activity insertion: This movement introduces a maintenance activity into an idle period between two jobs and stands first in our sequence. Although it yielded the lowest frequency of improvements (21.73%), when improvements occurred, they were substantial, with a mean improvement percentage of 7.13% (first overall). Most importantly, this movement registered the fastest mean computational time, substantiating its placement as the first movement. Figure 7 displays a graphic example of this movement. 2. Job swapping: This movement, which swaps the positions of two jobs in the sequence, has the second shortest computational time and a reasonable frequency of improvements of 39.13% (third overall). This combination of speed and relatively high improvement frequency justifies its second-place position in the sequence, even  
Figure 5: Movement’s mean improvement frequency. Figure 6: Movement’s mean improvement magnitude. though the mean improvement percentage (0.67%) was not the highest. Figure 8 displays a graphic example of this movement. 3. Maintenance activity position swapping: In third place, this movement alters the position of a maintenance activity within the sequence. With the second-lowest computational time, second-highest frequency of improvements (41.07%), and mean improvement percentage (3.70%), it found its place in the middle of the sequence. Figure 9 displays a graphic example of this movement. 4. Maintenance activity deletion: This movement removes a maintenance activity from the sequence. Although it had the highest frequency of improvements (56.07%), its relatively high computational time (third-fastest overall) and modest mean improvement percentage (0.75%) push it to the fourth position. Figure 10 displays a graphic example of this movement. 5.