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
« 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.
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
12import numpy as np
13from numpy.random import Generator
14from pycommons.types import type_error
16from moptipy.api.operators import Op0
17from moptipy.spaces.signed_permutations import SignedPermutations
20class Op0ShuffleAndFlip(Op0):
21 """Shuffle permutations randomly and flip signs randomly."""
23 def __init__(self, space: SignedPermutations):
24 """
25 Initialize this shuffle and flip operation: use blueprint from space.
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
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.
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)
51 def __str__(self) -> str:
52 """
53 Get the name of this shuffle-and-flip operator.
55 :return: "shuffleAndFlip"
56 """
57 return "shuffleAndFlip"