#include #include #include using namespace std; double function(double x1, double x2, double x3); // исходная функция double grad_x1(double x1, double x2, double x3); // чп по х1 double grad_x2(double x1, double x2, double x3); // чп по х2 double grad_x3(double x1, double x2, double x3); // чп по х3 double grad(double x1, double x2, double x3); // градиент функции double StepCalculator(double x1, double x2, double x3, double p_x1, double p_x2, double p_x3); //Метод покоординатного спуска void CoordinateDescent(double current_x1, double current_x2, double current_x3); int main() { setlocale(LC_ALL, "RUSSIAN"); double x1 = 1; double x2 = 2; double x3 = 3; //Метод покоординатного спуска CoordinateDescent(x1, x2, x3); system("pause"); return 0; } double function(double x1, double x2, double x3) { return 3 * pow(x1, 2) + 4 * pow(x2, 2) + 6 * pow(x3, 2) + 2 * x1 * x2 + 2 * x1 - 3 * x2 + 5 * x3; } double grad_x1(double x1, double x2, double x3) { return 6 * x1 + 2 * x2 + 2; } double grad_x2(double x1, double x2, double x3) { return 8 * x2 + 2 * x1 - 3; } double grad_x3(double x1, double x2, double x3) { return 12 * x3 + 5; } double grad(double x1, double x2, double x3) { double gr_x1 = grad_x1(x1, x2, x3); double gr_x2 = grad_x2(x1, x2, x3); double gr_x3 = grad_x3(x1, x2, x3); return sqrt(pow(gr_x1, 2) + pow(gr_x2, 2) + pow(gr_x3, 2)); } //Подсчет значения шага double StepCalculator(double x1, double x2, double x3, double p_x1, double p_x2, double p_x3) { double step = 0; double numerator = 0; double denominator = 0; //подсчет выражения для определения шага numerator = 6 * x1 * p_x1 + 8 * x2 * p_x2 + 12 * x3 * p_x3 + 2 * x1 * p_x2 + 2 * x2 * p_x1 + 2 * p_x1 - 3 * p_x2 + 5 * p_x3; denominator = 6 * pow(p_x1, 2) + 8 * pow(p_x2, 2) + 12 * pow(p_x3, 2) + 4 * p_x1 * p_x2; step = -numerator / denominator; return step; } //Метод покоординатного спуска void CoordinateDescent(double current_x1, double current_x2, double current_x3) { //начальная установкаcurrent double next_x1 = current_x1; double next_x2 = current_x2; double next_x3 = current_x3; double step = 0; //шаг int iterations = 0; //количество итераций double eps = 0.0001; //точность //элементы вектора P double p_x1 = 0; double p_x2 = 0; double p_x3 = 0; cout << " >> Покоординатный спуск:\n"; cout << setw(11) << left << " Итерация" << setw(12) << left << "x1 " << setw(12) << left << "x2 " << setw(12) << left << "x3 " << setw(18) << left << "||grad f(x1^k)|| " << setw(12) << left << " f(x1^k)\n" << endl; while (grad(next_x1, next_x2, next_x3) > eps) { //определение переменных текущей итерации current_x1 = next_x1; current_x2 = next_x2; current_x3 = next_x3; //подсчет значений элементов вектора P p_x1 = -grad_x1(current_x1, current_x2, current_x3); p_x2 = -grad_x2(current_x1, current_x2, current_x3); p_x3 = -grad_x3(current_x1, current_x2, current_x3); step = StepCalculator(current_x1, current_x2, current_x3, p_x1, p_x2, p_x3); // получение значения шага для x1 next_x1 = current_x1 + step * p_x1; //расчет следующего значения переменной х //подсчет значений элементов вектора L p_x1 = -grad_x1(next_x1, current_x2, current_x3); p_x2 = -grad_x2(next_x1, current_x2, current_x3); p_x3 = -grad_x3(next_x1, current_x2, current_x3); step = StepCalculator(next_x1, current_x2, current_x3, p_x1, p_x2, p_x3); next_x2 = current_x2 + step * p_x2; p_x1 = -grad_x1(next_x1, next_x2, current_x3); p_x2 = -grad_x2(next_x1, next_x2, current_x3); p_x3 = -grad_x3(next_x1, next_x2, current_x3); step = StepCalculator(next_x1, next_x2, current_x3, p_x1, p_x2, p_x3); next_x3 = current_x3 + step * p_x3; iterations++; cout << " " << setw(10) << left << iterations << setw(12) << left << next_x1 << setw(12) << left << next_x2 << setw(12) << left << next_x3 << setw(16) << left << grad(next_x1, next_x2, next_x3) << setw(12) << left << function(next_x1, next_x2, next_x3) << endl; } cout << "\nПолученная точка минимума: (" << next_x1 << ", " << next_x2 << ", " << next_x3 << ")" << endl; cout << "Количество итераций: " << iterations << endl; }