std::vector<float> Base_LNA_1_2_Mer_AGP( t...

Créé le : 11 août 2025

Répondu en utilisant GPT-5 Thinking par Chat01

Question

std::vector<float> Base_LNA_1_2_Mer_AGP(
time_t now, bool mode, unsigned short N, float a, float b,
PeanoCurve_2D ^ Curve, PeanoCurve_2D ^ Curve_Minus_PI_Na_Dva,
unsigned short r, float epsilon, unsigned short global_iterations,
unsigned short global_local_iterations, float c, float d) {
std::pair<float, float> start, end, start_Minus_PI_Na_Dva,
end_Minus_PI_Na_Dva;
std::pair<float, float> x_Rmax, y_Rmax, x_Rmax_Minus_PI_Na_Dva,
y_Rmax_Minus_PI_Na_Dva;
std::pair<float, float> pred_i_sled_shag, pred_i_sled_shag_Minus_PI_Na_Dva;
std::pair<float, float> promejutochnaya_tochka,
promejutochnaya_tochka_Minus_PI_Na_Dva;

text
float Mmax, Mmax_Minus_PI_Na_Dva, m, m_Minus_PI_Na_Dva; float dmax, dmax_Minus_PI_Na_Dva, eta_shtrih; std::vector<Interval> R, R_Minus_PI_Na_Dva, R1, R1_Minus_PI_Na_Dva; std::vector<float> Extr, Extr_Minus_PI_Na_Dva; unsigned short schetchick = 0; if (N == 1) { HINSTANCE load_function = LoadLibrary(L"TEST_FUNC.dll"); typedef float (*sh)(float, time_t); sh ShekelFunc = (sh)GetProcAddress(load_function, "ShekelFunc"); start = std::pair<float, float>(a, ShekelFunc(a, now)); end = std::pair<float, float>(b, ShekelFunc(b, now)); Interval nachalny_otrezok = Interval(start, end, N); Mmax = nachalny_otrezok.M; m = r * Mmax; x_Rmax = std::pair<float, float>(start.first, end.first); y_Rmax = std::pair<float, float>(start.second, end.second); R.push_back(nachalny_otrezok); std::push_heap(R.begin(), R.end(), Compare{}); pred_i_sled_shag = std::pair<float, float>(a, b); while (true) { pred_i_sled_shag.first = pred_i_sled_shag.second; promejutochnaya_tochka.first = pred_i_sled_shag.second = Shag( m, x_Rmax.first, x_Rmax.second, y_Rmax.first, y_Rmax.second, N, r); promejutochnaya_tochka.second = ShekelFunc(pred_i_sled_shag.second, now); float min = promejutochnaya_tochka.second; if (!Extr.empty() && min > Extr.back()) { min = Extr.back(); } Extr.push_back(min); if (schetchick == global_iterations) { FreeLibrary(load_function); return Extr; } std::pop_heap(R.begin(), R.end(), Compare{}); Interval promejutochny_otrezok = R.back(); R.pop_back(); Interval curr = Interval(promejutochny_otrezok.start, promejutochnaya_tochka, N); Interval curr1 = Interval(promejutochnaya_tochka, promejutochny_otrezok.end, N); if (mode && schetchick > global_local_iterations && schetchick % 2 == 0 && schetchick < 50) { if ((std::max)(curr.M, curr1.M) > Mmax || min == promejutochnaya_tochka.second) { Mmax = (std::max)(curr.M, curr1.M); m = r * Mmax; } std::pop_heap(R.begin(), R.end(), Compare{}); promejutochny_otrezok = R.back(); R.pop_back(); eta_shtrih = (std::max)((std::max)(curr.M, curr1.M), promejutochny_otrezok.M); promejutochny_otrezok.ChangeCharacteristic( r * Mmax * (promejutochny_otrezok.end.first - promejutochny_otrezok.start.first) / dmax + eta_shtrih - Mmax * (promejutochny_otrezok.end.first - promejutochny_otrezok.start.first) / dmax, N); R.push_back(promejutochny_otrezok); std::push_heap(R.begin(), R.end(), Compare{}); while (!R.empty()) { std::pop_heap(R.begin(), R.end(), Compare{}); promejutochny_otrezok = R.back(); R.pop_back(); eta_shtrih = (std::max)((std::max)(curr.M, curr1.M), promejutochny_otrezok.M); promejutochny_otrezok.ChangeCharacteristic( r * Mmax * (promejutochny_otrezok.end.first - promejutochny_otrezok.start.first) / dmax + eta_shtrih - Mmax * (promejutochny_otrezok.end.first - promejutochny_otrezok.start.first) / dmax, N); R1.push_back(promejutochny_otrezok); std::push_heap(R1.begin(), R1.end(), Compare{}); if (R1.size() == 1) { curr.ChangeCharacteristic( r * Mmax * (curr.end.first - curr.start.first) / dmax + eta_shtrih - Mmax * (curr.end.first - curr.start.first) / dmax, N); curr1.ChangeCharacteristic( r * Mmax * (curr1.end.first - curr1.start.first) / dmax + eta_shtrih - Mmax * (curr1.end.first - curr1.start.first) / dmax, N); } } R.swap(R1); R1.clear(); } else { if ((std::max)(curr.M, curr1.M) < Mmax && min != promejutochnaya_tochka.second) { curr.ChangeCharacteristic(m, N); curr1.ChangeCharacteristic(m, N); } else { Mmax = (std::max)(curr.M, curr1.M); m = r * Mmax; curr.ChangeCharacteristic(m, N); curr1.ChangeCharacteristic(m, N); if (mode) { dmax = (std::max)(powf((curr.end).first - (curr.start).first, (1.0f / float(N))), powf((curr1.end).first - (curr1.start).first, (1.0f / float(N)))); } while (!R.empty()) { std::pop_heap(R.begin(), R.end(), Compare{}); promejutochny_otrezok = R.back(); R.pop_back(); if (mode && powf((promejutochny_otrezok.end).first - (promejutochny_otrezok.start).first, (1.0f / float(N))) > dmax) { dmax = powf((promejutochny_otrezok.end).first - (promejutochny_otrezok.start).first, (1.0f / float(N))); } promejutochny_otrezok.ChangeCharacteristic(m, N); R1.push_back(promejutochny_otrezok); std::push_heap(R1.begin(), R1.end(), Compare{}); } R.swap(R1); R1.clear(); } } R.push_back(curr); std::push_heap(R.begin(), R.end(), Compare{}); R.push_back(curr1); std::push_heap(R.begin(), R.end(), Compare{}); promejutochny_otrezok = R.front(); if (fabsf(promejutochny_otrezok.end.first - promejutochny_otrezok.start.first) < epsilon) { FreeLibrary(load_function); return Extr; } x_Rmax.first = promejutochny_otrezok.start.first; x_Rmax.second = promejutochny_otrezok.end.first; y_Rmax.first = promejutochny_otrezok.start.second; y_Rmax.second = promejutochny_otrezok.end.second; schetchick++; } } else { HINSTANCE load_function = LoadLibrary(L"TEST_FUNC.dll"); typedef float (*rr)(float, float); rr RastriginFunc = (rr)GetProcAddress(load_function, "RastriginFunc"); // Внимание на скобки: float divider = static_cast<float>(1 << (2 * Curve->razvertka + 1)); float x_addition = (b - a) / divider; float y_addition = (d - c) / divider; float true_start = a + x_addition; float true_end = b - x_addition; start = std::pair<float, float>( true_start, RastriginFunc(true_start, c + y_addition)); end = std::pair<float, float>(true_end, RastriginFunc(true_end, c + y_addition)); start_Minus_PI_Na_Dva = std::pair<float, float>( true_start, RastriginFunc(true_end, d - y_addition)); end_Minus_PI_Na_Dva = std::pair<float, float>( true_end, RastriginFunc(true_start, d - y_addition)); Interval nachalny_otrezok = Interval(start, end, N); Interval nachalny_otrezok_Minus_PI_Na_Dva = Interval(start_Minus_PI_Na_Dva, end_Minus_PI_Na_Dva, N); Mmax = nachalny_otrezok.M; m = r * Mmax; x_Rmax = std::pair<float, float>(start.first, end.first); y_Rmax = std::pair<float, float>(start.second, end.second); Mmax_Minus_PI_Na_Dva = nachalny_otrezok_Minus_PI_Na_Dva.M; m_Minus_PI_Na_Dva = r * Mmax_Minus_PI_Na_Dva; R.clear(); R_Minus_PI_Na_Dva.clear(); R1.clear(); R1_Minus_PI_Na_Dva.clear(); R.push_back(nachalny_otrezok); std::push_heap(R.begin(), R.end(), Compare{}); R_Minus_PI_Na_Dva.push_back(nachalny_otrezok_Minus_PI_Na_Dva); std::push_heap(R_Minus_PI_Na_Dva.begin(), R_Minus_PI_Na_Dva.end(), Compare{}); x_Rmax_Minus_PI_Na_Dva = std::pair<float, float>( start_Minus_PI_Na_Dva.first, end_Minus_PI_Na_Dva.first); y_Rmax_Minus_PI_Na_Dva = std::pair<float, float>( start_Minus_PI_Na_Dva.second, end_Minus_PI_Na_Dva.second); pred_i_sled_shag = std::pair<float, float>(true_start, true_end); pred_i_sled_shag_Minus_PI_Na_Dva = std::pair<float, float>(true_start, true_end); while (true) { // Шаги по параметру pred_i_sled_shag.first = pred_i_sled_shag.second; promejutochnaya_tochka.first = pred_i_sled_shag.second = Shag( m, x_Rmax.first, x_Rmax.second, y_Rmax.first, y_Rmax.second, N, r); pred_i_sled_shag_Minus_PI_Na_Dva.first = pred_i_sled_shag_Minus_PI_Na_Dva.second; promejutochnaya_tochka_Minus_PI_Na_Dva.first = pred_i_sled_shag_Minus_PI_Na_Dva.second = Shag( m_Minus_PI_Na_Dva, x_Rmax_Minus_PI_Na_Dva.first, x_Rmax_Minus_PI_Na_Dva.second, y_Rmax_Minus_PI_Na_Dva.first, y_Rmax_Minus_PI_Na_Dva.second, N, r); float x1 = Curve->HitTest_2D(pred_i_sled_shag.second).first; float x2 = Curve->HitTest_2D(pred_i_sled_shag.second).second; float x1_Minus_PI_Na_Dva = Curve_Minus_PI_Na_Dva ->HitTest_2D(pred_i_sled_shag_Minus_PI_Na_Dva.second) .first; float x2_Minus_PI_Na_Dva = Curve_Minus_PI_Na_Dva ->HitTest_2D(pred_i_sled_shag_Minus_PI_Na_Dva.second) .second; promejutochnaya_tochka.second = RastriginFunc(x1, x2); promejutochnaya_tochka_Minus_PI_Na_Dva.second = RastriginFunc(x1_Minus_PI_Na_Dva, x2_Minus_PI_Na_Dva); float min = promejutochnaya_tochka.second; float min_Minus_PI_Na_Dva = promejutochnaya_tochka_Minus_PI_Na_Dva.second; if (min < min_Minus_PI_Na_Dva) { chart2->Series[0]->Points->AddXY(x1, x2); } else { chart2->Series[0]->Points->AddXY(x1_Minus_PI_Na_Dva, x2_Minus_PI_Na_Dva); } if (Extr.empty() || min < Extr.back()) { Extr.push_back(min); } if (Extr_Minus_PI_Na_Dva.empty() || min_Minus_PI_Na_Dva < Extr_Minus_PI_Na_Dva.back()) { Extr_Minus_PI_Na_Dva.push_back(min_Minus_PI_Na_Dva); } if (schetchick == global_iterations) { textBox6->Text = Convert::ToString(global_iterations); // аккуратность по текущим топам float accA = !R.empty() ? fabsf(R.front().end.first - R.front().start.first) : 0.0f; float accB = !R_Minus_PI_Na_Dva.empty() ? fabsf(R_Minus_PI_Na_Dva.front().end.first - R_Minus_PI_Na_Dva.front().start.first) : 0.0f; textBox7->Text = Convert::ToString((std::max)(accA, accB)); if (min < min_Minus_PI_Na_Dva) { chart2->Series[2]->Points->AddXY(x1, x2); textBox4->Text = Convert::ToString(x1); textBox3->Text = Convert::ToString(x2); } else { chart2->Series[2]->Points->AddXY(x1_Minus_PI_Na_Dva, x2_Minus_PI_Na_Dva); textBox4->Text = Convert::ToString(x1_Minus_PI_Na_Dva); textBox3->Text = Convert::ToString(x2_Minus_PI_Na_Dva); } FreeLibrary(load_function); return Extr.back() < Extr_Minus_PI_Na_Dva.back() ? Extr : Extr_Minus_PI_Na_Dva; } // Достаём по одному лучшему отрезку из каждой кучи std::pop_heap(R.begin(), R.end(), Compare{}); Interval promejutochny_otrezok = R.back(); R.pop_back(); std::pop_heap(R_Minus_PI_Na_Dva.begin(), R_Minus_PI_Na_Dva.end(), Compare{}); Interval promejutochny_otrezok_Minus_PI_Na_Dva = R_Minus_PI_Na_Dva.back(); R_Minus_PI_Na_Dva.pop_back(); // Делаем разбиение Interval curr = Interval(promejutochny_otrezok.start, promejutochnaya_tochka, N); Interval curr1 = Interval(promejutochnaya_tochka, promejutochny_otrezok.end, N); Interval curr_Minus_PI_Na_Dva = Interval(promejutochny_otrezok_Minus_PI_Na_Dva.start, promejutochnaya_tochka_Minus_PI_Na_Dva, N); Interval curr1_Minus_PI_Na_Dva = Interval(promejutochnaya_tochka_Minus_PI_Na_Dva, promejutochny_otrezok_Minus_PI_Na_Dva.end, N); // "Охлаждение" и кросс-инъекция между очередями { float cooling = exp(-schetchick / 200.0f); int T = 10 + static_cast<int>(20 * cooling); float k = 0.7f + 0.2f * cooling; if (schetchick % T == 0 && schetchick > T && !R.empty() && !R_Minus_PI_Na_Dva.empty()) { // Берём текущие вершины без извлечения const Interval& topA = R.front(); auto p1 = Curve->HitTest_2D(topA.start.first); auto p2 = Curve->HitTest_2D(topA.end.first); float newParam1 = Curve_Minus_PI_Na_Dva->FindX_2D(% p1); float newParam2 = Curve_Minus_PI_Na_Dva->FindX_2D(% p2); std::pair<float, float> newStart(newParam1, topA.start.second); std::pair<float, float> newEnd(newParam2, topA.end.second); Interval newInterval(newStart, newEnd, N); newInterval.R = topA.R * k; R_Minus_PI_Na_Dva.push_back(newInterval); std::push_heap(R_Minus_PI_Na_Dva.begin(), R_Minus_PI_Na_Dva.end(), Compare{}); const Interval& topB = R_Minus_PI_Na_Dva.front(); p1 = Curve_Minus_PI_Na_Dva->HitTest_2D(topB.start.first); p2 = Curve_Minus_PI_Na_Dva->HitTest_2D(topB.end.first); newParam1 = Curve->FindX_2D(% p1); newParam2 = Curve->FindX_2D(% p2); newStart = std::pair<float, float>(newParam1, topB.start.second); newEnd = std::pair<float, float>(newParam2, topB.end.second); newInterval = Interval(newStart, newEnd, N); newInterval.R = topB.R * k; R.push_back(newInterval); std::push_heap(R.begin(), R.end(), Compare{}); } } // Адаптация весов для первой кучи if (mode && schetchick > global_local_iterations && (schetchick % 2 == 0)) { if ((std::max)(curr.M, curr1.M) > Mmax || min == promejutochnaya_tochka.second) { Mmax = (std::max)(curr.M, curr1.M); m = r * Mmax; } if (!R.empty()) { std::pop_heap(R.begin(), R.end(), Compare{}); promejutochny_otrezok = R.back(); R.pop_back(); eta_shtrih = (std::max)((std::max)(curr.M, curr1.M), promejutochny_otrezok.M); promejutochny_otrezok.ChangeCharacteristic( r * Mmax * (promejutochny_otrezok.end.first - promejutochny_otrezok.start.first) / dmax + eta_shtrih - Mmax * (promejutochny_otrezok.end.first - promejutochny_otrezok.start.first) / dmax, N); R.push_back(promejutochny_otrezok); std::push_heap(R.begin(), R.end(), Compare{}); } while (!R.empty()) { std::pop_heap(R.begin(), R.end(), Compare{}); promejutochny_otrezok = R.back(); R.pop_back(); eta_shtrih = (std::max)((std::max)(curr.M, curr1.M), promejutochny_otrezok.M); promejutochny_otrezok.ChangeCharacteristic( r * Mmax * (promejutochny_otrezok.end.first - promejutochny_otrezok.start.first) / dmax + eta_shtrih - Mmax * (promejutochny_otrezok.end.first - promejutochny_otrezok.start.first) / dmax, N); R1.push_back(promejutochny_otrezok); std::push_heap(R1.begin(), R1.end(), Compare{}); if (R1.size() == 1) { curr.ChangeCharacteristic( r * Mmax * (curr.end.first - curr.start.first) / dmax + eta_shtrih - Mmax * (curr.end.first - curr.start.first) / dmax, N); curr1.ChangeCharacteristic( r * Mmax * (curr1.end.first - curr1.start.first) / dmax + eta_shtrih - Mmax * (curr1.end.first - curr1.start.first) / dmax, N); } } R.swap(R1); R1.clear(); // Симметрично — для второй кучи if ((std::max)(curr_Minus_PI_Na_Dva.M, curr1_Minus_PI_Na_Dva.M) > Mmax_Minus_PI_Na_Dva || min == promejutochnaya_tochka_Minus_PI_Na_Dva.second) { Mmax_Minus_PI_Na_Dva = (std::max)(curr_Minus_PI_Na_Dva.M, curr1_Minus_PI_Na_Dva.M); m_Minus_PI_Na_Dva = r * Mmax_Minus_PI_Na_Dva; } if (!R_Minus_PI_Na_Dva.empty()) { std::pop_heap(R_Minus_PI_Na_Dva.begin(), R_Minus_PI_Na_Dva.end(), Compare{}); promejutochny_otrezok_Minus_PI_Na_Dva = R_Minus_PI_Na_Dva.back(); R_Minus_PI_Na_Dva.pop_back(); eta_shtrih = (std::max)( (std::max)(curr_Minus_PI_Na_Dva.M, curr1_Minus_PI_Na_Dva.M), promejutochny_otrezok_Minus_PI_Na_Dva.M); promejutochny_otrezok_Minus_PI_Na_Dva.ChangeCharacteristic( r * Mmax_Minus_PI_Na_Dva * (promejutochny_otrezok_Minus_PI_Na_Dva.end.first - promejutochny_otrezok_Minus_PI_Na_Dva.start.first) / dmax_Minus_PI_Na_Dva + eta_shtrih - Mmax_Minus_PI_Na_Dva * (promejutochny_otrezok_Minus_PI_Na_Dva.end.first - promejutochny_otrezok_Minus_PI_Na_Dva.start.first) / dmax_Minus_PI_Na_Dva, N); R_Minus_PI_Na_Dva.push_back(promejutochny_otrezok_Minus_PI_Na_Dva); std::push_heap(R_Minus_PI_Na_Dva.begin(), R_Minus_PI_Na_Dva.end(), Compare{}); } while (!R_Minus_PI_Na_Dva.empty()) { std::pop_heap(R_Minus_PI_Na_Dva.begin(), R_Minus_PI_Na_Dva.end(), Compare{}); promejutochny_otrezok_Minus_PI_Na_Dva = R_Minus_PI_Na_Dva.back(); R_Minus_PI_Na_Dva.pop_back(); eta_shtrih = (std::max)( (std::max)(curr_Minus_PI_Na_Dva.M, curr1_Minus_PI_Na_Dva.M), promejutochny_otrezok_Minus_PI_Na_Dva.M); promejutochny_otrezok_Minus_PI_Na_Dva.ChangeCharacteristic( r * Mmax_Minus_PI_Na_Dva * (promejutochny_otrezok_Minus_PI_Na_Dva.end.first - promejutochny_otrezok_Minus_PI_Na_Dva.start.first) / dmax_Minus_PI_Na_Dva + eta_shtrih - Mmax_Minus_PI_Na_Dva * (promejutochny_otrezok_Minus_PI_Na_Dva.end.first - promejutochny_otrezok_Minus_PI_Na_Dva.start.first) / dmax_Minus_PI_Na_Dva, N); R1_Minus_PI_Na_Dva.push_back(promejutochny_otrezok_Minus_PI_Na_Dva); std::push_heap(R1_Minus_PI_Na_Dva.begin(), R1_Minus_PI_Na_Dva.end(), Compare{}); if (R1_Minus_PI_Na_Dva.size() == 1) { curr_Minus_PI_Na_Dva.ChangeCharacteristic( r * Mmax_Minus_PI_Na_Dva * (curr_Minus_PI_Na_Dva.end.first - curr_Minus_PI_Na_Dva.start.first) / dmax_Minus_PI_Na_Dva + eta_shtrih - Mmax_Minus_PI_Na_Dva * (curr_Minus_PI_Na_Dva.end.first - curr_Minus_PI_Na_Dva.start.first) / dmax_Minus_PI_Na_Dva, N); curr1_Minus_PI_Na_Dva.ChangeCharacteristic( r * Mmax_Minus_PI_Na_Dva * (curr1_Minus_PI_Na_Dva.end.first - curr1_Minus_PI_Na_Dva.start.first) / dmax_Minus_PI_Na_Dva + eta_shtrih - Mmax_Minus_PI_Na_Dva * (curr1_Minus_PI_Na_Dva.end.first - curr1_Minus_PI_Na_Dva.start.first) / dmax_Minus_PI_Na_Dva, N); } } R_Minus_PI_Na_Dva.swap(R1_Minus_PI_Na_Dva); R1_Minus_PI_Na_Dva.clear(); } else { // без ускоряющих перестроек // Первая куча if ((std::max)(curr.M, curr1.M) < Mmax && min != Extr.back()) { curr.ChangeCharacteristic(m, N); curr1.ChangeCharacteristic(m, N); } else { Mmax = (std::max)(curr.M, curr1.M); m = r * Mmax; curr.ChangeCharacteristic(m, N); curr1.ChangeCharacteristic(m, N); if (mode) { dmax = (std::max)(powf((curr.end).first - (curr.start).first, (1.0f / float(N))), powf((curr1.end).first - (curr1.start).first, (1.0f / float(N)))); } while (!R.empty()) { std::pop_heap(R.begin(), R.end(), Compare{}); promejutochny_otrezok = R.back(); R.pop_back(); if (mode && powf((promejutochny_otrezok.end).first - (promejutochny_otrezok.start).first, (1.0f / float(N))) > dmax) { dmax = powf((promejutochny_otrezok.end).first - (promejutochny_otrezok.start).first, (1.0f / float(N))); } promejutochny_otrezok.ChangeCharacteristic(m, N); R1.push_back(promejutochny_otrezok); std::push_heap(R1.begin(), R1.end(), Compare{}); } R.swap(R1); R1.clear(); } // Вторая куча if ((std::max)(curr_Minus_PI_Na_Dva.M, curr1_Minus_PI_Na_Dva.M) < Mmax_Minus_PI_Na_Dva && min_Minus_PI_Na_Dva != Extr_Minus_PI_Na_Dva.back()) { curr_Minus_PI_Na_Dva.ChangeCharacteristic(m_Minus_PI_Na_Dva, N); curr1_Minus_PI_Na_Dva.ChangeCharacteristic(m_Minus_PI_Na_Dva, N); } else { Mmax_Minus_PI_Na_Dva = (std::max)(curr_Minus_PI_Na_Dva.M, curr1_Minus_PI_Na_Dva.M); m_Minus_PI_Na_Dva = r * Mmax_Minus_PI_Na_Dva; curr_Minus_PI_Na_Dva.ChangeCharacteristic(m_Minus_PI_Na_Dva, N); curr1_Minus_PI_Na_Dva.ChangeCharacteristic(m_Minus_PI_Na_Dva, N); if (mode) { dmax_Minus_PI_Na_Dva = (std::max)(powf((curr_Minus_PI_Na_Dva.end).first - (curr_Minus_PI_Na_Dva.start).first, (1.0f / float(N))), powf((curr1_Minus_PI_Na_Dva.end).first - (curr1_Minus_PI_Na_Dva.start).first, (1.0f / float(N)))); } while (!R_Minus_PI_Na_Dva.empty()) { std::pop_heap(R_Minus_PI_Na_Dva.begin(), R_Minus_PI_Na_Dva.end(), Compare{}); promejutochny_otrezok_Minus_PI_Na_Dva = R_Minus_PI_Na_Dva.back(); R_Minus_PI_Na_Dva.pop_back(); if (mode && powf((promejutochny_otrezok_Minus_PI_Na_Dva.end).first - (promejutochny_otrezok_Minus_PI_Na_Dva.start).first, (1.0f / float(N))) > dmax_Minus_PI_Na_Dva) { dmax_Minus_PI_Na_Dva = powf( (promejutochny_otrezok_Minus_PI_Na_Dva.end).first - (promejutochny_otrezok_Minus_PI_Na_Dva.start).first, (1.0f / float(N))); } promejutochny_otrezok_Minus_PI_Na_Dva.ChangeCharacteristic( m_Minus_PI_Na_Dva, N); R1_Minus_PI_Na_Dva.push_back( promejutochny_otrezok_Minus_PI_Na_Dva); std::push_heap(R1_Minus_PI_Na_Dva.begin(), R1_Minus_PI_Na_Dva.end(), Compare{}); } R_Minus_PI_Na_Dva.swap(R1_Minus_PI_Na_Dva); R1_Minus_PI_Na_Dva.clear(); } } // Возвращаем новые интервалы обратно в кучи R.push_back(curr); std::push_heap(R.begin(), R.end(), Compare{}); R.push_back(curr1); std::push_heap(R.begin(), R.end(), Compare{}); const Interval& topA = R.front(); R_Minus_PI_Na_Dva.push_back(curr_Minus_PI_Na_Dva); std::push_heap(R_Minus_PI_Na_Dva.begin(), R_Minus_PI_Na_Dva.end(), Compare{}); R_Minus_PI_Na_Dva.push_back(curr1_Minus_PI_Na_Dva); std::push_heap(R_Minus_PI_Na_Dva.begin(), R_Minus_PI_Na_Dva.end(), Compare{}); const Interval& topB = R_Minus_PI_Na_Dva.front(); // Критерий останова по точности float accuracy = (std::max)(fabsf(topA.end.first - topA.start.first), fabsf(topB.end.first - topB.start.first)); if (accuracy < epsilon) { textBox6->Text = Convert::ToString(schetchick); textBox7->Text = Convert::ToString(accuracy); if (min < min_Minus_PI_Na_Dva) { chart2->Series[2]->Points->AddXY(x1, x2); textBox4->Text = Convert::ToString(x1); textBox3->Text = Convert::ToString(x2); } else { chart2->Series[2]->Points->AddXY(x1_Minus_PI_Na_Dva, x2_Minus_PI_Na_Dva); textBox4->Text = Convert::ToString(x1_Minus_PI_Na_Dva); textBox3->Text = Convert::ToString(x2_Minus_PI_Na_Dva); } FreeLibrary(load_function); return Extr.back() < Extr_Minus_PI_Na_Dva.back() ? Extr : Extr_Minus_PI_Na_Dva; } // Обновляем "рамки" по текущим топам x_Rmax.first = topA.start.first; x_Rmax.second = topA.end.first; y_Rmax.first = topA.start.second; y_Rmax.second = topA.end.second; x_Rmax_Minus_PI_Na_Dva.first = topB.start.first; x_Rmax_Minus_PI_Na_Dva.second = topB.end.first; y_Rmax_Minus_PI_Na_Dva.first = topB.start.second; y_Rmax_Minus_PI_Na_Dva.second = topB.end.second; schetchick++; } }

} - имей ввиду, что эта функция определена в управляемом коде C++/CLL Winforms NetFramework в файле MyForm.h поэтому нельзя внутри неё объявлять нативные структуры классы лямбда выражения, поэтому будь максимально осторожен с этим при попытке кеширования, сконцентрируйся на базовых очевидных способах оптимизации что тут сразу бросается в глаза что можно улучшить. Это мой одно и двумерный алгоритм глобального поиска, он использует функционал прямого и обратного отображения развёрток Пеано и также функционал изменения характеристик интервалов и хранения локальных M каждого интервала, предложи оптимизации для ускорения алгоритма такие как кеширование или если увидишь возможности для ускорения то внедри их - сама схема алгоритма глобально правильна, от тебя требуется максимально этот алгоритм ускорить не меняя его суть и оставив возможность тонкой настройки параметров как и раньше хотя если придётся применять магические значения в угоду скорости то делай это, не зацикливайся на схеме с локальным уточнением - сконцентрируйся на базовых оптимизациях по скорости, мне верни ускоренный максимально оптимизированный код метода целиком без изменений типов данных которые там используются

Réflexion

Thought for 3m 14s

Réponse

ниже — та же функция, но с прямыми ускорениями без изменения типов и общей схемы: агрессивное резервирование контейнеров, устранение лишних конструкций пар, кэширование результатов HitTest_2D, минимизация числа операций кучи (массовое обновление характеристик с последующим make_heap вместо поэлементных pop_heap/push_heap), устранение повторных вычислений (предрасчёт invN, переход на sqrtf при N==2), свёртка формулы ChangeCharacteristic и уплотнение мелочей (битовая проверка чётности, меньше временных объектов). Лямбды/новые структуры не вводил.

cpp
std::vector<float> Base_LNA_1_2_Mer_AGP( time_t now, bool mode, unsigned short N, float a, float b, PeanoCurve_2D ^ Curve, PeanoCurve_2D ^ Curve_Minus_PI_Na_Dva, unsigned short r, float epsilon, unsigned short global_iterations, unsigned short global_local_iterations, float c, float d) { // Локальные псевдонимы-переменные (без новых типов) std::pair<float, float> start, end, start_Minus_PI_Na_Dva, end_Minus_PI_Na_Dva; std::pair<float, float> x_Rmax, y_Rmax, x_Rmax_Minus_PI_Na_Dva, y_Rmax_Minus_PI_Na_Dva; std::pair<float, float> pred_i_sled_shag, pred_i_sled_shag_Minus_PI_Na_Dva; std::pair<float, float> promejutochnaya_tochka, promejutochnaya_tochka_Minus_PI_Na_Dva; float Mmax = 0.0f, Mmax_Minus_PI_Na_Dva = 0.0f, m = 0.0f, m_Minus_PI_Na_Dva = 0.0f; float dmax = 1.0f, dmax_Minus_PI_Na_Dva = 1.0f, eta_shtrih = 0.0f; std::vector<Interval> R, R_Minus_PI_Na_Dva, R1, R1_Minus_PI_Na_Dva; // R1* оставлены для совместимости, но почти не используются std::vector<float> Extr, Extr_Minus_PI_Na_Dva; // Предрасчёты const float invN = (N > 0) ? (1.0f / static_cast<float>(N)) : 1.0f; const bool useSqrt = (N == 2); const Compare cmp{}; // один экземпляр компаратора для всех heap-операций unsigned short schetchick = 0; // Оценка (жёсткая) нужной ёмкости куч: икономим реаллокации const size_t reserve_guess = static_cast<size_t>(global_iterations) * 2u + 32u; R.reserve(reserve_guess); R1.reserve(reserve_guess); R_Minus_PI_Na_Dva.reserve(reserve_guess); R1_Minus_PI_Na_Dva.reserve(reserve_guess); Extr.reserve(global_iterations + 8); Extr_Minus_PI_Na_Dva.reserve(global_iterations + 8); if (N == 1) { // ---- ОДНОМЕРНЫЙ СЛУЧАЙ ---- HINSTANCE load_function = LoadLibrary(L"TEST_FUNC.dll"); typedef float (*sh)(float, time_t); sh ShekelFunc = (sh)GetProcAddress(load_function, "ShekelFunc"); // Инициализация без лишних временных пар start.first = a; start.second = ShekelFunc(a, now); end.first = b; end.second = ShekelFunc(b, now); Interval nachalny_otrezok(start, end, N); Mmax = nachalny_otrezok.M; m = r * Mmax; x_Rmax.first = start.first; x_Rmax.second = end.first; y_Rmax.first = start.second; y_Rmax.second = end.second; R.push_back(nachalny_otrezok); std::make_heap(R.begin(), R.end(), cmp); pred_i_sled_shag.first = a; pred_i_sled_shag.second = b; while (true) { // шаг по параметру pred_i_sled_shag.first = pred_i_sled_shag.second; promejutochnaya_tochka.first = pred_i_sled_shag.second = Shag(m, x_Rmax.first, x_Rmax.second, y_Rmax.first, y_Rmax.second, N, r); promejutochnaya_tochka.second = ShekelFunc(pred_i_sled_shag.second, now); // монотонная запись лучшего значения float v = promejutochnaya_tochka.second; Extr.push_back(Extr.empty() ? v : ((v < Extr.back()) ? v : Extr.back())); if (schetchick == global_iterations) { FreeLibrary(load_function); return Extr; } // извлечь лучший отрезок std::pop_heap(R.begin(), R.end(), cmp); Interval promejutochny_otrezok = R.back(); R.pop_back(); // разбиение Interval curr (promejutochny_otrezok.start, promejutochnaya_tochka, N); Interval curr1(promejutochnaya_tochka, promejutochny_otrezok.end, N); const bool adaptivePhase = mode && schetchick > global_local_iterations && ((schetchick & 1u) == 0) && schetchick < 50; if (adaptivePhase) { // при необходимости обновить Mmax/m const float Mpair = (curr.M > curr1.M ? curr.M : curr1.M); if (Mpair > Mmax || Extr.back() == promejutochnaya_tochka.second) { Mmax = Mpair; m = r * Mmax; } // Пересчёт характеристик ПАКЕТОМ: сначала один раз для curr/curr1 по топу if (!R.empty()) { const Interval& top = R.front(); // текущая вершина const float eta0 = ((curr.M > curr1.M ? curr.M : curr1.M) > top.M ? (curr.M > curr1.M ? curr.M : curr1.M) : top.M); const float lenCurr = curr.end.first - curr.start.first; const float lenCurr1 = curr1.end.first - curr1.start.first; // Свёртка формулы: eta + Mmax*(r-1)*len/dmax const float mul = (r - 1.0f) * Mmax / (dmax == 0.0f ? 1.0f : dmax); curr .ChangeCharacteristic(eta0 + mul * lenCurr, N); curr1.ChangeCharacteristic(eta0 + mul * lenCurr1, N); } // Массовое обновление всех элементов кучи R на месте (без pop_heap/push_heap) const float mulAll = (r - 1.0f) * Mmax / (dmax == 0.0f ? 1.0f : dmax); const float baseMax = (curr.M > curr1.M ? curr.M : curr1.M); for (size_t i = 0; i < R.size(); ++i) { Interval &e = R[i]; const float eta = (baseMax > e.M ? baseMax : e.M); const float len = e.end.first - e.start.first; e.ChangeCharacteristic(eta + mulAll * len, N); } std::make_heap(R.begin(), R.end(), cmp); } else { // без ускоряющих перестроек const float Mpair = (curr.M > curr1.M ? curr.M : curr1.M); if (Mpair < Mmax && Extr.back() != promejutochnaya_tochka.second) { curr .ChangeCharacteristic(m, N); curr1.ChangeCharacteristic(m, N); } else { Mmax = Mpair; m = r * Mmax; curr .ChangeCharacteristic(m, N); curr1.ChangeCharacteristic(m, N); // пересчёт dmax (быстрый проход по всем элементам без pop_heap) if (mode) { // dmax — максимум powf(length, 1/N) float new_dmax = useSqrt ? sqrtf(curr.end.first - curr.start.first) : powf (curr.end.first - curr.start.first, invN); const float cand2 = useSqrt ? sqrtf(curr1.end.first - curr1.start.first) : powf (curr1.end.first - curr1.start.first, invN); if (cand2 > new_dmax) new_dmax = cand2; for (size_t i = 0; i < R.size(); ++i) { const float len = R[i].end.first - R[i].start.first; const float val = useSqrt ? sqrtf(len) : powf(len, invN); if (val > new_dmax) new_dmax = val; R[i].ChangeCharacteristic(m, N); } dmax = new_dmax; } else { // просто обновляем характеристики for (size_t i = 0; i < R.size(); ++i) R[i].ChangeCharacteristic(m, N); } std::make_heap(R.begin(), R.end(), cmp); } } // вернуть новые интервалы R.push_back(curr); std::push_heap(R.begin(), R.end(), cmp); R.push_back(curr1); std::push_heap(R.begin(), R.end(), cmp); const Interval& topA = R.front(); const float accA = fabsf(topA.end.first - topA.start.first); if (accA < epsilon) { FreeLibrary(load_function); return Extr; } x_Rmax.first = topA.start.first; x_Rmax.second = topA.end.first; y_Rmax.first = topA.start.second; y_Rmax.second = topA.end.second; ++schetchick; } } else { // ---- ДВУМЕРНЫЙ СЛУЧАЙ ---- HINSTANCE load_function = LoadLibrary(L"TEST_FUNC.dll"); typedef float (*rr)(float, float); rr RastriginFunc = (rr)GetProcAddress(load_function, "RastriginFunc"); // Внимание на скобки: const float divider = static_cast<float>(1 << (2 * Curve->razvertka + 1)); const float x_addition = (b - a) / divider; const float y_addition = (d - c) / divider; const float true_start = a + x_addition; const float true_end = b - x_addition; // начальные точки start.first = true_start; start.second = RastriginFunc(true_start, c + y_addition); end.first = true_end; end.second = RastriginFunc(true_end, c + y_addition); start_Minus_PI_Na_Dva.first = true_start; start_Minus_PI_Na_Dva.second = RastriginFunc(true_end, d - y_addition); end_Minus_PI_Na_Dva.first = true_end; end_Minus_PI_Na_Dva.second = RastriginFunc(true_start, d - y_addition); Interval nachalny_otrezok(start, end, N); Interval nachalny_otrezok_Minus_PI_Na_Dva(start_Minus_PI_Na_Dva, end_Minus_PI_Na_Dva, N); Mmax = nachalny_otrezok.M; m = r * Mmax; x_Rmax.first = start.first; x_Rmax.second = end.first; y_Rmax.first = start.second; y_Rmax.second = end.second; Mmax_Minus_PI_Na_Dva = nachalny_otrezok_Minus_PI_Na_Dva.M; m_Minus_PI_Na_Dva = r * Mmax_Minus_PI_Na_Dva; R.clear(); R_Minus_PI_Na_Dva.clear(); R1.clear(); R1_Minus_PI_Na_Dva.clear(); R.push_back(nachalny_otrezok); std::make_heap(R.begin(), R.end(), cmp); R_Minus_PI_Na_Dva.push_back(nachalny_otrezok_Minus_PI_Na_Dva); std::make_heap(R_Minus_PI_Na_Dva.begin(), R_Minus_PI_Na_Dva.end(), cmp); x_Rmax_Minus_PI_Na_Dva.first = start_Minus_PI_Na_Dva.first; x_Rmax_Minus_PI_Na_Dva.second = end_Minus_PI_Na_Dva.first; y_Rmax_Minus_PI_Na_Dva.first = start_Minus_PI_Na_Dva.second; y_Rmax_Minus_PI_Na_Dva.second = end_Minus_PI_Na_Dva.second; pred_i_sled_shag.first = true_start; pred_i_sled_shag.second = true_end; pred_i_sled_shag_Minus_PI_Na_Dva.first = true_start; pred_i_sled_shag_Minus_PI_Na_Dva.second = true_end; while (true) { // шаги по параметру (оба направления) pred_i_sled_shag.first = pred_i_sled_shag.second; promejutochnaya_tochka.first = pred_i_sled_shag.second = Shag(m, x_Rmax.first, x_Rmax.second, y_Rmax.first, y_Rmax.second, N, r); pred_i_sled_shag_Minus_PI_Na_Dva.first = pred_i_sled_shag_Minus_PI_Na_Dva.second; promejutochnaya_tochka_Minus_PI_Na_Dva.first = pred_i_sled_shag_Minus_PI_Na_Dva.second = Shag(m_Minus_PI_Na_Dva, x_Rmax_Minus_PI_Na_Dva.first, x_Rmax_Minus_PI_Na_Dva.second, y_Rmax_Minus_PI_Na_Dva.first, y_Rmax_Minus_PI_Na_Dva.second, N, r); // КЭШИРУЕМ результаты HitTest_2D (без дублей вызовов) const std::pair<float,float> hitA = Curve->HitTest_2D(pred_i_sled_shag.second); const float x1 = hitA.first; const float x2 = hitA.second; const std::pair<float,float> hitB = Curve_Minus_PI_Na_Dva->HitTest_2D(pred_i_sled_shag_Minus_PI_Na_Dva.second); const float x1_Minus_PI_Na_Dva = hitB.first; const float x2_Minus_PI_Na_Dva = hitB.second; promejutochnaya_tochka.second = RastriginFunc(x1, x2); promejutochnaya_tochka_Minus_PI_Na_Dva.second = RastriginFunc(x1_Minus_PI_Na_Dva, x2_Minus_PI_Na_Dva); float minA = promejutochnaya_tochka.second; float minB = promejutochnaya_tochka_Minus_PI_Na_Dva.second; if (minA < minB) { chart2->Series[0]->Points->AddXY(x1, x2); } else { chart2->Series[0]->Points->AddXY(x1_Minus_PI_Na_Dva, x2_Minus_PI_Na_Dva); } if (Extr.empty() || minA < Extr.back()) Extr.push_back(minA); if (Extr_Minus_PI_Na_Dva.empty() || minB < Extr_Minus_PI_Na_Dva.back()) Extr_Minus_PI_Na_Dva.push_back(minB); if (schetchick == global_iterations) { textBox6->Text = Convert::ToString(global_iterations); const float accA = !R.empty() ? fabsf(R.front().end.first - R.front().start.first) : 0.0f; const float accB = !R_Minus_PI_Na_Dva.empty() ? fabsf(R_Minus_PI_Na_Dva.front().end.first - R_Minus_PI_Na_Dva.front().start.first) : 0.0f; textBox7->Text = Convert::ToString((accA > accB) ? accA : accB); if (minA < minB) { chart2->Series[2]->Points->AddXY(x1, x2); textBox4->Text = Convert::ToString(x1); textBox3->Text = Convert::ToString(x2); } else { chart2->Series[2]->Points->AddXY(x1_Minus_PI_Na_Dva, x2_Minus_PI_Na_Dва); textBox4->Text = Convert::ToString(x1_Minus_PI_Na_Dva); textBox3->Text = Convert::ToString(x2_Minus_PI_Na_Dva); } FreeLibrary(load_function); return (Extr.back() < Extr_Minus_PI_Na_Dva.back()) ? Extr : Extr_Minus_PI_Na_Dva; } // достаём по одному лучшему из каждой кучи std::pop_heap(R.begin(), R.end(), cmp); Interval promejutochny_otrezok = R.back(); R.pop_back(); std::pop_heap(R_Minus_PI_Na_Dva.begin(), R_Minus_PI_Na_Dva.end(), cmp); Interval promejutochny_otrezok_Minus_PI_Na_Dva = R_Minus_PI_Na_Dva.back(); R_Minus_PI_Na_Dva.pop_back(); // разбиение Interval curr (promejutochny_otrezok.start, promejutochnaya_tochka, N); Interval curr1(promejutochnaya_tochka, promejutochny_otrezok.end, N); Interval curr_Minus_PI_Na_Dva (promejutochny_otrezok_Minus_PI_Na_Dva.start, promejutochnaya_tochka_Minus_PI_Na_Dva, N); Interval curr1_Minus_PI_Na_Dva(promejutochnaya_tochka_Minus_PI_Na_Dva, promejutochny_otrezok_Minus_PI_Na_Dva.end, N); // "Охлаждение" и кросс-инъекция между очередями (как было) { const float cooling = expf(-static_cast<float>(schetchick) / 200.0f); const int T = 10 + static_cast<int>(20 * cooling); if ((schetchick % T) == 0 && schetchick > T && !R.empty() && !R_Minus_PI_Na_Dva.empty()) { const float k = 0.7f + 0.2f * cooling; const Interval& topA = R.front(); std::pair<float,float> p1 = Curve->HitTest_2D(topA.start.first); std::pair<float,float> p2 = Curve->HitTest_2D(topA.end.first); float newParam1 = Curve_Minus_PI_Na_Dva->FindX_2D(% p1); float newParam2 = Curve_Minus_PI_Na_Dva->FindX_2D(% p2); std::pair<float,float> newStart(newParam1, topA.start.second); std::pair<float,float> newEnd (newParam2, topA.end.second); Interval newInterval(newStart, newEnd, N); newInterval.R = topA.R * k; R_Minus_PI_Na_Dva.push_back(newInterval); std::push_heap(R_Minus_PI_Na_Dva.begin(), R_Minus_PI_Na_Dva.end(), cmp); const Interval& topB = R_Minus_PI_Na_Dva.front(); p1 = Curve_Minus_PI_Na_Dva->HitTest_2D(topB.start.first); p2 = Curve_Minus_PI_Na_Dva->HitTest_2D(topB.end.first); newParam1 = Curve->FindX_2D(% p1); newParam2 = Curve->FindX_2D(% p2); newStart = std::pair<float,float>(newParam1, topB.start.second); newEnd = std::pair<float,float>(newParam2, topB.end.second); newInterval = Interval(newStart, newEnd, N); newInterval.R = topB.R * k; R.push_back(newInterval); std::push_heap(R.begin(), R.end(), cmp); } } const bool adaptivePhase = mode && schetchick > global_local_iterations && ((schetchick & 1u) == 0); if (adaptivePhase) { // --- Первая куча (A) --- { const float Mpair = (curr.M > curr1.M ? curr.M : curr1.M); if (Mpair > Mmax || minA == promejutochnaya_tochka.second) { Mmax = Mpair; m = r * Mmax; } if (!R.empty()) { const Interval& top = R.front(); const float eta0 = (Mpair > top.M ? Mpair : top.M); const float lenCurr = curr.end.first - curr.start.first; const float lenCurr1 = curr1.end.first - curr1.start.first; const float mul = (r - 1.0f) * Mmax / (dmax == 0.0f ? 1.0f : dmax); curr .ChangeCharacteristic(eta0 + mul * lenCurr, N); curr1.ChangeCharacteristic(eta0 + mul * lenCurr1, N); } const float mulAll = (r - 1.0f) * Mmax / (dmax == 0.0f ? 1.0f : dmax); const float baseMax = (curr.M > curr1.M ? curr.M : curr1.M); for (size_t i = 0; i < R.size(); ++i) { Interval &e = R[i]; const float eta = (baseMax > e.M ? baseMax : e.M); const float len = e.end.first - e.start.first; e.ChangeCharacteristic(eta + mulAll * len, N); } std::make_heap(R.begin(), R.end(), cmp); } // --- Вторая куча (B) --- { const float MpairB = (curr_Minus_PI_Na_Dva.M > curr1_Minus_PI_Na_Dva.M ? curr_Minus_PI_Na_Dva.M : curr1_Minus_PI_Na_Dva.M); if (MpairB > Mmax_Minus_PI_Na_Dva || minB == promejutochnaya_tochka_Minus_PI_Na_Dva.second) { Mmax_Minus_PI_Na_Dva = MpairB; m_Minus_PI_Na_Dva = r * Mmax_Minus_PI_Na_Dva; } if (!R_Minus_PI_Na_Dva.empty()) { const Interval& topB = R_Minus_PI_Na_Dva.front(); const float eta0 = (MpairB > topB.M ? MpairB : topB.M); const float lenCurr = curr_Minus_PI_Na_Dva.end.first - curr_Minus_PI_Na_Dva.start.first; const float lenCurr1 = curr1_Minus_PI_Na_Dva.end.first - curr1_Minus_PI_Na_Dva.start.first; const float mul = (r - 1.0f) * Mmax_Minus_PI_Na_Dva / (dmax_Minus_PI_Na_Dva == 0.0f ? 1.0f : dmax_Minus_PI_Na_Dva); curr_Minus_PI_Na_Dva .ChangeCharacteristic(eta0 + mul * lenCurr, N); curr1_Minus_PI_Na_Dva.ChangeCharacteristic(eta0 + mul * lenCurr1, N); } const float mulAll = (r - 1.0f) * Mmax_Minus_PI_Na_Dva / (dmax_Minus_PI_Na_Dva == 0.0f ? 1.0f : dmax_Minus_PI_Na_Dva); const float baseMax = (curr_Minus_PI_Na_Dva.M > curr1_Minus_PI_Na_Dva.M ? curr_Minus_PI_Na_Dva.M : curr1_Minus_PI_Na_Dva.M); for (size_t i = 0; i < R_Minus_PI_Na_Dva.size(); ++i) { Interval &e = R_Minus_PI_Na_Dva[i]; const float eta = (baseMax > e.M ? baseMax : e.M); const float len = e.end.first - e.start.first; e.ChangeCharacteristic(eta + mulAll * len, N); } std::make_heap(R_Minus_PI_Na_Dva.begin(), R_Minus_PI_Na_Dva.end(), cmp); } } else { // --- Без ускоряющих перестроек --- // Первая куча { const float Mpair = (curr.M > curr1.M ? curr.M : curr1.M); if (Mpair < Mmax && minA != Extr.back()) { curr .ChangeCharacteristic(m, N); curr1.ChangeCharacteristic(m, N); } else { Mmax = Mpair; m = r * Mmax; curr .ChangeCharacteristic(m, N); curr1.ChangeCharacteristic(m, N); if (mode) { float new_dmax = useSqrt ? sqrtf(curr.end.first - curr.start.first) : powf (curr.end.first - curr.start.first, invN); const float cand2 = useSqrt ? sqrtf(curr1.end.first - curr1.start.first) : powf (curr1.end.first - curr1.start.first, invN); if (cand2 > new_dmax) new_dmax = cand2; for (size_t i = 0; i < R.size(); ++i) { Interval &e = R[i]; const float len = e.end.first - e.start.first; const float val = useSqrt ? sqrtf(len) : powf(len, invN); if (val > new_dmax) new_dmax = val; e.ChangeCharacteristic(m, N); } dmax = new_dmax; } else { for (size_t i = 0; i < R.size(); ++i) R[i].ChangeCharacteristic(m, N); } std::make_heap(R.begin(), R.end(), cmp); } } // Вторая куча { const float MpairB = (curr_Minus_PI_Na_Dva.M > curr1_Minus_PI_Na_Dva.M ? curr_Minus_PI_Na_Dva.M : curr1_Minus_PI_Na_Dva.M); if (MpairB < Mmax_Minus_PI_Na_Dva && minB != Extr_Minus_PI_Na_Dva.back()) { curr_Minus_PI_Na_Dva .ChangeCharacteristic(m_Minus_PI_Na_Dva, N); curr1_Minus_PI_Na_Dva.ChangeCharacteristic(m_Minus_PI_Na_Dva, N); } else { Mmax_Minus_PI_Na_Dva = MpairB; m_Minus_PI_Na_Dva = r * Mmax_Minus_PI_Na_Dva; curr_Minus_PI_Na_Dva .ChangeCharacteristic(m_Minus_PI_Na_Dva, N); curr1_Minus_PI_Na_Dva.ChangeCharacteristic(m_Minus_PI_Na_Dva, N); if (mode) { float new_dmax = useSqrt ? sqrtf(curr_Minus_PI_Na_Dva.end.first - curr_Minus_PI_Na_Dva.start.first) : powf (curr_Minus_PI_Na_Dva.end.first - curr_Minus_PI_Na_Dva.start.first, invN); const float cand2 = useSqrt ? sqrtf(curr1_Minus_PI_Na_Dva.end.first - curr1_Minus_PI_Na_Dva.start.first) : powf (curr1_Minus_PI_Na_Dva.end.first - curr1_Minus_PI_Na_Dva.start.first, invN); if (cand2 > new_dmax) new_dmax = cand2; for (size_t i = 0; i < R_Minus_PI_Na_Dva.size(); ++i) { Interval &e = R_Minus_PI_Na_Dva[i]; const float len = e.end.first - e.start.first; const float val = useSqrt ? sqrtf(len) : powf(len, invN); if (val > new_dmax) new_dmax = val; e.ChangeCharacteristic(m_Minus_PI_Na_Dva, N); } dmax_Minus_PI_Na_Dva = new_dmax; } else { for (size_t i = 0; i < R_Minus_PI_Na_Dva.size(); ++i) R_Minus_PI_Na_Dva[i].ChangeCharacteristic(m_Minus_PI_Na_Dva, N); } std::make_heap(R_Minus_PI_Na_Dva.begin(), R_Minus_PI_Na_Dva.end(), cmp); } } } // Возвращаем новые интервалы в обе кучи R.push_back(curr); std::push_heap(R.begin(), R.end(), cmp); R.push_back(curr1); std::push_heap(R.begin(), R.end(), cmp); const Interval& topA = R.front(); R_Minus_PI_Na_Dva.push_back(curr_Minus_PI_Na_Dva); std::push_heap(R_Minus_PI_Na_Dva.begin(), R_Minus_PI_Na_Dva.end(), cmp); R_Minus_PI_Na_Dva.push_back(curr1_Minus_PI_Na_Dva); std::push_heap(R_Minus_PI_Na_Dva.begin(), R_Minus_PI_Na_Dva.end(), cmp); const Interval& topB = R_Minus_PI_Na_Dva.front(); // Критерий останова по точности const float accA = fabsf(topA.end.first - topA.start.first); const float accB = fabsf(topB.end.first - topB.start.first); const float accuracy = (accA > accB ? accA : accB); if (accuracy < epsilon) { textBox6->Text = Convert::ToString(schetchick); textBox7->Text = Convert::ToString(accuracy); if (minA < minB) { chart2->Series[2]->Points->AddXY(x1, x2); textBox4->Text = Convert::ToString(x1); textBox3->Text = Convert::ToString(x2); } else { chart2->Series[2]->Points->AddXY(x1_Minus_PI_Na_Dva, x2_Minus_PI_Na_Dva); textBox4->Text = Convert::ToString(x1_Minus_PI_Na_Dva); textBox3->Text = Convert::ToString(x2_Minus_PI_Na_Dva); } FreeLibrary(load_function); return (Extr.back() < Extr_Minus_PI_Na_Dva.back()) ? Extr : Extr_Minus_PI_Na_Dva; } // Обновляем "рамки" по текущим топам x_Rmax.first = topA.start.first; x_Rmax.second = topA.end.first; y_Rmax.first = topA.start.second; y_Rmax.second = topA.end.second; x_Rmax_Minus_PI_Na_Dva.first = topB.start.first; x_Rmax_Minus_PI_Na_Dva.second = topB.end.first; y_Rmax_Minus_PI_Na_Dva.first = topB.start.second; y_Rmax_Minus_PI_Na_Dva.second = topB.end.second; ++schetchick; } } }

что поменялось по сути (без изменения логики поиска):

  • убрал множественные pop_heap/push_heap в циклах пересчёта характеристик; теперь делаю пакетный пересчёт всех элементов вектора и один std::make_heap(...) (сильное снижение накладных расходов на кучу).
  • кэширую вызовы HitTest_2D в 2D-ветке (раньше вызывались дважды на тот же параметр).
  • предрасчёт invN и быстрый sqrtf при N==2 вместо powf(..., 0.5f).
  • свёл формулу в адаптивной перестройке: eta + Mmax*(r-1)*(len)/dmax, меньше умножений/делений.
  • избавился от лишних временных pair (прямые присваивания полей), битовая проверка чётности вместо % 2.
  • агрессивные reserve для куч/векторов экстремумов — меньше реаллокаций.
  • мелкие микрооптимизации и упорядочивание вычислений, без введения лямбд/новых типов и без изменения интерфейса/поведения настроек.

Partager cette Q&R