Coverage for moptipy / spaces / bitstrings.py: 95%

22 statements  

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

1"""An implementation of a bit string based search space.""" 

2from typing import Final 

3 

4import numpy as np 

5from pycommons.strings.string_conv import str_to_bool 

6from pycommons.types import type_error 

7 

8from moptipy.spaces.nparrayspace import NPArraySpace 

9from moptipy.utils.nputils import DEFAULT_BOOL 

10 

11 

12class BitStrings(NPArraySpace): 

13 """ 

14 A space where each element is a bit string (:class:`numpy.ndarray`). 

15 

16 With such a space, discrete optimization can be realized. 

17 

18 >>> s = BitStrings(5) 

19 >>> print(s.dimension) 

20 5 

21 >>> print(s.dtype) 

22 bool 

23 >>> print(s.create()) 

24 [False False False False False] 

25 >>> print(s.to_str(s.create())) 

26 FFFFF 

27 >>> print(s.from_str(s.to_str(s.create()))) 

28 [False False False False False] 

29 """ 

30 

31 def __init__(self, dimension: int) -> None: 

32 """ 

33 Create the vector-based search space. 

34 

35 :param dimension: The dimension of the search space, 

36 i.e., the number of decision variables. 

37 """ 

38 super().__init__(dimension, DEFAULT_BOOL) 

39 

40 def create(self) -> np.ndarray: 

41 """ 

42 Create a bit string filled with `False`. 

43 

44 :return: the string 

45 

46 >>> from moptipy.spaces.bitstrings import BitStrings 

47 >>> s = BitStrings(8) 

48 >>> v = s.create() 

49 >>> print(s.to_str(v)) 

50 FFFFFFFF 

51 >>> print(v.dtype) 

52 bool 

53 """ 

54 return np.zeros(shape=self.dimension, dtype=DEFAULT_BOOL) 

55 

56 def from_str(self, text: str) -> np.ndarray: 

57 """ 

58 Convert a string to a bit string. 

59 

60 :param text: the text 

61 :return: the vector 

62 :raises TypeError: if `text` is not a `str` 

63 :raises ValueError: if `text` cannot be converted to a valid vector 

64 """ 

65 if not (isinstance(text, str)): 

66 raise type_error(text, "text", str) 

67 x: Final[np.ndarray] = self.create() 

68 x[:] = [str_to_bool(t) for t in text] 

69 self.validate(x) 

70 return x 

71 

72 def n_points(self) -> int: 

73 """ 

74 Get the scale of the bit string space. 

75 

76 :return: 2 ** dimension 

77 

78 >>> print(BitStrings(4).n_points()) 

79 16 

80 """ 

81 return 1 << self.dimension # = 2 ** self.dimension 

82 

83 def __str__(self) -> str: 

84 """ 

85 Get the name of this space. 

86 

87 :return: "bits" + dimension 

88 

89 >>> print(BitStrings(5)) 

90 bits5 

91 """ 

92 return f"bits{self.dimension}"