forked from stud203836/SPLITOVIK
создание 1 верии дочерней программы курсовой работы
This commit is contained in:
parent
ab85bc6f1b
commit
39d860bb49
172
PowellProcess.cpp
Normal file
172
PowellProcess.cpp
Normal file
@ -0,0 +1,172 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
#include <windows.h>
|
||||
#include <stdexcept>
|
||||
|
||||
// Тип функции из DLL
|
||||
typedef double (*TargetFunctionType)(double*, int);
|
||||
TargetFunctionType g_TargetFunction = nullptr;
|
||||
|
||||
// Обертка для вызова целевой функции
|
||||
double CallTargetFunction(const std::vector<double>& x) {
|
||||
if (!g_TargetFunction) return 0.0;
|
||||
return g_TargetFunction(const_cast<double*>(&x[0]), static_cast<int>(x.size()));
|
||||
}
|
||||
|
||||
void add_scaled(const std::vector<double>& dir, std::vector<double>& res, double lambda) {
|
||||
for (size_t i = 0; i < dir.size(); ++i) {
|
||||
res[i] += lambda * dir[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Поиск интервала (из peyll.txt)
|
||||
void get_lambda_segment(const std::vector<double>& point, const std::vector<double>& dir, double step, double& a, double& c) {
|
||||
double left = 0, middle = 0, right = 0;
|
||||
double y_curr = CallTargetFunction(point);
|
||||
double y_next = y_curr;
|
||||
double r = (3.0 - std::sqrt(5.0)) / 2.0;
|
||||
r = (1.0 - r) / r; // ~ 1.618
|
||||
|
||||
int iterations = 0;
|
||||
do {
|
||||
y_curr = y_next;
|
||||
left = middle;
|
||||
middle = right;
|
||||
right += step;
|
||||
std::vector<double> x = point;
|
||||
add_scaled(dir, x, right);
|
||||
y_next = CallTargetFunction(x);
|
||||
step *= r;
|
||||
iterations++;
|
||||
} while (y_next < y_curr && iterations < 100);
|
||||
|
||||
a = left;
|
||||
c = right;
|
||||
}
|
||||
|
||||
// Золотое сечение (из peyll.txt)
|
||||
double gold_method(const std::vector<double>& point, const std::vector<double>& dir, double a, double c, double eps) {
|
||||
double r = (3.0 - std::sqrt(5.0)) / 2.0;
|
||||
double b = a + r * (c - a);
|
||||
std::vector<double> x_b = point;
|
||||
add_scaled(dir, x_b, b);
|
||||
double y_b = CallTargetFunction(x_b);
|
||||
|
||||
while (std::abs(c - a) > eps) {
|
||||
double d = c + r * (a - c);
|
||||
std::vector<double> x_d = point;
|
||||
add_scaled(dir, x_d, d);
|
||||
double y_d = CallTargetFunction(x_d);
|
||||
if (y_d < y_b) { a = b; b = d; y_b = y_d; }
|
||||
else { c = a; a = d; }
|
||||
}
|
||||
return (a + c) / 2.0;
|
||||
}
|
||||
|
||||
// Поиск лучшей лямбды в обоих направлениях
|
||||
double get_best_lambda(const std::vector<double>& point, const std::vector<double>& dir, double eps, double initial_step) {
|
||||
double a, c;
|
||||
// Поиск в '+'
|
||||
get_lambda_segment(point, dir, initial_step, a, c);
|
||||
double l1 = gold_method(point, dir, a, c, eps);
|
||||
// Поиск в '-'
|
||||
get_lambda_segment(point, dir, -initial_step, a, c);
|
||||
double l2 = gold_method(point, dir, a, c, eps);
|
||||
|
||||
std::vector<double> x1 = point, x2 = point;
|
||||
add_scaled(dir, x1, l1);
|
||||
add_scaled(dir, x2, l2);
|
||||
return (CallTargetFunction(x1) < CallTargetFunction(x2)) ? l1 : l2;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
// ВАЖНО: argc - 1 (exe) - 1 (dll) - 1 (eps) - 1 (iter) - 1 (step) = N
|
||||
// Значит N = argc - 5
|
||||
if (argc < 6) {
|
||||
std::cerr << "Error: Not enough arguments! Received: " << argc << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
HMODULE hLib = NULL;
|
||||
try {
|
||||
std::string dllPath = argv[1];
|
||||
int numVars = argc - 5;
|
||||
|
||||
std::vector<double> x(numVars);
|
||||
for (int i = 0; i < numVars; i++) {
|
||||
x[i] = std::stod(argv[2 + i]);
|
||||
}
|
||||
|
||||
double epsilon = std::stod(argv[argc - 3]);
|
||||
int maxIter = std::stoi(argv[argc - 2]);
|
||||
double userStep = std::stod(argv[argc - 1]); // Возвращенный параметр шага
|
||||
|
||||
std::cout << "Starting Powell Optimization..." << std::endl;
|
||||
std::cout << "DLL: " << dllPath << " | Vars: " << numVars << std::endl;
|
||||
std::cout << "Eps: " << epsilon << " | MaxIter: " << maxIter << " | Step: " << userStep << std::endl;
|
||||
std::cout << "------------------------------------------" << std::endl;
|
||||
|
||||
hLib = LoadLibraryA(dllPath.c_str());
|
||||
if (!hLib) throw std::runtime_error("Could not load DLL: " + dllPath);
|
||||
|
||||
g_TargetFunction = (TargetFunctionType)GetProcAddress(hLib, "targetFunction");
|
||||
if (!g_TargetFunction) throw std::runtime_error("Function 'targetFunction' not found in DLL.");
|
||||
|
||||
std::vector<std::vector<double>> directions(numVars, std::vector<double>(numVars, 0.0));
|
||||
for (int i = 0; i < numVars; ++i) directions[i][i] = 1.0;
|
||||
|
||||
int iterations = 0;
|
||||
bool converged = false;
|
||||
|
||||
while (iterations < maxIter) {
|
||||
double f_start = CallTargetFunction(x);
|
||||
std::vector<double> p_start = x;
|
||||
|
||||
// 1. Поиск по текущим направлениям
|
||||
for (int i = 0; i < numVars; ++i) {
|
||||
double lambda = get_best_lambda(x, directions[i], epsilon, userStep);
|
||||
add_scaled(directions[i], x, lambda);
|
||||
}
|
||||
|
||||
// 2. Новое направление (сопряженное)
|
||||
std::vector<double> new_dir(numVars);
|
||||
for (int i = 0; i < numVars; ++i) new_dir[i] = x[i] - p_start[i];
|
||||
|
||||
double lambda = get_best_lambda(x, new_dir, epsilon, userStep);
|
||||
add_scaled(new_dir, x, lambda);
|
||||
|
||||
// 3. Обновление направлений
|
||||
for (int i = 0; i < numVars - 1; ++i) directions[i] = directions[i + 1];
|
||||
directions[numVars - 1] = new_dir;
|
||||
|
||||
iterations++;
|
||||
double f_end = CallTargetFunction(x);
|
||||
double delta = std::abs(f_start - f_end);
|
||||
|
||||
std::cout << "Iteration " << iterations << ": F = " << f_end << " (delta: " << delta << ")" << std::endl;
|
||||
|
||||
if (delta < epsilon) {
|
||||
converged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "\n========================================\n";
|
||||
std::cout << "RESULT: " << (converged ? "CONVERGED" : "MAX ITERATIONS REACHED") << std::endl;
|
||||
for (int i = 0; i < numVars; i++) std::cout << "x[" << i << "] = " << x[i] << std::endl;
|
||||
std::cout << "F(min) = " << CallTargetFunction(x) << std::endl;
|
||||
std::cout << "Iterations: " << iterations << std::endl;
|
||||
std::cout << "========================================\n";
|
||||
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "RUNTIME ERROR: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
if (hLib) FreeLibrary(hLib);
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user