ПРОГРАММИРОВАНИЕ ИТЕРАЦИОННЫХ ЦИКЛОВ Итерационным (от латинского iteratio – повторение) называют цикл, характеризующийся последовательным приближением вычисляемой величины (величин) к искомому результату. Подобные вычисления можно реализовать двумя способами: 1) С помощью цикла с заранее неизвестным числом повторений (т. е. цикла с предусловием или с постусловием). В этом случае цикл заканчивается при достижении заданной точности, когда абсолютная величина разности вычисленного и точного значения искомой величины становится меньше требуемой точности. 2) С помощью цикла с известным числом повторений (т.е. цикла с параметром). В этом случае ставится ограничение на максимальное число повторений цикла, и цикл заканчивается, как только произойдет одно из двух: либо будет достигнута заданная точность, либо будет исчерпано максимальное число повторений цикла. В разделе “Цикл с параметром” мы будем программировать итерационные циклы вторым способом. ЗАДАЧИ, ПРИВОДЯЩИЕ К ИТЕРАЦИОННЫМ ЦИКЛАМ К итерационным циклам приводят задачи: 1) 2) 3) Вычисления сумм и произведений бесконечных рядов; Реализации численных методов решения уравнений и их систем; Задачи нахождения максимумов и минимумов функций и некоторые другие задачи. Наиболее простым видом задач, реализуемых с помощью итерационных циклов, являются задачи вычисления сумм и произведений бесконечных рядов. Эти задачи мы и будем рассматривать на примерах. ПРИМЕР Составить программу вычисления суммы ряда sin 3x sin 5 x sin (2 i 1) x S sin x ... 3 5 2 i 1 i 1 с точностью до члена ряда, меньшего ε, для заданного значения x. Метод решения задачи Для реализации решения этой задачи с помощью цикла с параметром следует ограничить максимальное количество итераций, т. е. максимальное количество повторений цикла. В качестве числа, ограничивающего этот максимум, следует взять такой номер N, при котором, как предполагается, гарантировано неравенство f (N ) Начальное значение параметра цикла будет равно единице, а конечное – N. При выполнении этого цикла возможны три случая: Три случая завершения цикла 1. Параметр цикла еще не достиг значения N, а абсолютная величина очередного члена ряда стала меньше, чем ε. В этом случае точность уже достигнута, и цикл следует прервать досрочно. Это можно сделать оператором BREAK. 2. Параметр цикла достиг значения N, и абсолютная величина N-го члена ряда меньше ε (абсолютная величина (N - 1)-го члена при этом больше либо равна ε. В этом случае точность достигается именно при завершении цикла «вовремя». 3. Параметр цикла достиг значения N, но абсолютная величина N-го члена ряда больше либо равна ε. В этом случае при завершении цикла «вовремя» требуемая точность еще не достигнута. Это, в свою очередь, означает одно из трех: Особые случаи завершения цикла 1) Число N выбрано недостаточно большим. Можно попробовать увеличить N. Если это помогает, проблема решена. 2) Допущена ошибка в формуле, используемой для вычисления члена ряда. Необходимо исправить эту ошибку и заново откомпилировать программу. 3) Ряд расходится, т. е. члены ряда никогда не станут по модулю меньше ε. В этом случае задача неразрешима. В рассмотренном выше примере в качестве N возьмем число 100, т. е. будем суммировать не более 100 членов ряда. ПРОГРАММА РЕШЕНИЯ ЗАДАЧИ PROGRAM RjadSinusov; CONST N : integer = 100; VAR S, x, z, eps : real; i, k : integer; BEGIN readln (x, eps); S := 0; FOR i := 1 TO N DO BEGIN k := 2 * i - 1; z := sin (k * x) / k; S := S + z; IF (abs (z) < eps) THEN Break; END; writeln ('S = ', S, ', z = ', z, ', i = ', i); END. вопрос ВОПРОС Какие переменные служат входными и выходными данными в этой программе? ЗАПУСК И ТЕСТИРОВАНИЕ ПРОГРАММЫ Запустим программу на выполнение. В качестве x введем единицу 3 (вещественную!), в качестве ε - 1E-3 (т. е. 10 ). Получим результаты: S = 7.8214648250E-01, z = -8.6001686648E-04, i = 57. Мы видим, что просуммировано 57 членов, причем значение последнего члена 4 приблизительно равно -8 • 10 , т. е. по модулю немногим 3 меньше, чем 10 . Из полученных результатов можно сделать вывод, что требуемая точность достигнута. 5 Выполним теперь программу еще раз при x = 1 и ε = 10 . Результаты при таких начальных данных будут: S = 7.8395912895E-01, z = -4.4311499301E-03, i = 100. На этот раз просуммировано 100 членов, но требуемая точность еще не достигнута. Попробуем увеличить максимальное число членов. Меняем в тексте программы N на 200, компилируем программу и запускаем ее на выполнение. На этот раз результаты следующие: S = 7.8630245665E-01, z = -8.4914155554E-08, i = 178. Итак, в данном случае 100 членов было недостаточно для достижения точности, но 200 членов хватило. Из сказанного можно сделать вывод: Чем выше требуемая точность, тем больше членов необходимо просуммировать. ВОПРОС НА ЗАСЫПКУ Почему итерационный процесс суммирования бесконечного ряда удобнее реализовать именно с помощью цикла с параметром, несмотря на то, что количество суммируемых членов ряда заранее неизвестно? ОТВЕТ ОТВЕТ В цикле с параметром количество повторений не только известно заранее, но и конечно, поэтому зацикливание невозможно. Результат (точный или неточный) всегда будет получен за конечное время. Если же использовать цикл с предусловием или постусловием (используя в качестве критерия окончания цикла достижение заданной точности), то в случае расходимости ряда или ошибки в формуле вычисления членов ряда произойдет зацикливание, т. е. цикл будет выполняться бесконечно, и мы никогда не получим результат. Поэтому итерационные процессы следует реализовать именно с помощью цикла с параметром. ПРАКТИЧЕСКАЯ РАБОТА составить программу вычисления числа π с заданной точностью ε по формуле 4 1 4 96 k 1 ( 2k 1) (суммировать до 1000 членов ряда) и протестировать 2 10 эту20программу для значений ε, равных 10 , 10 и 10 . ПРОГРАММА Программа имеет вид: PROGRAM Iter; CONST N : integer = 1000; VAR pi, eps, S, z : real; k : integer; BEGIN readln (eps); S := 0; FOR k := 0 TO N DO РЕЗУЛЬТАТЫ ВЫЧИСЛЕНИЙ BEGIN z := 1. / sqr (sqr (2. * k + 1)); S := S + z; IF (abs (z) < eps) THEN Break; END; pi := sqrt (sqrt (96. * S)); writeln ('pi = ', pi, ', z = ', z, ', k = ', k); END. РЕЗУЛЬТАТЫ ВЫЧИСЛЕНИЙ 3 2 При ε = 10 : π = 3,1410256322, z = 1,6 • 10 , k = 2; 11 10 При ε = 10 : π = 3,1415926496, z = 9,9029127142 • 10 , k = 158; 14 При ε = 10 20: π = 3,1415926535, z = 6,2375156094 • 10 , k = 1000 В последнем случае 1000 членов недостаточно для достижения точности, и число N необходимо увеличить до 50000 (изменив при этом тип константы N и переменной k на LongInt, а тип переменной pi на Double, поскольку N в данном случае превышает 32767, а число π вычисляется с 20-ю знаками после запятой). После внесения изменений в программу получаем: 21 π = 3,14159265350132, z = 9,99960001000003 • 10 , k = 50000. Т. о., точность ε = 10 20 достигается ровно на 50000-й итерации. . КОНТРОЛЬНЫЕ ВОПРОСЫ 1) Какой цикл называется итерационным? 2) Какие задачи решаются с помощью итерационных циклов? 3) Какими способами можно реализовать итерационный процесс? 4) Какой способ предпочтительнее и почему? 5) Каким образом проверяется критерий достижения заданной точности? 6) Как следует поступать в случаях, когда максимальное количество итераций исчерпано, но требуемая точность не достигнута? ДОМАШНЕЕ ЗАДАНИЕ Составить программу вычисления бесконечного произведения P= Аргумент x и точность ε вводятся с клавиатуры. Протестировать программу при различных значениях аргумента и точности, а именно: 1) При x = 0.05 и ε = 10 ;3 2) При x = 0.5 и ε = 10 ;4 3) При х = 1.57 и ε =10 5