ommx-openjij-adapter 1.9.0rc1__tar.gz → 1.9.0rc2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ommx_openjij_adapter-1.9.0rc1 → ommx_openjij_adapter-1.9.0rc2}/PKG-INFO +1 -1
- {ommx_openjij_adapter-1.9.0rc1 → ommx_openjij_adapter-1.9.0rc2}/ommx_openjij_adapter/__init__.py +31 -7
- {ommx_openjij_adapter-1.9.0rc1 → ommx_openjij_adapter-1.9.0rc2}/ommx_openjij_adapter.egg-info/PKG-INFO +1 -1
- {ommx_openjij_adapter-1.9.0rc1 → ommx_openjij_adapter-1.9.0rc2}/pyproject.toml +1 -1
- ommx_openjij_adapter-1.9.0rc2/tests/test_sample.py +147 -0
- ommx_openjij_adapter-1.9.0rc1/tests/test_sample.py +0 -35
- {ommx_openjij_adapter-1.9.0rc1 → ommx_openjij_adapter-1.9.0rc2}/README.md +0 -0
- {ommx_openjij_adapter-1.9.0rc1 → ommx_openjij_adapter-1.9.0rc2}/ommx_openjij_adapter.egg-info/SOURCES.txt +0 -0
- {ommx_openjij_adapter-1.9.0rc1 → ommx_openjij_adapter-1.9.0rc2}/ommx_openjij_adapter.egg-info/dependency_links.txt +0 -0
- {ommx_openjij_adapter-1.9.0rc1 → ommx_openjij_adapter-1.9.0rc2}/ommx_openjij_adapter.egg-info/requires.txt +0 -0
- {ommx_openjij_adapter-1.9.0rc1 → ommx_openjij_adapter-1.9.0rc2}/ommx_openjij_adapter.egg-info/top_level.txt +0 -0
- {ommx_openjij_adapter-1.9.0rc1 → ommx_openjij_adapter-1.9.0rc2}/setup.cfg +0 -0
{ommx_openjij_adapter-1.9.0rc1 → ommx_openjij_adapter-1.9.0rc2}/ommx_openjij_adapter/__init__.py
RENAMED
@@ -4,6 +4,8 @@ from ommx.v1 import Instance, State, Samples, SampleSet
|
|
4
4
|
from ommx.adapter import SamplerAdapter
|
5
5
|
import openjij as oj
|
6
6
|
from typing_extensions import deprecated
|
7
|
+
from typing import Optional
|
8
|
+
import copy
|
7
9
|
|
8
10
|
|
9
11
|
class OMMXOpenJijSAAdapter(SamplerAdapter):
|
@@ -46,6 +48,13 @@ class OMMXOpenJijSAAdapter(SamplerAdapter):
|
|
46
48
|
seed: int | None = None
|
47
49
|
""" seed for Monte Carlo algorithm """
|
48
50
|
|
51
|
+
uniform_penalty_weight: Optional[float] = None
|
52
|
+
""" Weight for uniform penalty, passed to ``Instance.to_qubo`` """
|
53
|
+
penalty_weights: dict[int, float] = {}
|
54
|
+
""" Penalty weights for each constraint, passed to ``Instance.to_qubo`` """
|
55
|
+
inequality_integer_slack_max_range: int = 32
|
56
|
+
""" Max range for integer slack variables in inequality constraints, passed to ``Instance.to_qubo`` """
|
57
|
+
|
49
58
|
@classmethod
|
50
59
|
def sample(
|
51
60
|
cls,
|
@@ -61,6 +70,9 @@ class OMMXOpenJijSAAdapter(SamplerAdapter):
|
|
61
70
|
sparse: bool | None = None,
|
62
71
|
reinitialize_state: bool | None = None,
|
63
72
|
seed: int | None = None,
|
73
|
+
uniform_penalty_weight: Optional[float] = None,
|
74
|
+
penalty_weights: dict[int, float] = {},
|
75
|
+
inequality_integer_slack_max_range: int = 32,
|
64
76
|
) -> SampleSet:
|
65
77
|
sampler = cls(
|
66
78
|
ommx_instance,
|
@@ -74,6 +86,9 @@ class OMMXOpenJijSAAdapter(SamplerAdapter):
|
|
74
86
|
sparse=sparse,
|
75
87
|
reinitialize_state=reinitialize_state,
|
76
88
|
seed=seed,
|
89
|
+
uniform_penalty_weight=uniform_penalty_weight,
|
90
|
+
penalty_weights=penalty_weights,
|
91
|
+
inequality_integer_slack_max_range=inequality_integer_slack_max_range,
|
77
92
|
)
|
78
93
|
response = sampler._sample()
|
79
94
|
return sampler.decode_to_sampleset(response)
|
@@ -92,8 +107,11 @@ class OMMXOpenJijSAAdapter(SamplerAdapter):
|
|
92
107
|
sparse: bool | None = None,
|
93
108
|
reinitialize_state: bool | None = None,
|
94
109
|
seed: int | None = None,
|
110
|
+
uniform_penalty_weight: Optional[float] = None,
|
111
|
+
penalty_weights: dict[int, float] = {},
|
112
|
+
inequality_integer_slack_max_range: int = 32,
|
95
113
|
):
|
96
|
-
self.ommx_instance = ommx_instance
|
114
|
+
self.ommx_instance = copy.deepcopy(ommx_instance)
|
97
115
|
self.beta_min = beta_min
|
98
116
|
self.beta_max = beta_max
|
99
117
|
self.num_sweeps = num_sweeps
|
@@ -104,6 +122,9 @@ class OMMXOpenJijSAAdapter(SamplerAdapter):
|
|
104
122
|
self.sparse = sparse
|
105
123
|
self.reinitialize_state = reinitialize_state
|
106
124
|
self.seed = seed
|
125
|
+
self.uniform_penalty_weight = uniform_penalty_weight
|
126
|
+
self.penalty_weights = penalty_weights
|
127
|
+
self.inequality_integer_slack_max_range = inequality_integer_slack_max_range
|
107
128
|
|
108
129
|
def decode_to_sampleset(self, data: oj.Response) -> SampleSet:
|
109
130
|
samples = decode_to_samples(data)
|
@@ -119,12 +140,16 @@ class OMMXOpenJijSAAdapter(SamplerAdapter):
|
|
119
140
|
|
120
141
|
@property
|
121
142
|
def sampler_input(self) -> dict[tuple[int, int], float]:
|
122
|
-
qubo, _offset = self.ommx_instance.
|
143
|
+
qubo, _offset = self.ommx_instance.to_qubo(
|
144
|
+
uniform_penalty_weight=self.uniform_penalty_weight,
|
145
|
+
penalty_weights=self.penalty_weights,
|
146
|
+
inequality_integer_slack_max_range=self.inequality_integer_slack_max_range,
|
147
|
+
)
|
123
148
|
return qubo
|
124
149
|
|
125
150
|
def _sample(self) -> oj.Response:
|
126
151
|
sampler = oj.SASampler()
|
127
|
-
qubo
|
152
|
+
qubo = self.sampler_input
|
128
153
|
return sampler.sample_qubo(
|
129
154
|
qubo, # type: ignore
|
130
155
|
beta_min=self.beta_min,
|
@@ -189,10 +214,8 @@ def sample_qubo_sa(
|
|
189
214
|
"""
|
190
215
|
Deprecated: Use :meth:`OMMXOpenJijSAAdapter.sample` instead
|
191
216
|
"""
|
192
|
-
|
193
|
-
|
194
|
-
response = sampler.sample_qubo(
|
195
|
-
q, # type: ignore
|
217
|
+
sampler = OMMXOpenJijSAAdapter(
|
218
|
+
instance,
|
196
219
|
beta_min=beta_min,
|
197
220
|
beta_max=beta_max,
|
198
221
|
num_sweeps=num_sweeps,
|
@@ -204,4 +227,5 @@ def sample_qubo_sa(
|
|
204
227
|
reinitialize_state=reinitialize_state,
|
205
228
|
seed=seed,
|
206
229
|
)
|
230
|
+
response = sampler._sample()
|
207
231
|
return decode_to_samples(response)
|
@@ -0,0 +1,147 @@
|
|
1
|
+
from ommx.v1 import Instance, DecisionVariable
|
2
|
+
from ommx_openjij_adapter import OMMXOpenJijSAAdapter
|
3
|
+
import pytest
|
4
|
+
|
5
|
+
|
6
|
+
def binary_no_constraint_minimize():
|
7
|
+
x0 = DecisionVariable.binary(0, name="x", subscripts=[0])
|
8
|
+
x1 = DecisionVariable.binary(1, name="x", subscripts=[1])
|
9
|
+
instance = Instance.from_components(
|
10
|
+
decision_variables=[x0, x1],
|
11
|
+
objective=x0 + x1,
|
12
|
+
constraints=[],
|
13
|
+
sense=Instance.MINIMIZE,
|
14
|
+
)
|
15
|
+
ans = {(0,): 0.0, (1,): 0.0}
|
16
|
+
return pytest.param(instance, ans, id="binary_no_constraint_minimize")
|
17
|
+
|
18
|
+
|
19
|
+
def binary_no_constraint_maximize():
|
20
|
+
x0 = DecisionVariable.binary(0, name="x", subscripts=[0])
|
21
|
+
x1 = DecisionVariable.binary(1, name="x", subscripts=[1])
|
22
|
+
instance = Instance.from_components(
|
23
|
+
decision_variables=[x0, x1],
|
24
|
+
objective=x0 + x1,
|
25
|
+
constraints=[],
|
26
|
+
sense=Instance.MAXIMIZE,
|
27
|
+
)
|
28
|
+
ans = {(0,): 1.0, (1,): 1.0}
|
29
|
+
return pytest.param(instance, ans, id="binary_no_constraint_maximize")
|
30
|
+
|
31
|
+
|
32
|
+
def binary_equality():
|
33
|
+
x0 = DecisionVariable.binary(0, name="x", subscripts=[0])
|
34
|
+
x1 = DecisionVariable.binary(1, name="x", subscripts=[1])
|
35
|
+
x2 = DecisionVariable.binary(2, name="x", subscripts=[2])
|
36
|
+
|
37
|
+
instance = Instance.from_components(
|
38
|
+
decision_variables=[x0, x1, x2],
|
39
|
+
objective=x0 + 2 * x1 + 3 * x2,
|
40
|
+
constraints=[x1 * x2 == 0],
|
41
|
+
sense=Instance.MAXIMIZE,
|
42
|
+
)
|
43
|
+
|
44
|
+
# x0 = x2 = 1, x1 = 0 is maximum
|
45
|
+
ans = {(0,): 1.0, (1,): 0.0, (2,): 1.0}
|
46
|
+
return pytest.param(instance, ans, id="binary_equality")
|
47
|
+
|
48
|
+
|
49
|
+
def binary_inequality():
|
50
|
+
x0 = DecisionVariable.binary(0, name="x", subscripts=[0])
|
51
|
+
x1 = DecisionVariable.binary(1, name="x", subscripts=[1])
|
52
|
+
x2 = DecisionVariable.binary(2, name="x", subscripts=[2])
|
53
|
+
|
54
|
+
instance = Instance.from_components(
|
55
|
+
decision_variables=[x0, x1, x2],
|
56
|
+
objective=x0 + 2 * x1 + 3 * x2,
|
57
|
+
constraints=[x0 + x1 + x2 <= 2],
|
58
|
+
sense=Instance.MAXIMIZE,
|
59
|
+
)
|
60
|
+
|
61
|
+
# x1 = x2 = 1, x0 = 0 is maximum
|
62
|
+
ans = {(0,): 0.0, (1,): 1.0, (2,): 1.0}
|
63
|
+
return pytest.param(instance, ans, id="binary_inequality")
|
64
|
+
|
65
|
+
|
66
|
+
def integer_equality():
|
67
|
+
x0 = DecisionVariable.integer(0, name="x", lower=-1, upper=1, subscripts=[0])
|
68
|
+
x1 = DecisionVariable.integer(1, name="x", lower=-1, upper=1, subscripts=[1])
|
69
|
+
|
70
|
+
instance = Instance.from_components(
|
71
|
+
decision_variables=[x0, x1],
|
72
|
+
objective=x0 + 2 * x1,
|
73
|
+
constraints=[x0 + x1 == 0],
|
74
|
+
sense=Instance.MAXIMIZE,
|
75
|
+
)
|
76
|
+
|
77
|
+
# x1 = -x0 = 1 is maximum
|
78
|
+
ans = {(0,): -1.0, (1,): 1.0}
|
79
|
+
return pytest.param(instance, ans, id="integer_equality")
|
80
|
+
|
81
|
+
|
82
|
+
def integer_inequality():
|
83
|
+
x0 = DecisionVariable.integer(0, name="x", lower=-1, upper=1, subscripts=[0])
|
84
|
+
x1 = DecisionVariable.integer(1, name="x", lower=-1, upper=1, subscripts=[1])
|
85
|
+
|
86
|
+
instance = Instance.from_components(
|
87
|
+
decision_variables=[x0, x1],
|
88
|
+
objective=x0 + 2 * x1,
|
89
|
+
constraints=[x0 + x1 <= 0],
|
90
|
+
sense=Instance.MAXIMIZE,
|
91
|
+
)
|
92
|
+
|
93
|
+
# x1 = -x0 = 1 is maximum
|
94
|
+
ans = {(0,): -1.0, (1,): 1.0}
|
95
|
+
return pytest.param(instance, ans, id="integer_inequality")
|
96
|
+
|
97
|
+
|
98
|
+
@pytest.mark.parametrize(
|
99
|
+
"instance, ans",
|
100
|
+
[
|
101
|
+
binary_no_constraint_minimize(),
|
102
|
+
binary_no_constraint_maximize(),
|
103
|
+
binary_equality(),
|
104
|
+
binary_inequality(),
|
105
|
+
integer_equality(),
|
106
|
+
integer_inequality(),
|
107
|
+
],
|
108
|
+
)
|
109
|
+
def test_sample(instance, ans):
|
110
|
+
sample_set = OMMXOpenJijSAAdapter.sample(
|
111
|
+
instance, num_reads=1, uniform_penalty_weight=3.0, seed=12345
|
112
|
+
)
|
113
|
+
assert sample_set.extract_decision_variables("x", 0) == ans
|
114
|
+
|
115
|
+
|
116
|
+
@pytest.mark.parametrize(
|
117
|
+
"instance, ans",
|
118
|
+
[
|
119
|
+
binary_no_constraint_minimize(),
|
120
|
+
binary_no_constraint_maximize(),
|
121
|
+
binary_equality(),
|
122
|
+
binary_inequality(),
|
123
|
+
integer_equality(),
|
124
|
+
integer_inequality(),
|
125
|
+
],
|
126
|
+
)
|
127
|
+
def test_solve(instance, ans):
|
128
|
+
solution = OMMXOpenJijSAAdapter.solve(
|
129
|
+
instance, num_reads=1, uniform_penalty_weight=3.0, seed=12345
|
130
|
+
)
|
131
|
+
assert solution.extract_decision_variables("x") == ans
|
132
|
+
|
133
|
+
|
134
|
+
@pytest.mark.parametrize(
|
135
|
+
"instance, ans",
|
136
|
+
[
|
137
|
+
binary_no_constraint_minimize(),
|
138
|
+
binary_no_constraint_maximize(),
|
139
|
+
binary_equality(),
|
140
|
+
binary_inequality(),
|
141
|
+
integer_equality(),
|
142
|
+
integer_inequality(),
|
143
|
+
],
|
144
|
+
)
|
145
|
+
def test_sample_twice(instance, ans):
|
146
|
+
test_sample(instance, ans)
|
147
|
+
test_sample(instance, ans)
|
@@ -1,35 +0,0 @@
|
|
1
|
-
from ommx.v1 import Instance, DecisionVariable
|
2
|
-
from ommx_openjij_adapter import OMMXOpenJijSAAdapter
|
3
|
-
|
4
|
-
|
5
|
-
def test_minimize():
|
6
|
-
x0 = DecisionVariable.binary(0, name="x", subscripts=[0])
|
7
|
-
x1 = DecisionVariable.binary(1, name="x", subscripts=[1])
|
8
|
-
|
9
|
-
instance = Instance.from_components(
|
10
|
-
decision_variables=[x0, x1],
|
11
|
-
objective=x0 + x1,
|
12
|
-
constraints=[],
|
13
|
-
sense=Instance.MINIMIZE,
|
14
|
-
)
|
15
|
-
sample_set = OMMXOpenJijSAAdapter.sample(instance, num_reads=1)
|
16
|
-
|
17
|
-
# x0 = x1 = 0 is minimum
|
18
|
-
assert sample_set.extract_decision_variables("x", 0) == {(0,): 0.0, (1,): 0.0}
|
19
|
-
|
20
|
-
|
21
|
-
def test_maximize():
|
22
|
-
x0 = DecisionVariable.binary(0, name="x", subscripts=[0])
|
23
|
-
x1 = DecisionVariable.binary(1, name="x", subscripts=[1])
|
24
|
-
|
25
|
-
instance = Instance.from_components(
|
26
|
-
decision_variables=[x0, x1],
|
27
|
-
objective=x0 + x1,
|
28
|
-
constraints=[],
|
29
|
-
sense=Instance.MAXIMIZE,
|
30
|
-
)
|
31
|
-
instance.as_minimization_problem()
|
32
|
-
sample_set = OMMXOpenJijSAAdapter.sample(instance, num_reads=1)
|
33
|
-
|
34
|
-
# x0 = x1 = 1 is maximum
|
35
|
-
assert sample_set.extract_decision_variables("x", 0) == {(0,): 1.0, (1,): 1.0}
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|