MAXimal | |
добавлено: 11 Jun 2008 11:14 Содержание [скрыть] Метод Ньютона (касательных) для поиска корнейЭто итерационный метод, изобретённый Исааком Ньютоном (Isaak Newton) около 1664 г. Впрочем, иногда этот метод называют методом Ньютона-Рафсона (Raphson), поскольку Рафсон изобрёл тот же самый алгоритм на несколько лет позже Ньютона, однако его статья была опубликована намного раньше. Задача заключается в следующем. Дано уравнение: Требуется решить это уравнение, точнее, найти один из его корней (предполагается, что корень существует). Предполагается, что АлгоритмВходным параметром алгоритма, кроме функции Пусть уже вычислено Нетрудно получить следующую формулу: Интуитивно ясно, что если функция Скорость сходимости является квадратичной, что, условно говоря, означает, что число точных разрядов в приближенном значении Применение для вычисления квадратного корняРассмотрим метод Ньютона на примере вычисления квадратного корня. Если подставить Первый типичный вариант задачи — когда дано дробное число double n; cin >> n; const double EPS = 1E-15; double x = 1; for (;;) { double nx = (x + n / x) / 2; if (abs (x - nx) < EPS) break; x = nx; } printf ("%.15lf", x); Другой распространённый вариант задачи — когда требуется посчитать целочисленный корень (для данного int n; cin >> n; int x = 1; bool decreased = false; for (;;) { int nx = (x + n / x) >> 1; if (x == nx || nx > x && decreased) break; decreased = nx < x; x = nx; } cout << x; Наконец, приведём ещё третий вариант — для случая длинной арифметики. Поскольку число BigInteger n; // входные данные BigInteger a = BigInteger.ONE.shiftLeft (n.bitLength() / 2); boolean p_dec = false; for (;;) { BigInteger b = n.divide(a).add(a).shiftRight(1); if (a.compareTo(b) == 0 || a.compareTo(b) < 0 && p_dec) break; p_dec = a.compareTo(b) > 0; a = b; } Например, этот вариант кода выполняется для числа
|