17#include "../utility/variable.hpp"
26template <
typename RandType>
31 const typename RandType::result_type seed)
32 : model(model), seed(seed), random_number_engine(seed) {
37 this->state_.reserve(num_variables);
38 const auto &bounds = this->model.
GetBounds();
39 for (std::int64_t i = 0; i < num_variables; ++i) {
41 x.SetRandomValue(this->random_number_engine);
42 this->state_.push_back(x);
44 this->energy_ = this->CalculateEnergy(this->state_);
47 const auto &squared = this->model.
GetSquared();
48 this->quad_coeff_ = squared;
49 this->linear_coeff_.resize(num_variables, 0.0);
51 const auto &linear = this->model.
GetLinear();
54 for (std::int64_t row = 0; row < num_variables; ++row) {
55 double dE = linear[row] + 2.0 * squared[row] * this->state_[row].value;
56 for (
const auto &[col, value] : quadratic[row]) {
57 dE += value * this->state_[col].value;
59 this->linear_coeff_[row] = dE;
65 double energy = this->model.GetConstant();
66 const auto &linear = this->model.GetLinear();
67 const auto &squared = this->model.GetSquared();
68 const auto &quadratic = this->model.GetQuadratic();
69 const std::int64_t num_variables = this->model.GetNumVariables();
71 for (std::int64_t i = 0; i < num_variables; ++i) {
72 auto x = state[i].value;
73 energy += linear[i] * x + squared[i] * x * x;
74 for (
const auto &[j, value] : quadratic[i]) {
75 auto y = state[j].value;
76 energy += 0.5 * value * x * y;
83 return this->state_[index].GenerateCandidateValue(
84 this->random_number_engine);
88 std::int64_t d = new_value - this->state_[index].value;
89 return this->quad_coeff_[index] * d * d + this->linear_coeff_[index] * d;
92 void SetValue(std::int64_t index, std::int64_t new_value) {
93 if (this->state_[index].value == new_value) {
97 this->energy_ += this->GetEnergyDifference(index, new_value);
98 std::int64_t dx = new_value - this->state_[index].value;
99 this->linear_coeff_[index] += 2.0 * this->model.GetSquared()[index] * dx;
101 const auto &quadratic = this->model.GetQuadratic();
102 for (
const auto &[i, q] : quadratic[index]) {
103 this->linear_coeff_[i] += q * dx;
106 this->state_[index].SetValue(new_value);
110 const double a = this->quad_coeff_[index];
111 const double b = this->linear_coeff_[index];
112 const auto &x = this->state_[index];
113 const std::int64_t dxl = x.lower_bound - x.value;
114 const std::int64_t dxu = x.upper_bound - x.value;
117 const double center = -b / (2 * a);
119 return std::make_pair(x.upper_bound,
120 this->GetEnergyDifference(index, x.upper_bound));
121 }
else if (dxl < center && center < dxu) {
122 const std::int64_t dx_left =
123 static_cast<std::int64_t
>(std::floor(center));
124 const std::int64_t dx_right =
125 static_cast<std::int64_t
>(std::ceil(center));
126 if (center - dx_left <= dx_right - center) {
127 return std::make_pair(
129 this->GetEnergyDifference(index, x.value + dx_left));
131 return std::make_pair(
133 this->GetEnergyDifference(index, x.value + dx_right));
135 }
else if (dxl >= center) {
136 return std::make_pair(x.lower_bound,
137 this->GetEnergyDifference(index, x.lower_bound));
139 throw std::runtime_error(
"Invalid state");
143 return std::make_pair(x.lower_bound,
144 this->GetEnergyDifference(index, x.lower_bound));
146 return std::make_pair(x.upper_bound,
147 this->GetEnergyDifference(index, x.upper_bound));
149 const std::int64_t random_value =
150 x.GenerateRandomValue(this->random_number_engine);
151 return std::make_pair(random_value, 0.0);
154 const double dE_lower = this->GetEnergyDifference(index, x.lower_bound);
155 const double dE_upper = this->GetEnergyDifference(index, x.upper_bound);
156 if (dE_lower <= dE_upper) {
157 return std::make_pair(x.lower_bound, dE_lower);
159 return std::make_pair(x.upper_bound, dE_upper);
164 const std::vector<utility::IntegerVariable> &
GetState()
const {
169 return this->linear_coeff_;
172 const std::vector<double> &
GetQuadCoeff()
const {
return this->quad_coeff_; }
177 return this->model.GetOnlyBilinearIndexSet().count(index) > 0;
183 return this->linear_coeff_[index];
192 std::vector<utility::IntegerVariable>
state_;
Definition integer_quadratic_model.hpp:20
const std::vector< double > & GetLinear() const
Definition integer_quadratic_model.hpp:152
std::int64_t GetNumVariables() const
Definition integer_quadratic_model.hpp:147
const std::vector< double > & GetSquared() const
Definition integer_quadratic_model.hpp:153
const std::vector< std::vector< std::pair< std::int64_t, double > > > & GetQuadratic() const
Definition integer_quadratic_model.hpp:149
const std::vector< std::pair< std::int64_t, std::int64_t > > & GetBounds() const
Definition integer_quadratic_model.hpp:155
std::vector< utility::IntegerVariable > state_
Definition integer_quadratic_sa_system.hpp:192
double GetEnergyDifference(std::int64_t index, std::int64_t new_value) const
Definition integer_quadratic_sa_system.hpp:87
std::int64_t GenerateCandidateValue(std::int64_t index)
Definition integer_quadratic_sa_system.hpp:82
const std::vector< utility::IntegerVariable > & GetState() const
Definition integer_quadratic_sa_system.hpp:164
const std::vector< double > & GetLinearCoeff() const
Definition integer_quadratic_sa_system.hpp:168
double energy_
Definition integer_quadratic_sa_system.hpp:193
double GetEnergy() const
Definition integer_quadratic_sa_system.hpp:174
double CalculateEnergy(const std::vector< utility::IntegerVariable > &state) const
Definition integer_quadratic_sa_system.hpp:64
bool CanOptMove(std::int64_t index) const
Definition integer_quadratic_sa_system.hpp:180
void SetValue(std::int64_t index, std::int64_t new_value)
Definition integer_quadratic_sa_system.hpp:92
std::vector< double > linear_coeff_
Definition integer_quadratic_sa_system.hpp:195
bool IsLinearCoeff(std::int64_t index) const
Definition integer_quadratic_sa_system.hpp:176
const graph::IntegerQuadraticModel model
Definition integer_quadratic_sa_system.hpp:187
IntegerSASystem(const graph::IntegerQuadraticModel &model, const typename RandType::result_type seed)
Definition integer_quadratic_sa_system.hpp:30
double GetLinearCoeff(std::int64_t index) const
Definition integer_quadratic_sa_system.hpp:182
const std::vector< double > & GetQuadCoeff() const
Definition integer_quadratic_sa_system.hpp:172
std::pair< int, double > GetMinEnergyDifference(std::int64_t index)
Definition integer_quadratic_sa_system.hpp:109
const std::int64_t seed
Definition integer_quadratic_sa_system.hpp:188
std::vector< double > quad_coeff_
Definition integer_quadratic_sa_system.hpp:194
RandType random_number_engine
Definition integer_quadratic_sa_system.hpp:189
Definition sa_system.hpp:24
Definition algorithm.hpp:24
Definition variable.hpp:20