static __declspec(noalias)std::vector<float> Base_...
Tạo vào: 4 tháng 9, 2025
Tạo vào: 4 tháng 9, 2025
static __declspec(noalias)std::vector<float> Base_LNA_1_2_Mer_AGP(const uint32_t N,
const uint32_t global_iterations, const float a, const float b, const float c, const float d, const float r,
const bool mode, const float epsilon, const float seed) noexcept
{
textif (N == 1u) { const float initial_length = b - a; float dmax = initial_length; const float start_val = ShekelFunc(a, seed); float best_f = ShekelFunc(b, seed); uint32_t schetchick = 0u; std::pair<float, float> x_Rmax = std::make_pair(a, b); std::pair<float, float> y_Rmax = std::make_pair(start_val, best_f); std::vector<float> Extr; Extr.reserve((global_iterations << 1u) + 4u); std::vector<Interval> R; R.reserve(global_iterations + 1u); R.emplace_back(std::make_pair(a, start_val), std::make_pair(b, best_f), N); float Mmax = R.front().M; float m = r * Mmax; const float threshold_03 = 0.3f * initial_length; const float inv_threshold_03 = 1.0f / threshold_03; while (true) { if (++schetchick == global_iterations) { const Interval& front = R.front(); Extr.emplace_back(front.end.first - front.start.first); Extr.emplace_back(global_iterations); return Extr; } const float new_point = Shag(m, x_Rmax.first, x_Rmax.second, y_Rmax.first, y_Rmax.second, N, r); const float new_value = ShekelFunc(new_point, seed); const std::pair<float, float> promejutochnaya_tochka{ new_point, new_value }; if (new_value < best_f) { best_f = new_value; Extr.emplace_back(best_f); Extr.emplace_back(new_point); } std::pop_heap(R.begin(), R.end(), Compare); Interval promejutochny_otrezok = std::move(R.back()); R.pop_back(); Interval curr(promejutochny_otrezok.start, promejutochnaya_tochka, N); Interval curr1(promejutochnaya_tochka, promejutochny_otrezok.end, N); const float currM = curr.M > curr1.M ? curr.M : curr1.M; const float len2 = promejutochny_otrezok.end.first - new_point; const float len1 = new_point - promejutochny_otrezok.start.first; const size_t r_size = R.size(); if (len2 + len1 == dmax) { dmax = len2 > len1 ? len2 : len1;
#pragma loop(ivdep)
for (size_t i = 0u; i < r_size; ++i) {
const float len = R[i].end.first - R[i].start.first;
if (len > dmax) {
dmax = len;
}
}
}
textif (mode) { if (threshold_03 > dmax && schetchick % 3u == 0u || 10.0f * dmax < initial_length) { if (currM > Mmax) { Mmax = currM; m = r * Mmax; } const float progress = fmaf(-inv_threshold_03, dmax, 1.0f); const float alpha = fmaf(progress, progress, 1.0f); const float betta = 2.0f - alpha; const float MULTIPLIER = (1.0f / dmax) * Mmax; const float global_coeff = fmaf(MULTIPLIER, r, -MULTIPLIER); const float GLOBAL_FACTOR = betta * global_coeff; curr.ChangeCharacteristic(fmaf(GLOBAL_FACTOR, len1, curr.M * alpha), N); curr1.ChangeCharacteristic(fmaf(GLOBAL_FACTOR, len2, curr1.M * alpha), N);
#pragma loop(ivdep)
for (size_t i = 0u; i < r_size; ++i) {
const float len_item = R[i].end.first - R[i].start.first;
R[i].ChangeCharacteristic(fmaf(GLOBAL_FACTOR, len_item, R[i].M * alpha), N);
}
std::make_heap(R.begin(), R.end(), Compare);
}
else {
if (currM > Mmax) {
Mmax = currM;
m = r * Mmax;
curr.ChangeCharacteristic(m, N);
curr1.ChangeCharacteristic(m, N);
#pragma loop(ivdep)
for (size_t i = 0u; i < r_size; ++i) {
R[i].ChangeCharacteristic(m, N);
}
std::make_heap(R.begin(), R.end(), Compare);
}
else {
curr.ChangeCharacteristic(m, N);
curr1.ChangeCharacteristic(m, N);
}
}
}
else {
if (currM > Mmax) {
Mmax = currM;
m = r * Mmax;
curr.ChangeCharacteristic(m, N);
curr1.ChangeCharacteristic(m, N);
#pragma loop(ivdep)
for (size_t i = 0u; i < r_size; ++i) {
R[i].ChangeCharacteristic(m, N);
}
std::make_heap(R.begin(), R.end(), Compare);
}
else {
curr.ChangeCharacteristic(m, N);
curr1.ChangeCharacteristic(m, N);
}
}
textR.emplace_back(std::move(curr)); std::push_heap(R.begin(), R.end(), Compare); R.emplace_back(std::move(curr1)); std::push_heap(R.begin(), R.end(), Compare); const Interval& top = R.front(); const float interval_length = top.end.first - top.start.first; if (interval_length < epsilon) { Extr.emplace_back(interval_length); Extr.emplace_back(schetchick); return Extr; } x_Rmax = std::make_pair(top.start.first, top.end.first); y_Rmax = std::make_pair(top.start.second, top.end.second); } } - внимательно проверь этот алгоритм - тут где-то есть ошибка попытки изъятия интервала из вектора интервалов когда вектор уже пуст - найди места где это потенциально может происходить - не надо говорить про все места где берётся интервал из вектора и делать лишние проверки не пуст ли вектор - найди именно место падения где это гарантированно происходит и найди причину почему происходит
Краш происходит вот здесь (внутри первой же итерации цикла), в связке:
cppstd::pop_heap(R.begin(), R.end(), Compare); Interval promejutochny_otrezok = std::move(R.back()); R.pop_back(); // <-- в этот момент R временно пуст
и дальше — в этом же обороте — вы заходите в “адаптивную” ветку и делаете:
cppconst float MULTIPLIER = (1.0f / dmax) * Mmax; // <-- деление на ноль, если dmax == 0
а затем меняете характеристики интервалов и перестраиваете кучу:
cpp// ... ChangeCharacteristic(...) ... std::make_heap(R.begin(), R.end(), Compare);
После pop_back()
вектор R
пуст до тех пор, пока вы не добавите curr
и curr1
. Если в этот момент dmax == 0
, то 1.0f / dmax
даёт inf/NaN
, что попадает в ChangeCharacteristic(...)
. В результате значения M
становятся NaN/inf
, сравнение в Compare
перестаёт быть строгим слабым порядком, и std::make_heap
оставляет структуру кучи в неопределённом состоянии. На следующей строке вы продолжаете выполнение, но до добавления curr
/curr1
вектор всё ещё пуст, и при следующем обращении к куче (следующая итерация — std::pop_heap
, либо доступ через R.front()
при раннем выходе) вы попадаете в “изъятие интервала из пустого вектора”.
Почему именно гарантированно возникает dmax == 0
:
a == b
(тогда initial_length == 0
, dmax == 0
уже до цикла);Shag(...)
возвращает одну из границ текущего отрезка (или численно совпадает с ней из-за округления), и вы многократно делите нулевую длину — len1 == 0
, len2 == 0
, отсюда dmax
остаётся 0.Ключевая цепочка событий:
pop_heap
/pop_back
делают R
пустым на этот момент итерации.if ((threshold_03 > dmax && schetchick % 3 == 0) || 10*dmax < initial_length)
при dmax == 0
неизбежно активируется из-за второй части (10*0 < initial_length
при положительной длине в начале, а при вырожденном старте — вы дальше всё равно делите на ноль).1.0f / dmax
→ inf
, характеристики становятся NaN/inf
, Compare
теряет корректность → make_heap
/кучевые операции разрушают инвариант.Итог: место падения — блок извлечения “топового” интервала (последовательность pop_heap
→ R.back()
→ pop_back()
), а первопричина — деление на ноль при вычислении MULTIPLIER
, которое вносит NaN/inf
в ключ сортировки, ломает кучу и приводит к последующему извлечению из пустого R
.
Минимально достаточная правка по сути:
1.0f / dmax
, когда dmax == 0
(и вообще не пересчитывать глобальные коэффициенты при нулевой длине);pop_heap
проверять, что верхний отрезок имеет ненулевую длину и сразу выходить (что логически корректнее), чтобы не оставлять R
пустым на участке, где вы делаете глобальную перенастройку характеристик.