Advertisement
baadgeorge

5

Nov 11th, 2021
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.10 KB | None | 0 0
  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.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement