Coverage for moptipy / operators / signed_permutations / op0_shuffle_and_flip.py: 94%

18 statements  

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

1""" 

2A nullary operator shuffling a signed permutation and flipping signs. 

3 

4This operator first copies the canonical permutation to the destination 

5string. It then applies the shuffle procedure of the random number 

6generator, which probably internally applies a Fisher-Yates Shuffle. 

7The result is a random permutation. Then, it goes over the permutation 

8once more and the signs of the elements randomly. 

9""" 

10from typing import Final 

11 

12import numpy as np 

13from numpy.random import Generator 

14from pycommons.types import type_error 

15 

16from moptipy.api.operators import Op0 

17from moptipy.spaces.signed_permutations import SignedPermutations 

18 

19 

20class Op0ShuffleAndFlip(Op0): 

21 """Shuffle permutations randomly and flip signs randomly.""" 

22 

23 def __init__(self, space: SignedPermutations): 

24 """ 

25 Initialize this shuffle and flip operation: use blueprint from space. 

26 

27 :param space: the search space 

28 """ 

29 super().__init__() 

30 if not isinstance(space, SignedPermutations): 

31 raise type_error(space, "space", SignedPermutations) 

32 #: the internal blueprint for filling permutations 

33 self.__blueprint: Final[np.ndarray] = space.blueprint 

34 

35 def op0(self, random: Generator, dest: np.ndarray) -> None: 

36 """ 

37 Copy the base string to `dest` and shuffle it and flip signs randomly. 

38 

39 :param random: the random number generator 

40 :param dest: the signed permutation that should be filled with a 

41 random sequence of the base permutation with potentially flipped 

42 signs. 

43 """ 

44 np.copyto(dest, self.__blueprint) 

45 random.shuffle(dest) # Shuffle destination array randomly. 

46 # integers(0, 2, n) -> n values V in {0, 1} 

47 # (2 * V) - 1 -> a value in {-1, 1} 

48 # dest[1] * V -> a value which is either {-dest[i], dest[i]} 

49 dest *= ((2 * random.integers(low=0, high=2, size=len(dest))) - 1) 

50 

51 def __str__(self) -> str: 

52 """ 

53 Get the name of this shuffle-and-flip operator. 

54 

55 :return: "shuffleAndFlip" 

56 """ 

57 return "shuffleAndFlip"