MyLibs 1.0
Расширенные библиотеки для STM32
Loading...
Searching...
No Matches
evolve_optimizer.h
Go to the documentation of this file.
1/**
2******************************************************************************
3* @file evolve_optimizer.h
4* @brief Заголовочный файл для адаптивного подбора параметров
5******************************************************************************
6* @addtogroup EVOLVE_OPTIMIZER Evolve optimizer
7* @ingroup MYLIBS_DEFINES
8* @brief Библиотека для эволюционного подбора параметров
9* @details
10Поддерживает:
11- Любое количество параметров
12- Генерацию новых параметров на основе лучших кандидатов
13- Мутацию для поиска оптимальных параметров
14- Несколько независимых оптимизаторов в одной программе
15
16Если библиотека отключена @ref ENABLE_EVOLVE_OPTIMIZATION, то вставляются
17заглушки, никак не влияющие на параметры и остальную программу
18
19@par Пример использования:
20@code
21#include "evolve_optimizer.h"
22#define N_PARAMS 4
23#define N_CANDIDATES 100
24#define N_BEST 10
25#define IQ_MUTATION 655
26int32_t params[N_PARAMS];
27EvolveOptimizer_t optimizer;
28
29// Формирование параметров
30uint16_t param_u16 = 800;
31float param_f = 0.01f;
32uint8_t param_u8 = 40;
33int16_t param_i16 = 1600;
34params[0] = PARAM_SCALE_Q16(param_u16, 0, 1000);
35params[1] = PARAM_SCALE_Q16(param_f, 0.001f, 0.1f);
36params[2] = PARAM_SCALE_Q16(param_u8, 10, 100);
37params[3] = PARAM_SCALE_Q16(param_i16, 500, 5000);
38
39// Инициалиазция
40EvolveOptimizer_Init(&optimizer, N_PARAMS, N_CANDIDATES, N_BEST, IQ_MUTATION, params);
41
42// Шаг эволюции
43int32_t loss = calc_iq_loss(); // расчет эффективности параметров
44EvolveOptimizer_Step(&optimizer, params, loss);
45
46// Взятие следующих для эволюции параметров
47param_u16 = PARAM_UNSCALE_Q16(params[0], 0, 1000);
48param_f = PARAM_UNSCALE_Q16(params[1], 0.001f, 0.1f);
49param_u8 = PARAM_UNSCALE_Q16(params[2], 10, 100);
50param_i16 = PARAM_UNSCALE_Q16(params[3], 500, 5000);
51@endcode
52* @{
53*****************************************************************************/
54#ifndef __EVOLVE_OPTIMIZER_H_
55#define __EVOLVE_OPTIMIZER_H_
56
57#include "mylibs_defs.h"
58#include <stdint.h>
59#include <stdlib.h>
60
61#ifdef ENABLE_EVOLVE_OPTIMIZATION
62
63#define Q16_MUL(a,b) ((int32_t)(((int64_t)(a) * (int64_t)(b)) >> 16))
64
65/**
66 * @brief Линейное масштабирование x из диапазона [min_val, max_val] в Q16.16 [0, 65536)
67 */
68#define PARAM_SCALE_Q16(x, min_val, max_val) \
69((int32_t)((((float)(x) - (float)(min_val)) / ((float)(max_val) - (float)(min_val))) * 65536.0f))
70
71/**
72 * @brief Обратное линейное масштабирование Q16.16 значения в диапазон [min_val, max_val]
73 */
74#define PARAM_UNSCALE_Q16(q16_val, min_val, max_val) \
75(((float)(q16_val) / 65536.0f) * ((float)(max_val) - (float)(min_val)) + (float)(min_val))
76
77
78/**
79 * @brief Структура эволюционного оптимизатора
80 */
81typedef struct {
82 uint16_t n_params; ///< Количество параметров
83 uint16_t n_cand; ///< Количество кандидатов
84 uint16_t n_best; ///< Количество лучших, усредняемых
85 uint16_t iq_mutation; ///< Амплитуда мутации в Q16.16
86 uint16_t cand_index; ///< Индекс кандидата для обработки
87 int32_t loss[EVOLVE_MAX_CANDIDATES]; ///< Loss для каждого кандидата
88 int32_t candidates[EVOLVE_MAX_CANDIDATES][EVOLVE_MAX_PARAMS]; ///< Параметры кандидатов
90
91
92/**
93 * @brief Инициализация эволюционного оптимизатора.
94 * @param opt Указатель на структуру оптимизатора
95 * @param n_params Количество параметров в одном кандидате
96 * @param n_cand Количество кандидатов
97 * @param n_best Количество лучших, усредняемых
98 * @param iq_mutation Амплитуда мутации в Q16.16
99 * @param start_params Начальные параметры (Q16.16)
100 */
101__STATIC_INLINE void EvolveOptimizer_Init(EvolveOptimizer_t* opt,
102 uint16_t n_params,
103 uint16_t n_cand,
104 uint16_t n_best,
105 uint16_t iq_mutation,
106 int32_t* start_params)
107{
108 if(check_null_ptr_2(opt, start_params))
109 return;
110
111 opt->n_params = n_params;
112 opt->n_cand = n_cand;
113 opt->n_best = n_best;
114 opt->iq_mutation = iq_mutation;
115
116 for (uint16_t i = 0; i < n_cand; i++) {
117 for (uint16_t j = 0; j < n_params; j++) {
118 opt->candidates[i][j] = start_params[j];
119 }
120 opt->loss[i] = 0;
121 }
122}
123
124
125/**
126 * @brief Один шаг эволюционного оптимизатора.
127 * @param opt Указатель на структуру оптимизатора
128 * @param params Массив параметров, которые будут обновлены (на выходе — новые параметры)
129 * @param loss Loss текущего кандидата (Q16.16)
130 * @details
131 * Сохраняет loss текущего кандидата и формирует параметры следующего кандидата.
132 * Если накоплено n_cand кандидатов, генерируется новое поколение.
133 * Новое поколение формируется случайным выбором из n_best лучших с добавлением мутации.
134 *
135 * На выходе params содержит параметры следующего кандидата для измерений.
136 */
137__STATIC_INLINE void EvolveOptimizer_Step(EvolveOptimizer_t* opt,
138 int32_t* params,
139 int32_t loss)
140{
141 if(check_null_ptr_2(opt, params))
142 return;
143
144 uint16_t n_params = opt->n_params;
145 uint16_t n_cand = opt->n_cand;
146 uint16_t n_best = opt->n_best;
147 uint16_t mut = opt->iq_mutation;
148
149 // 1. Сохраняем loss текущего кандидата
150 opt->loss[opt->cand_index] = loss;
151
152 opt->cand_index++;
153
154 if (opt->cand_index >= n_cand) {
155 // 2. Сортируем текущее поколение по loss
156 for (uint16_t i = 0; i < n_cand - 1; i++) {
157 for (uint16_t j = i + 1; j < n_cand; j++) {
158 if (opt->loss[j] < opt->loss[i]) {
159 int32_t tmp_loss = opt->loss[i];
160 opt->loss[i] = opt->loss[j];
161 opt->loss[j] = tmp_loss;
162
163 for (uint16_t k = 0; k < n_params; k++) {
164 int32_t tmp = opt->candidates[i][k];
165 opt->candidates[i][k] = opt->candidates[j][k];
166 opt->candidates[j][k] = tmp;
167 }
168 }
169 }
170 }
171
172 // 3. Генерируем новое поколение: каждый кандидат берется случайно из лучших с мутацией
173 uint16_t n_elite = 2; // количество элитных кандидатов, которые сохраняем без изменений
174 for (uint16_t c = 0; c < n_cand; c++) {
175 if (c < n_elite) {
176 // Копируем лучших кандидатов напрямую без мутации
177 for (uint16_t i = 0; i < n_params; i++) {
178 opt->candidates[c][i] = opt->candidates[c][i]; // просто сохраняем параметры
179 }
180 opt->loss[c] = 0;
181 } else {
182 // Остальные кандидаты формируются с кроссовером и мутацией
183 for (uint16_t i = 0; i < n_params; i++) {
184 int32_t noise = (rand() % (2 * mut)) - mut;
185 uint16_t parent = rand() % n_best; // каждый параметр из случайного лучшего
186 opt->candidates[c][i] = opt->candidates[parent][i] + noise;
187 }
188 opt->loss[c] = 0;
189 }
190 }
191 opt->cand_index = 0;
192 }
193
194 // 4. Возвращаем параметры следующего кандидата
195 for (uint16_t i = 0; i < opt->n_params; i++)
196 params[i] = opt->candidates[opt->cand_index][i];
197}
198#else // ENABLE_EVOLVE_OPTIMIZATION
199//заглушки
200typedef struct {
201 uint16_t n_params;
202 uint16_t n_cand;
203 uint16_t n_best;
204 uint16_t iq_mutation;
205 int32_t loss[0];
206 int32_t candidates[0][0];
208#define EvolveOptimizer_Init(opt, n_params, n_cand, n_best, iq_mutation, start_params)
209#define EvolveOptimizer_Step(opt, params, LossFunc)
210#define PARAM_SCALE_Q16(x, min_val, max_val) (x)
211#define PARAM_UNSCALE_Q16(q16_val, min_val, max_val) (q16_val) (q16_val)
212#endif // ENABLE_EVOLVE_OPTIMIZATION
213
214#endif // __EVOLVE_OPTIMIZER_H_
215
216/** EVOLVE_OPTIMIZER
217 * @}
218 */
#define check_null_ptr_2(p1, p2)
Проверить два указателя на NULL.
Definition mylibs_defs.h:41
#define EVOLVE_MAX_CANDIDATES
Максимальное количество кандидатов для обучения
#define EVOLVE_MAX_PARAMS
Максимальное количество параметров
__STATIC_INLINE void EvolveOptimizer_Step(EvolveOptimizer_t *opt, int32_t *params, int32_t loss)
Один шаг эволюционного оптимизатора.
__STATIC_INLINE void EvolveOptimizer_Init(EvolveOptimizer_t *opt, uint16_t n_params, uint16_t n_cand, uint16_t n_best, uint16_t iq_mutation, int32_t *start_params)
Инициализация эволюционного оптимизатора.
Заголочный файл для дефайнов библиотеки MyLibsGeneral.
Структура эволюционного оптимизатора
uint16_t cand_index
Индекс кандидата для обработки
uint16_t n_params
Количество параметров
uint16_t iq_mutation
Амплитуда мутации в Q16.16.
int32_t candidates[100][20]
Параметры кандидатов
uint16_t n_best
Количество лучших, усредняемых
uint16_t n_cand
Количество кандидатов
int32_t loss[100]
Loss для каждого кандидата