Coverage for moptipy / algorithms / random_walk.py: 100%

21 statements  

« prev     ^ index     » next       coverage.py v7.12.0, created at 2025-11-24 08:49 +0000

1""" 

2A random walk algorithm implementation. 

3 

4A random walk starts with a random point in the search space created with 

5the nullary search operator. In each step, it applies the unary search 

6operator to move a new point. It does not really care whether the new point 

7is better or worse, it will always accept it. 

8 

9Of course, it still needs to call the objective function to make sure to 

10inform the :class:`moptipy.api.process.Process` about the new point so that, 

11at the end, we can obtain the best point that was visited. 

12But during the course of its run, it will walk around the search space 

13randomly without direction. 

14""" 

15from typing import Callable, Final 

16 

17from numpy.random import Generator 

18 

19from moptipy.api.algorithm import Algorithm1 

20from moptipy.api.operators import Op0, Op1 

21from moptipy.api.process import Process 

22 

23 

24# start book 

25class RandomWalk(Algorithm1): 

26 """ 

27 Perform a random walk through the search space. 

28 

29 In each step, a random walk creates a modified copy of the current 

30 solution and accepts it as starting point for the next step. 

31 """ 

32 

33 def solve(self, process: Process) -> None: 

34 """ 

35 Apply the random walk to an optimization problem. 

36 

37 :param process: the black-box process object 

38 """ 

39 # create records for old and new point in the search space 

40 old_x = process.create() # record for best-so-far solution 

41 new_x = process.create() # record for new solution 

42 # Obtain the random number generator. 

43 random: Final[Generator] = process.get_random() 

44 

45 # Put function references in variables to save time. 

46 evaluate: Final[Callable] = process.evaluate # the objective 

47 op1: Final[Callable] = self.op1.op1 # the unary operator 

48 should_terminate: Final[Callable] = process.should_terminate 

49 

50 # Start at a random point in the search space and evaluate it. 

51 self.op0.op0(random, new_x) # Create one solution randomly 

52 evaluate(new_x) # and evaluate it. 

53 

54 while not should_terminate(): # Until we need to quit... 

55 old_x, new_x = new_x, old_x # Swap old and new solution. 

56 op1(random, new_x, old_x) # new_x = neighbor of old_x 

57 evaluate(new_x) # Evaluate the solution and ignore result. 

58# end book 

59 

60 def __init__(self, op0: Op0, op1: Op1) -> None: 

61 """ 

62 Create the random walk. 

63 

64 :param op0: the nullary search operator 

65 :param op1: the unary search operator 

66 """ 

67 super().__init__("rw", op0, op1)