Coverage for moptipyapps / order1d / space.py: 97%
34 statements
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-11 04:40 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-11 04:40 +0000
1"""
2An extension of the permutation space for one-dimensional ordering.
4The main difference is how the `to_str` result is noted, namely that it
5contains the mapping of tags to locations.
7>>> def _dist(a, b):
8... return abs(a - b)
9>>> def _tags(a):
10... return f"t{a}"
11>>> the_instance = Instance.from_sequence_and_distance(
12... [1, 2, 3, 3, 2, 3], _dist, 2, 10, ("x", ), _tags)
13>>> the_space = OrderingSpace(the_instance)
14>>> the_str = the_space.to_str(np.array([0, 2, 1]))
15>>> the_str.splitlines()
16['0;2;1', '', 'indexZeroBased;suggestedXin01;x', '0;0;t1', '2;1;t2', \
17'2;1;t2', '1;0.5;t3', '1;0.5;t3', '1;0.5;t3']
18>>> print(the_space.from_str(the_str))
19[0 2 1]
20"""
22from typing import Final
24import numpy as np
25from moptipy.spaces.permutations import Permutations
26from moptipy.utils.logger import CSV_SEPARATOR
27from moptipy.utils.strings import float_to_str
28from pycommons.types import type_error
30from moptipyapps.order1d.instance import (
31 _SUGGESTED_X_IN_0_1,
32 _ZERO_BASED_INDEX,
33 Instance,
34)
37class OrderingSpace(Permutations):
38 """A space for one-dimensional orderings."""
40 def __init__(self, instance: Instance) -> None:
41 """
42 Create an ordering space from an instance.
44 :param instance: the instance
45 """
46 if not isinstance(instance, Instance):
47 raise type_error(instance, "instance", Instance)
48 super().__init__(range(instance.n))
49 #: the instance
50 self.instance: Final[Instance] = instance
52 def to_str(self, x: np.ndarray) -> str:
53 """
54 Convert a solution to a string.
56 :param x: the permutation
57 :return: the string
58 """
59 tags: Final[tuple[tuple[tuple[str, ...], int], ...]] \
60 = self.instance.tags
62 n: Final[int] = len(self.blueprint) - 1
63 text: list[str] = []
65 text.extend(super().to_str(x).split("\n"))
66 text.append("") # noqa
68 row: list[str] = [_ZERO_BASED_INDEX, _SUGGESTED_X_IN_0_1]
69 row.extend(self.instance.tag_titles)
70 text.append(f"{CSV_SEPARATOR.join(row)}")
72 for tag, i in tags:
73 row.clear()
74 row.extend((str(x[i]), float_to_str(x[i] / n)))
75 row.extend(tag)
76 text.append(f"{CSV_SEPARATOR.join(row)}")
77 return "\n".join(text)
79 def from_str(self, text: str) -> np.ndarray:
80 """
81 Get the string version from the given text.
83 :param text: the text
84 :return: the string
85 """
86 text = text.lstrip()
87 idx: int = text.find("\n")
88 if idx > 0:
89 text = text[:idx]
90 return super().from_str(text.rstrip())