openjij
Framework for the Ising model and QUBO.
Loading...
Searching...
No Matches
integer_polynomial_model.hpp
Go to the documentation of this file.
1// Copyright 2023 Jij Inc.
2
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6
7// http://www.apache.org/licenses/LICENSE-2.0
8
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#pragma once
16
17namespace openjij {
18namespace graph {
19
21
22public:
24 std::vector<std::vector<std::int64_t>> &key_list,
25 std::vector<double> &value_list,
26 std::vector<std::pair<std::int64_t, std::int64_t>> &bounds) {
27 if (key_list.size() != value_list.size()) {
28 throw std::runtime_error("Key and value lists must have the same size.");
29 }
30
31 std::unordered_set<std::int64_t> index_set;
32 for (const auto &key : key_list) {
33 index_set.insert(key.begin(), key.end());
34 }
35
36 this->bounds_ = bounds;
37
38 this->index_list_ =
39 std::vector<std::int64_t>(index_set.begin(), index_set.end());
40 std::sort(this->index_list_.begin(), this->index_list_.end());
41
42 this->num_variables_ = this->index_list_.size();
43
44 this->constant_ = 0.0;
45 for (std::size_t i = 0; i < key_list.size(); ++i) {
46 if (key_list[i].empty()) {
47 this->constant_ += value_list[i];
48 } else {
49 // Count occurrences of each index
50 std::unordered_map<std::int64_t, std::int64_t> index_count;
51 for (const auto &k : key_list[i]) {
52 index_count[k]++;
53 }
54
55 // Convert to vector of pairs
56 std::vector<std::pair<std::int64_t, std::int64_t>> int_keys;
57 for (const auto &[index, degree] : index_count) {
58 int_keys.emplace_back(index, degree);
59 }
60
61 std::sort(int_keys.begin(), int_keys.end());
62
63 this->key_value_list_.emplace_back(int_keys, value_list[i]);
64 }
65 }
66
67 // Sort by number of variables
68 std::sort(this->key_value_list_.begin(), this->key_value_list_.end(),
69 [](const auto &a, const auto &b) {
70 return a.first.size() < b.first.size();
71 });
72
73 // Create index_to_interactions
74 this->index_to_interactions_.resize(this->num_variables_);
75 for (std::size_t i = 0; i < this->key_value_list_.size(); ++i) {
76 for (const auto &[index, degree] : this->key_value_list_[i].first) {
77 this->index_to_interactions_[index].emplace_back(i, degree);
78 }
79 }
80
81 // Sort index_to_interactions
82 for (auto &interactions : this->index_to_interactions_) {
83 std::sort(interactions.begin(), interactions.end());
84 }
85
86 // Create max degree of each variable
87 this->max_variable_degree_.resize(this->num_variables_, 0);
88 for (std::int64_t index = 0; index < this->num_variables_; ++index) {
89 std::int64_t max_degree = 0;
90 for (const auto &[_, degree] : this->index_to_interactions_[index]) {
91 if (degree > max_degree) {
93 }
94 }
95 if (max_degree == 0) {
96 throw std::runtime_error("Variable with no interactions found.");
97 }
98 this->max_variable_degree_[index] = max_degree;
99 }
100 }
101
102 std::pair<double, double> GetMaxMinTerms() const {
103 const double MIN_THRESHOLD = 1e-10;
104
105 auto nonzero_abs_min = [&](double current_min, double value) -> double {
106 if (std::abs(value) > MIN_THRESHOLD) {
107 return std::min(std::abs(current_min), std::abs(value));
108 }
109 return current_min;
110 };
111
112 auto nonzero_abs_max = [&](double current_max, double value) -> double {
113 if (std::abs(value) > MIN_THRESHOLD) {
114 return std::max(std::abs(current_max), std::abs(value));
115 }
116 return current_max;
117 };
118
119 double abs_min_dE = std::numeric_limits<double>::infinity();
120 double abs_max_dE = 0.0;
121
122 for (std::int64_t i = 0; i < this->key_value_list_.size(); ++i) {
123 const double value = this->key_value_list_[i].second;
124 double min_term = std::abs(value);
125 double max_term = std::abs(value);
126 for (const auto &iter: this->key_value_list_[i].first) {
127 const std::int64_t index = iter.first;
128 const std::int64_t degree = iter.second;
129 const std::int64_t lower = this->bounds_[index].first;
130 const std::int64_t upper = this->bounds_[index].second;
131 if (lower <= 0 && 0 <= upper) {
132 max_term *= std::pow(std::max(std::abs(lower), std::abs(upper)), degree);
133 }
134 else {
135 if (lower > 0) {
136 min_term *= std::pow(lower, degree);
137 max_term *= std::pow(upper, degree);
138 } else if (upper < 0) {
139 min_term *= std::abs(std::pow(upper, degree));
140 max_term *= std::abs(std::pow(lower, degree));
141 } else {
142 throw std::runtime_error("Bounds are not valid.");
143 }
144 }
145 }
146
149 }
150
151 if (std::isinf(abs_min_dE) || abs_max_dE == 0.0) {
152 throw std::runtime_error("No valid energy difference found.");
153 }
154
155 return std::make_pair(abs_max_dE, abs_min_dE);
156 }
157
158 const std::vector<std::int64_t> &GetIndexList() const {
159 return this->index_list_;
160 }
161 std::int64_t GetNumVariables() const { return this->num_variables_; }
162 const std::vector<std::pair<std::int64_t, std::int64_t>> &GetBounds() const {
163 return this->bounds_;
164 }
165 double GetConstant() const { return this->constant_; }
166 const std::vector<
167 std::pair<std::vector<std::pair<std::int64_t, std::int64_t>>, double>> &
169 return this->key_value_list_;
170 }
171 const std::vector<std::vector<std::pair<std::size_t, std::int64_t>>> &
173 return this->index_to_interactions_;
174 }
175 std::int64_t GetEachVariableDegreeAt(const std::int64_t index) const {
176 return this->max_variable_degree_[index];
177 }
178 const std::vector<std::int64_t> &GetEachVariableDegree() const {
179 return this->max_variable_degree_;
180 }
181
182private:
183 std::vector<std::int64_t> index_list_;
184 std::int64_t num_variables_;
185 std::vector<std::pair<std::int64_t, std::int64_t>> bounds_;
186 double constant_;
187 std::vector<
188 std::pair<std::vector<std::pair<std::int64_t, std::int64_t>>, double>>
190 std::vector<std::vector<std::pair<std::size_t, std::int64_t>>>
192 std::vector<std::int64_t> max_variable_degree_;
193};
194
195} // namespace graph
196} // namespace openjij
Definition integer_polynomial_model.hpp:20
std::pair< double, double > GetMaxMinTerms() const
Definition integer_polynomial_model.hpp:102
std::int64_t GetEachVariableDegreeAt(const std::int64_t index) const
Definition integer_polynomial_model.hpp:175
const std::vector< std::pair< std::int64_t, std::int64_t > > & GetBounds() const
Definition integer_polynomial_model.hpp:162
std::vector< std::pair< std::vector< std::pair< std::int64_t, std::int64_t > >, double > > key_value_list_
Definition integer_polynomial_model.hpp:189
std::int64_t num_variables_
Definition integer_polynomial_model.hpp:184
IntegerPolynomialModel(std::vector< std::vector< std::int64_t > > &key_list, std::vector< double > &value_list, std::vector< std::pair< std::int64_t, std::int64_t > > &bounds)
Definition integer_polynomial_model.hpp:23
double GetConstant() const
Definition integer_polynomial_model.hpp:165
const std::vector< std::int64_t > & GetIndexList() const
Definition integer_polynomial_model.hpp:158
std::vector< std::int64_t > max_variable_degree_
Definition integer_polynomial_model.hpp:192
std::int64_t GetNumVariables() const
Definition integer_polynomial_model.hpp:161
const std::vector< std::vector< std::pair< std::size_t, std::int64_t > > > & GetIndexToInteractions() const
Definition integer_polynomial_model.hpp:172
const std::vector< std::int64_t > & GetEachVariableDegree() const
Definition integer_polynomial_model.hpp:178
std::vector< std::pair< std::int64_t, std::int64_t > > bounds_
Definition integer_polynomial_model.hpp:185
const std::vector< std::pair< std::vector< std::pair< std::int64_t, std::int64_t > >, double > > & GetKeyValueList() const
Definition integer_polynomial_model.hpp:168
std::vector< std::int64_t > index_list_
Definition integer_polynomial_model.hpp:183
std::vector< std::vector< std::pair< std::size_t, std::int64_t > > > index_to_interactions_
Definition integer_polynomial_model.hpp:191
double constant_
Definition integer_polynomial_model.hpp:186
auto json_parse(const json &obj, bool relabel=true)
parse json object from bqm.to_serializable
Definition parse.hpp:50
Definition algorithm.hpp:24