-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathASR_C++
More file actions
350 lines (325 loc) · 12.5 KB
/
Copy pathASR_C++
File metadata and controls
350 lines (325 loc) · 12.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
// algorithm_ASR.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <time.h>
#include <unordered_map>
#include <unordered_set>
#include <chrono>
#include <random>
using namespace std;
float adaptive_search_resampling(int dimension, float feasible_region_min, float feasible_region_max, float r);
int M(int i, float b);
int rise_rate_K(int k, float c, float Ck);
float Tk_(float T, int k_);
float uniformly_distribution(float a, float b);
int find_resample(float resample, vector<float> probability);
bool float_equal(float a, float b);
float noise(int mean_value, int variance);
float test_1_smooth_without_noise(vector<float> solution);
float test_1_smooth(vector<float> solution);
float test_2_twohills_without_noise(vector<float> solution);
float test_2_twohills(vector<float> solution);
float test_3_rosenbrock_without_noise(vector<float> solution);
float test_3_rosenbrock(vector<float> solution);
float main()
{
float result = 0;
/* test_1_smooth:
cout<<"求解test_1_smooth"<<endl;
int dimension = 2;
float feasible_region_min = 0.0f;
float feasible_region_max = 1.0f;
float r = 0.02f; // 0.02-smooth problem, 1.0-two hills problem, 0.4-Rosenbrock problems.
*/
/* test_2_twohills:
cout<<"求解test_2_twohills"<<endl;
int dimension = 2;
float feasible_region_min = 0.0f;
float feasible_region_max = 50.0f;
float r = 1.0f; // 0.02-smooth problem, 1.0-two hills problem, 0.4-Rosenbrock problems.
*/
cout << "求解test_3_rosenbrock" << endl;
int dimension = 2;
float feasible_region_min = -10.0f;
float feasible_region_max = 10.0f;
float r = 0.4f; // 0.02-smooth problem, 1.0-two hills problem, 0.4-Rosenbrock problems.
result = adaptive_search_resampling(dimension, feasible_region_min, feasible_region_max, r); // 不同问题对应的参数r不同
cout << result << endl;
system("pause");
return result;
}
float adaptive_search_resampling(int dimension, float feasible_region_min, float feasible_region_max, float r)
{
/********************* 参数定义 *********************/
float b = 1.1f; // 采样/重采样条件参数 b >=1
float c = 0.5f; // 增长率指数
float Ck = 1.0f; // 增长率系数
float g = 0.5f; // 全局采样概率
float delta = 0.01f; // 接受标准参数
int K = 10; // 判断采样点是否符合接受标准前对其最少采样次数
float T = 0.1f; // 重采样概率系数
/********************* 参数定义 *********************/
int i = 1; // 采样次数
int k = 0; // 迭代次数
int iterations = 700000; // 迭代终止次数
int accepted_count = 1; // 接收点个数
int simulation_budget = 1; // 仿真代价,计算目标函数估计数量,用于作图
float result = 3.402823466e+38f;
vector<pair<vector<float>, float>> accepted_set; // 接受采样点集
unordered_map < int, pair<float,int> > estimated_value; // 接受采样点的观测函数和与观测次数
pair<vector<float>, float> best_solution; // 最佳解
int best_solution_loc = 0; // 最佳解在接受采样点集的位置
vector<pair<vector<float>, float>> best_solution_change;
vector<pair<int, float>> paint;
clock_t start, finish;
start = clock();
while (k <= iterations && best_solution_change.size() <= 100)
{
++k;
if (k == M(i, b))
{
vector<float> new_sample(dimension);
if (uniformly_distribution(0.0f, 1.0f) < g || i == 1) // 以概率g全局探索新解
{
for (int i = 0; i < dimension; ++i)
{
new_sample[i] = uniformly_distribution(feasible_region_min, feasible_region_max);
}
}
else // 以概率1 - g局部探索新解
{
for (int i = 0; i < dimension; ++i)
{
// 注意不要超过可行域,需补充该功能
float local_min = max(best_solution.first[i] - r, feasible_region_min);
float local_max = min(best_solution.first[i] + r, feasible_region_max);
new_sample[i] = uniformly_distribution(local_min, local_max);
}
}
// float new_sample_value = test_1_smooth(new_sample);
// float new_sample_value = test_2_twohills(new_sample);
float new_sample_value = test_3_rosenbrock(new_sample);
// 用接受标准判断是否接受该点
if (i == 1)
{
best_solution.first = new_sample;
best_solution.second = new_sample_value;
accepted_set.push_back({ new_sample,new_sample_value });
estimated_value.insert({ 0,{ new_sample_value, 1 } });
best_solution_change.push_back({ new_sample,new_sample_value });
paint.push_back({ simulation_budget, new_sample_value });
}
else
{
int count = K - 1;
float add = new_sample_value;
while (count > 0)
{
//add += test_1_smooth(new_sample);
//add += test_2_twohills(new_sample);
add += test_3_rosenbrock(new_sample);
--count;
}
simulation_budget += K;
new_sample_value = add / K;
if (new_sample_value >= best_solution.second - delta)
{
accepted_set.push_back({ new_sample,new_sample_value });
estimated_value.insert({ accepted_count,{ new_sample_value, 1 } });
++accepted_count;
}
}
// 使得所有接受集中的点的观测次数大于等于最低增长率K
for (auto it = estimated_value.begin(); it != estimated_value.end(); ++it)
{
if (it->second.second < rise_rate_K(i, c, Ck))
{
int additional_ob_times = rise_rate_K(i, c, Ck) - it->second.second;
float additional_observe = 0;
simulation_budget += additional_ob_times;
it->second.second += additional_ob_times;
while (additional_ob_times > 0)
{
//additional_observe += test_1_smooth(accepted_set[it->first].first);
//additional_observe += test_2_twohills(accepted_set[it->first].first);
additional_observe += test_3_rosenbrock(accepted_set[it->first].first);
--additional_ob_times;
}
it->second.first += additional_observe;
accepted_set[it->first].second = it->second.first / it->second.second;
if (it->first == best_solution_loc)
best_solution.second = accepted_set[it->first].second;
if (accepted_set[it->first].second > best_solution.second)
{
best_solution = { accepted_set[it->first].first, accepted_set[it->first].second };
best_solution_loc = it->first;
best_solution_change.push_back({ best_solution.first, best_solution.second });
paint.push_back({ simulation_budget, best_solution.second });
}
}
}
++i;
}
else
{
// 以重采样策略在已接受采样点集采样一个点
int k_ = M(int(pow(k, 1 / b)), b); // 上一次采样时的迭代次数k
vector<float> probability(accepted_set.size());
float tk_ = Tk_(T, k_);
float pk = 0.0f;
for (unsigned int i = 0; i < accepted_set.size(); ++i)
{
probability[i] = pk + exp(accepted_set[i].second / tk_);
pk = probability[i];
}
float resample = uniformly_distribution(0.0f, probability[probability.size() - 1]);
int resample_loc = find_resample(resample, probability);
//float resample_value = test_1_smooth(accepted_set[resample_loc].first);
//float resample_value = test_2_twohills(accepted_set[resample_loc].first);
float resample_value = test_3_rosenbrock(accepted_set[resample_loc].first);
++simulation_budget;
estimated_value[resample_loc].first += resample_value;
estimated_value[resample_loc].second += 1;
accepted_set[resample_loc].second = estimated_value[resample_loc].first / estimated_value[resample_loc].second;
if (accepted_set[resample_loc].second > accepted_set[best_solution_loc].second)
{
best_solution = { accepted_set[resample_loc].first, accepted_set[resample_loc].second };
best_solution_loc = resample_loc;
best_solution_change.push_back({ best_solution.first, best_solution.second });
paint.push_back({ simulation_budget, best_solution.second });
}
}
}
finish = clock();
float duration = (float)(finish - start) / CLOCKS_PER_SEC; // 程序运行时间
cout << "程序运行耗时: " << duration << "秒。" << endl;
for (int i = 0; i < dimension; ++i)
cout << best_solution.first[i] << ",";
result = best_solution.second;
cout << "收敛性:" << endl;
for (unsigned int i = 0; i < best_solution_change.size(); ++i)
{
cout << "[" << best_solution_change[i].first[0] << "," << best_solution_change[i].first[1] << "]" << ":" << best_solution_change[i].second;
//cout << " "<<test_1_smooth_without_noise(best_solution_change[i].first) << endl;
//cout << " " << test_2_twohills_without_noise(best_solution_change[i].first) << endl;
cout << " " << test_3_rosenbrock_without_noise(best_solution_change[i].first) << endl;
}
cout << "****************************分割线*******************************" << endl;
for (unsigned int i = 0; i < best_solution_change.size(); ++i)
{
//cout << "[" << paint[i].first << "," << paint[i].second << "]" << ",";
//cout << "[" << paint[i].first << "," << test_1_smooth_without_noise(best_solution_change[i].first) << "]" << ",";
//cout << "[" << paint[i].first << "," << test_2_twohills_without_noise(best_solution_change[i].first) << "]" << ",";
cout << "[" << paint[i].first << "," << test_3_rosenbrock_without_noise(best_solution_change[i].first) << "]" << ",";
cout << endl;
}
cout << "最佳点" << best_solution_change.size() << endl;
return result;
}
int M(int i, float b)
{
return int(pow(i, b));
}
int rise_rate_K(int k, float c, float Ck)
{
return int(Ck * pow(k, c) + 1);
}
float Tk_(float T, int k_)
{
return T / float(log(k_ + 1));
}
float uniformly_distribution(float a,float b) // N(a,b)均匀分布
{
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
default_random_engine generator(seed);
uniform_real_distribution<float> distribution(a, b);
return distribution(generator);
}
int find_resample(float resample, vector<float> probability)
{
int begin = 0;
int end = probability.size();
while (begin < end)
{
int mid = begin + (end - begin) / 2;
if (probability[mid] > resample)
{
end = mid;
}
else if (probability[mid] < resample)
{
begin = mid + 1;
}
else
{
return mid;
}
}
if (begin == 0)
return 0;
return begin - 1;
}
bool float_equal(float a, float b)
{
if (abs(a - b) < FLT_EPSILON)
return true;
else
return false;
}
float noise(int mean_value, int variance) // N(0,1)正态分布
{
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
default_random_engine generator(seed);
normal_distribution<float> dist(mean_value, variance);
float noise_ = dist(generator);
return noise_;
}
float test_1_smooth_without_noise(vector<float> solution)
{
float res = -((solution[0] - 0.5f) * sin(10 * solution[0]) + (solution[1] + 0.5f) * cos(5 * solution[1]));
return res;
}
float test_1_smooth(vector<float> solution)
{
float res = -((solution[0] - 0.5f) * sin(10 * solution[0]) + (solution[1] + 0.5f) * cos(5 * solution[1]));
res = res + noise(0,1);
return res;
}
float test_2_twohills_without_noise(vector<float> solution)
{
float f1 = -pow(0.4f * solution[0] - 5, 2) - 2 * pow(0.4f * solution[1] - 17, 2) + 7;
float f2 = -pow(0.4f * solution[0] - 12, 2) - pow(0.4f * solution[1] - 4, 2) + 4;
float res = max(f1, f2);
res = max(res, 0);
return res;
}
float test_2_twohills(vector<float> solution)
{
float f1 = - pow(0.4f * solution[0] - 5, 2) - 2 * pow(0.4f * solution[1] - 17, 2) + 7;
float f2 = -pow(0.4f * solution[0] - 12, 2) - pow(0.4f * solution[1] - 4, 2) + 4;
float res = max(f1, f2);
res = max(res, 0);
return res + noise(0, 50);
}
float test_3_rosenbrock_without_noise(vector<float> solution)
{
float res = 0;
for (unsigned int i = 0; i < solution.size() - 1; ++i)
{
res = res + (pow(1 - solution[i], 2) + 100 * pow(solution[i + 1] - pow(solution[i], 2), 2));
}
res = -(res + 1);
return res;
}
float test_3_rosenbrock(vector<float> solution)
{
float res = 0;
for (unsigned int i = 0; i < solution.size() - 1; ++i)
{
res = res + (pow(1 - solution[i], 2) + 100 * pow(solution[i + 1] - pow(solution[i], 2), 2));
}
res = -(res + 1);
return res + noise(0, 100);
}