Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <iomanip>
- #include <cmath>
- 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 ProgFletcherReeves(double current_x1, double current_x2, double current_x3);
- int main()
- {
- setlocale(LC_ALL, "RUSSIAN");
- double x1 = 1;
- double x2 = 2;
- double x3 = 3;
- //Метод Флетчера-Ривса
- ProgFletcherReeves(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 ProgFletcherReeves(double current_x1, double current_x2, double current_x3)
- {
- //начальная установка
- double next_x1 = current_x1;
- double next_x2 = current_x2;
- double next_x3 = current_x3;
- double step = 0; //шаг
- int iterations = 0; //количество итераций
- double eps = 0.001; //точность
- //элементы вектора P
- double p_x1 = -grad_x1(current_x1, current_x2, current_x3);
- double p_x2 = -grad_x2(current_x1, current_x2, current_x3);
- double p_x3 = -grad_x3(current_x1, current_x2, current_x3);
- double p_next_x1 = 0;
- double p_next_x2 = 0;
- double p_next_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)
- {
- //подсчет до первой итерации
- if (iterations == 0)
- {
- 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);
- next_x1 = current_x1 + step * p_x1;
- next_x2 = current_x2 + step * p_x2;
- next_x3 = current_x3 + step * p_x3;
- }
- //получение значения вектора P в текущей итерации
- p_next_x1 = -grad_x1(next_x1, next_x2, next_x3) + (pow(grad(next_x1, next_x2, next_x3), 2) / pow(grad(current_x1, current_x2, current_x3), 2)) * p_x1;
- p_next_x2 = -grad_x2(next_x1, next_x2, next_x3) + (pow(grad(next_x1, next_x2, next_x3), 2) / pow(grad(current_x1, current_x2, current_x3), 2)) * p_x2;
- p_next_x3 = -grad_x3(next_x1, next_x2, next_x3) + (pow(grad(next_x1, next_x2, next_x3), 2) / pow(grad(current_x1, current_x2, current_x3), 2)) * p_x3;
- //подсчет шага в текущей итерации
- step = StepCalculator(next_x1, next_x2, next_x3, p_next_x1, p_next_x2, p_next_x3);
- //сохранение значений переменых для следующей итерации
- current_x1 = next_x1;
- current_x2 = next_x2;
- current_x3 = next_x3;
- p_x1 = p_next_x1;
- p_x2 = p_next_x2;
- p_x3 = p_next_x3;
- //высчитывание следующих значений переменных
- next_x1 = current_x1 + step * p_next_x1;
- next_x2 = current_x2 + step * p_next_x2;
- next_x3 = current_x3 + step * p_next_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;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement