22 template <
typename SystemType>
24 const double T,
const double _progress) {
25 const auto candidate_value = sa_system.GenerateCandidateValue(index);
26 const double dE = sa_system.GetEnergyDifference(index, candidate_value);
27 if (dE <= 0.0 ||
dist(sa_system.random_number_engine) < std::exp(-dE / T)) {
28 return candidate_value;
30 return sa_system.GetState()[index].value;
34 std::uniform_real_distribution<double>
dist{0.0, 1.0};
38 template <
typename SystemType>
40 const double T,
const double progress) {
43 if (sa_system.CanOptMove(index) &&
dist(sa_system.random_number_engine) < progress) {
44 const auto [min_val, min_dE] = sa_system.GetMinEnergyDifference(index);
46 dist(sa_system.random_number_engine) < std::exp(-min_dE / T)) {
49 return sa_system.GetState()[index].value;
52 const auto candidate_value = sa_system.GenerateCandidateValue(index);
53 const double dE = sa_system.GetEnergyDifference(index, candidate_value);
55 dist(sa_system.random_number_engine) < std::exp(-dE / T)) {
56 return candidate_value;
58 return sa_system.GetState()[index].value;
63 std::uniform_real_distribution<double>
dist{0.0, 1.0};
67 template <
typename SystemType>
69 const double T,
const double _progress) {
70 if (sa_system.IsLinearCoeff(index)) {
73 return ForAll(sa_system, index, T, _progress);
77 template <
typename SystemType>
78 std::int64_t
ForAll(SystemType &sa_system,
const std::int64_t index,
79 const double T,
const double _progress) {
80 const auto &var = sa_system.GetState()[index];
81 const double beta = 1.0 / T;
82 std::int64_t selected_state_number = -1;
83 double max_z = -std::numeric_limits<double>::infinity();
85 for (std::int64_t i = 0; i < var.num_states; ++i) {
87 -std::log(-std::log(
dist(sa_system.random_number_engine)));
88 const double z = -beta * sa_system.GetEnergyDifference(
89 index, var.GetValueFromState(i)) + g;
92 selected_state_number = i;
95 if (selected_state_number == -1) {
96 throw std::runtime_error(
"No state selected.");
98 return var.GetValueFromState(selected_state_number);
101 template <
typename SystemType>
103 const std::int64_t index,
const double T,
104 const double _progress) {
105 const auto &state = sa_system.GetState()[index];
106 const double linear_coeff = sa_system.GetLinearCoeff(index);
108 if (std::abs(linear_coeff) < 1e-10) {
109 return state.GenerateRandomValue(sa_system.random_number_engine);
112 const double b = -linear_coeff * (1.0 / T);
113 const double dxl =
static_cast<double>(state.lower_bound - state.value);
114 const double dxu =
static_cast<double>(state.upper_bound - state.value);
116 const double u = this->
dist(sa_system.random_number_engine);
118 double selected_dz = 0.0;
120 selected_dz = dxu + std::log(u + (1.0 - u) * std::exp(-b * (dxu - dxl + 1))) / b;
122 selected_dz = dxl - 1.0 + std::log(1.0 - u * (1.0 - std::exp(b * (dxu - dxl + 1)))) / b;
125 selected_dz =
static_cast<std::int64_t
>(std::ceil(std::max(dxl, std::min(selected_dz, dxu))));
127 return state.value + selected_dz;
130 std::uniform_real_distribution<double>
dist{0.0, 1.0};
134 template <
typename SystemType>
136 const double T,
const double _progress) {
137 const auto &var = sa_system.GetState()[index];
138 const std::int64_t max_num_state = var.num_states;
139 std::vector<double> weight_list(max_num_state, 0.0);
140 std::vector<double> sum_weight_list(max_num_state, 0.0);
142 const auto [max_weight_state_value, min_dE] = sa_system.GetMinEnergyDifference(index);
143 const auto max_weight_state = var.GetStateFromValue(max_weight_state_value);
145 for (std::int64_t i = 0; i < max_num_state; ++i) {
146 const std::int64_t state = (i == 0) ? max_weight_state : ((i == max_weight_state) ? 0 : i);
147 const double dE = sa_system.GetEnergyDifference(index, var.GetValueFromState(state)) - min_dE;
148 weight_list[i] = std::exp(-dE / T);
149 sum_weight_list[i] = (i == 0) ? weight_list[i] : sum_weight_list[i - 1] + weight_list[i];
152 std::int64_t current_state = var.GetStateFromValue(var.value);
153 if (current_state == 0) {
154 current_state = max_weight_state;
155 }
else if (current_state == max_weight_state) {
159 const double w_0 = weight_list[0];
160 const double w_c = weight_list[current_state];
161 const double sum_w_c = sum_weight_list[current_state];
162 const double rand =
dist(sa_system.random_number_engine) * w_c;
163 std::int64_t selected_state = -1;
164 double prob_sum = 0.0;
166 for (std::int64_t j = 0; j < max_num_state; ++j) {
167 const double d_ij = sum_w_c - sum_weight_list[(j - 1 + max_num_state) % max_num_state] + w_0;
168 prob_sum += std::max(0.0, std::min({d_ij, w_c + (weight_list[j] - d_ij), w_c, weight_list[j]}));
169 if (rand <= prob_sum) {
171 selected_state = max_weight_state;
172 }
else if (j == max_weight_state) {
181 if (selected_state == -1) {
182 throw std::runtime_error(
"No state selected.");
185 return var.GetValueFromState(selected_state);
188 std::uniform_real_distribution<double>
dist{0.0, 1.0};
Definition algorithm.hpp:24
Definition single_integer_move.hpp:66
std::int64_t ForBilinear(SystemType &sa_system, const std::int64_t index, const double T, const double _progress)
Definition single_integer_move.hpp:102
std::int64_t GenerateNewValue(SystemType &sa_system, const std::int64_t index, const double T, const double _progress)
Definition single_integer_move.hpp:68
std::int64_t ForAll(SystemType &sa_system, const std::int64_t index, const double T, const double _progress)
Definition single_integer_move.hpp:78
std::uniform_real_distribution< double > dist
Definition single_integer_move.hpp:130
Definition single_integer_move.hpp:21
std::int64_t GenerateNewValue(SystemType &sa_system, const std::int64_t index, const double T, const double _progress)
Definition single_integer_move.hpp:23
std::uniform_real_distribution< double > dist
Definition single_integer_move.hpp:34
Definition single_integer_move.hpp:37
std::uniform_real_distribution< double > dist
Definition single_integer_move.hpp:63
std::int64_t GenerateNewValue(SystemType &sa_system, const std::int64_t index, const double T, const double progress)
Definition single_integer_move.hpp:39
Definition single_integer_move.hpp:133
std::int64_t GenerateNewValue(SystemType &sa_system, const std::int64_t index, const double T, const double _progress)
Definition single_integer_move.hpp:135
std::uniform_real_distribution< double > dist
Definition single_integer_move.hpp:188