5

Nov 11th, 2021
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. #include <iostream>
2. #include <iomanip>
3. #include <cmath>
4. using namespace std;
5. double function(double x1, double x2, double x3); // исходная функция
6. double grad_x1(double x1, double x2, double x3);  // чп по х1
7. double grad_x2(double x1, double x2, double x3);  // чп по х2
8. double grad_x3(double x1, double x2, double x3);  // чп по х3
9. double grad(double x1, double x2, double x3);     // градиент функции
10. double StepCalculator(double x1, double x2, double x3, double p_x1, double p_x2, double p_x3);  // значение
11. //Метод Флетчера-Ривса
12. void ProgFletcherReeves(double current_x1, double current_x2, double current_x3);
13. int main()
14. {
15.     setlocale(LC_ALL, "RUSSIAN");
16.     double x1 = 1;
17.     double x2 = 2;
18.     double x3 = 3;
19.     //Метод Флетчера-Ривса
20.     ProgFletcherReeves(x1, x2, x3);
21.     system("pause");
22.     return 0;
23. }
24. double function(double x1, double x2, double x3)
25. {
26.     return 3 * pow(x1, 2) + 4 * pow(x2, 2) + 6 * pow(x3, 2) + 2 * x1 * x2 + 2 * x1 - 3 * x2 + 5 * x3;
27. }
28. double grad_x1(double x1, double x2, double x3)
29. {
30.     return 6 * x1 + 2 * x2 + 2;
31. }
32. double grad_x2(double x1, double x2, double x3)
33. {
34.     return 8 * x2 + 2 * x1 - 3;
35. }
36. double grad_x3(double x1, double x2, double x3)
37. {
38.     return 12 * x3 + 5;
39. }
40.
41. double grad(double x1, double x2, double x3)
42. {
43.     double gr_x1 = grad_x1(x1, x2, x3);
44.     double gr_x2 = grad_x2(x1, x2, x3);
45.     double gr_x3 = grad_x3(x1, x2, x3);
46.
47.     return sqrt(pow(gr_x1, 2) + pow(gr_x2, 2) + pow(gr_x3, 2));
48. }
49.
50. double StepCalculator(double x1, double x2, double x3, double p_x1, double p_x2, double p_x3)
51. {
52.     double step = 0;
53.     double numerator = 0;
54.     double denominator = 0;
55.     //подсчет выражения для определения шага
56.     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;
57.     denominator = -6 * pow(p_x1, 2) - 8 * pow(p_x2, 2) - 12 * pow(p_x3, 2) - 4 * p_x1 * p_x2;
58.     step = numerator / denominator;
59.     return step;
60. }
61.
62. //Метод Флетчера-Ривса
63. void ProgFletcherReeves(double current_x1, double current_x2, double current_x3)
64. {
65.     //начальная установка
66.     double next_x1 = current_x1;
67.     double next_x2 = current_x2;
68.     double next_x3 = current_x3;
69.     double step = 0; //шаг
70.     int iterations = 0; //количество итераций
71.     double eps = 0.001; //точность
72.     //элементы вектора P
73.     double p_x1 = -grad_x1(current_x1, current_x2, current_x3);
74.     double p_x2 = -grad_x2(current_x1, current_x2, current_x3);
75.     double p_x3 = -grad_x3(current_x1, current_x2, current_x3);
76.     double p_next_x1 = 0;
77.     double p_next_x2 = 0;
78.     double p_next_x3 = 0;
79.     cout << " >> Алгоритм Флетчера-Ривса:\n";
80.     cout << setw(11) << left << " Итерация" << setw(12) << left << "x1 " << setw(12) << left << "x2 " << setw(12) << left << "x3 "
81.         << setw(18) << left << "||grad f(x1^k)|| " << setw(12) << left << " f(x1^k)\n" << endl;
82.     while (grad(next_x1, next_x2, next_x3) > eps)
83.     {
84.         //подсчет до первой итерации
85.         if (iterations == 0)
86.         {
87.             p_x1 = -grad_x1(current_x1, current_x2, current_x3);
88.             p_x2 = -grad_x2(current_x1, current_x2, current_x3);
89.             p_x3 = -grad_x3(current_x1, current_x2, current_x3);
90.             step = StepCalculator(current_x1, current_x2, current_x3, p_x1, p_x2, p_x3);
91.             next_x1 = current_x1 + step * p_x1;
92.             next_x2 = current_x2 + step * p_x2;
93.             next_x3 = current_x3 + step * p_x3;
94.         }
95.         //получение значения вектора P в текущей итерации
96.         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;
97.         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;
98.         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;
99.         //подсчет шага в текущей итерации
100.         step = StepCalculator(next_x1, next_x2, next_x3, p_next_x1, p_next_x2, p_next_x3);
101.         //сохранение значений переменых для следующей итерации
102.         current_x1 = next_x1;
103.         current_x2 = next_x2;
104.         current_x3 = next_x3;
105.         p_x1 = p_next_x1;
106.         p_x2 = p_next_x2;
107.         p_x3 = p_next_x3;
108.         //высчитывание следующих значений переменных
109.         next_x1 = current_x1 + step * p_next_x1;
110.         next_x2 = current_x2 + step * p_next_x2;
111.         next_x3 = current_x3 + step * p_next_x3;
112.         ++iterations;
113.         cout << " " << setw(10) << left << iterations << setw(12) << left << next_x1 << setw(12) << left << next_x2 << setw(12) << left << next_x3
114.             << setw(16) << left << grad(next_x1, next_x2, next_x3) << setw(12) << left << function(next_x1, next_x2, next_x3) << endl;
115.     }
116.     cout << "\n Полученная точка минимума: (" << next_x1 << ", " << next_x2 << ", " << next_x3 << ")" << endl;
117.     cout << " Количество итераций = " << iterations << endl;
118. }
119.