Advertisement
mamamaria

Untitled

Apr 19th, 2022 (edited)
603
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.85 KB | None | 0 0
  1. // OM_1.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
  2. //
  3.  
  4. #include <iostream>
  5. using namespace std;
  6.  
  7. //double k = 1, N = 0;
  8. const int M = 50;
  9. int k = 0;
  10. using gradient = pair <double, double>;
  11. using dot = pair <double, double>;
  12. using vec = pair <double, double>;
  13. using matrix = pair <dot, dot>;
  14. double F(dot x) {
  15.     return x.first * x.first + 8 * x.second * x.second + x.first * x.second + x.first;
  16. }
  17. gradient Gradient(dot x) {
  18.     return make_pair(2 * x.first + x.second + 1, 16 * x.second + x.first);
  19. }
  20. matrix Hessian() {
  21.     return  make_pair(make_pair(2, 1), make_pair(1, 16));
  22. }
  23. matrix InverseHessian() {
  24.     return  make_pair(make_pair(16.0 / 31, -1.0 / 31), make_pair(-1.0 / 31, 2.0 / 31));
  25. }
  26. double Norm(dot x) {
  27.     return sqrt(x.first * x.first + x.second * x.second);
  28. }
  29. vec Multiply(matrix m, vec v) {
  30.     return make_pair(m.first.first * v.first + m.first.second * v.second, m.second.first* v.first + m.second.second * v.second);
  31. }
  32. double Checkpositive(matrix m) {
  33.  
  34.     double d1 = m.first.first;
  35.     double d2 = m.first.first * m.second.second - m.first.second * m.second.second;
  36.     return d1 > 0 && d2 > 0;
  37. }
  38. //}
  39. double φ(double t, const dot x, gradient grad) {
  40.     double first = t * grad.first;
  41.     double second = t * grad.second;
  42.     first = x.first - first;
  43.     second = x.second - second;
  44.     return F(make_pair(first, second));
  45. }
  46. //a = 0, b = 5, ε = 0.01, l = 0.1
  47. //a=0 потому что шаги назад делать не надо
  48. double Dichotomy(double a, double b, double eps, double l, const dot x, gradient grad) {
  49.     double yk, zk, φyk, φzk; int counter=0;
  50.     while (true) {
  51.         yk = (a + b - eps) / 2;
  52.         φyk = φ(yk,x,grad);
  53.         zk = (a + b + eps) / 2;
  54.         φzk = φ(zk,x, grad);
  55.         if (φyk <= φzk)b = zk;
  56.         else a = yk;
  57.         double dif = abs(a - b);
  58.         if (dif <= l) return (a + b) / 2;
  59.         else  counter++;
  60.     }
  61. }
  62. //
  63. //
  64. //dot GradientDescent(dot x, double eps1, double eps2) {
  65. //    int k = 0; bool flag = false;
  66. //    
  67. //    while (true) {
  68. //        gradient grad = Gradient(x);
  69. //        if (Norm(grad) < eps1)
  70. //            return x;
  71. //        if (k >= M)
  72. //            return x;
  73. //        double t = Dichotomy(0, 5, 0.01, 0.1, x, grad);
  74. //        
  75. //        dot oldx = x;
  76. //
  77. //        double first = t * grad.first;
  78. //        double second = t * grad.second;
  79. //        first = x.first - first;
  80. //        second = x.second - second;
  81. //        x.first = first; x.second = second;
  82. //
  83. //        if (Norm(make_pair(x.first - oldx.first, x.second - oldx.second)) < eps2 && abs(f(x) - f(oldx)) < eps2) {
  84. //
  85. //            if (flag == true)
  86. //                return x;
  87. //            flag = true;
  88. //
  89. //        }
  90. //        else {
  91. //            k++;
  92. //            flag = false;
  93. //        }
  94. //    }
  95. //}
  96.    
  97. dot Newton(dot x0, double eps1, double eps2) {
  98.    
  99.     dot x = x0;
  100.     double t; dot newx;
  101.     double oldF = F(x);
  102.     bool flag = false;
  103.     while (true) {
  104.         gradient grad = Gradient(x);
  105.         if (Norm(grad) < eps1 || k >= M)
  106.             return x;
  107.         matrix ihessian = InverseHessian();
  108.         vec d = make_pair(-grad.first, -grad.second);
  109.         if (Checkpositive(ihessian)) {
  110.             d = Multiply(ihessian, d);
  111.             //newx = make_pair(x.first + d.first, x.second + d.second);
  112.         }
  113.         t = Dichotomy(0, 5, 0.01, 0.1, x, grad);
  114.         newx.first = t * d.first; newx.second = t * d.second;
  115.         newx.first += x.first; newx.second += x.second;
  116.         double newF = F(x);
  117.         /*double newF = F(x);
  118.         if (t * Norm(d) < eps2 && abs(oldF - newF) < eps2) {
  119.             if (flag) return x;
  120.             else flag = true;
  121.         }
  122.         else flag = false;
  123.         oldF = newF;
  124.         k += 1;*/
  125.  
  126.         if (Norm(make_pair(newx.first - x.first, newx.second - x.second)) < eps2 && abs(F(newx) - F(x)) < eps2) {
  127.            
  128.            
  129.             if (flag)
  130.                 return x;
  131.             flag = true;
  132.            
  133.             }
  134.             else {
  135.                 k++;
  136.                 flag = false;
  137.             }
  138.         x = newx;
  139.         oldF = newF;
  140.     }
  141. }
  142.  
  143. int main()
  144. {
  145.     //dot x = GradientDescent(make_pair(1.5, 0.5), 0.1, 0.15);
  146.     //cout << x.first << "\t" << x.second;
  147.     dot x = Newton(make_pair(1.5, 0.5), 0.1, 0.15);
  148.     cout << x.first << "\t" << x.second << endl;
  149.     cout << k;
  150. }
  151.  
  152. // Запуск программы: CTRL+F5 или меню "Отладка" > "Запуск без отладки"
  153. // Отладка программы: F5 или меню "Отладка" > "Запустить отладку"
  154.  
  155. // Советы по началу работы
  156. //   1. В окне обозревателя решений можно добавлять файлы и управлять ими.
  157. //   2. В окне Team Explorer можно подключиться к системе управления версиями.
  158. //   3. В окне "Выходные данные" можно просматривать выходные данные сборки и другие сообщения.
  159. //   4. В окне "Список ошибок" можно просматривать ошибки.
  160. //   5. Последовательно выберите пункты меню "Проект" > "Добавить новый элемент", чтобы создать файлы кода, или "Проект" > "Добавить существующий элемент", чтобы добавить в проект существующие файлы кода.
  161. //   6. Чтобы снова открыть этот проект позже, выберите пункты меню "Файл" > "Открыть" > "Проект" и выберите SLN-файл.
  162.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement