====== Урок 3. Программирование итерационных циклов ======
[[http://wiki.likt590.ru/doku.php/metodika_prepodavanija_informatiki._06.12.2008_-_27.04.2009:fedorov_konstantin_pavlovich_gou_97_vyborgskij_rajon|на главную]]\\
===== Цель урока: =====
* //**Предметная:**// Сформировать представление учащихся об итерационных циклах, задачах, реализуемых с помощью итерационных циклах, оформлении итерационного цикла с помощью цикла с параметром, средствах избежания зацикливания.
* //**Общеобразовательная:**// Развивать умение осваивать новый материал, умение логически мыслить, применять полученные знания на практике.
===== Ход урока: =====
==== 1.Организационный момент. (4 мин) ====
* Приветствие класса\\
* Проверка домашнего задания\\
* Объявление нового раздела и темы урока
==== 2. Изучение нового материала: рассмотрение принципов организации итерационных циклов и итерационных процессов (8 мин) ====
Учащиеся читают теорию (текст спроецирован на экран или интерактивную доску либо находится в {{:metodika_prepodavanija_informatiki._06.12.2008_-_27.04.2009:cursovic333.ppt|файле}}, имеющемся на каждом компьютере):\\
**[[http://www.finam.ru/dictionary/wordf015C1/default.asp?n=20|Итерационным]]** (от латинского **//iteratio//** – повторение) называют цикл, характеризующийся последовательным приближением вычисляемой величины (величин) к искомому результату.\\
Подобные вычисления можно реализовать //двумя способами://\\
1. **С помощью цикла с заранее неизвестным числом повторений** (т. е. цикла с **предусловием** или
с **постусловием**). В этом случае **цикл заканчивается при достижении заданной точности**, когда абсолютная величина разности вычисленного и точного значения искомой величины становится меньше требуемой точности.\\
2. **С помощью цикла с известным числом повторений** (т.е. цикла **с параметром**). В этом случае ставится **ограничение на максимальное число повторений цикла**, и **цикл заканчивается, как только произойдет одно из двух: либо будет достигнута заданная точность, либо будет исчерпано максимальное число повторений цикла.**\\
**В разделе “Цикл с параметром”** мы будем программировать итерационные циклы **вторым способом**.\\
**К итерационным циклам приводят задачи:**\\
1. Вычисления **сумм и произведений бесконечных рядов**;\\
2. Реализации **численных методов решения уравнений и их систем**;\\
3. Задачи **нахождения максимумов и минимумов функций**\\
и некоторые другие задачи.
**Наиболее простым видом задач**, реализуемых с помощью итерационных циклов, являются задачи **вычисления сумм и произведений бесконечных рядов**. Эти задачи мы и будем рассматривать на примерах.
==== 3. Рассмотрение конкретных примеров (15 мин). ====
Пример. Составить программу вычисления суммы ряда\\
{{:metodika_prepodavanija_informatiki._06.12.2008_-_27.04.2009:formula_6.doc|формула}}\\
с точностью до члена ряда, по модулю меньшего //ε//, для заданного значения x.\\
Для **реализации решения этой задачи с помощью цикла с параметром** следует **ограничить максимальное количество итераций**, т. е. максимальное количество повторений цикла. В качестве **числа, ограничивающего этот максимум**, следует взять такой номер **//N//**, при котором, как предполагается, **гарантировано неравенство** {{:metodika_prepodavanija_informatiki._06.12.2008_-_27.04.2009:formula_7.doc|формула}}. **Начальное значение** параметра цикла будет равно **единице**, а **конечное** - //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//, **точность** //ε//) и **выходными** (**вычисленная сумма** //S//, **последний член ряда** //z//, **количество членов ** //i//) **данными** в этой программе?\\
**Запустим программу на выполнение**. В качестве //x// введем **единицу (//вещественную!//)**, в качестве //ε// - **1E-3** (т. е. 10-3).\\
Получим **результаты**: //S// = 7.8214648250E-01, //z// = -8.6001686648E-04, //i// = 57.\\
Мы видим, что **просуммировано** //57// членов, причем **значение последнего члена** приблизительно равно -8 • 10-4, т. е. **по модулю немногим меньше**, чем 10-3. **Из полученных результатов** можно сделать вывод, что **требуемая точность достигнута**.\\
Выполним теперь программу еще раз при //x// = //1// и //ε// = 10-5.\\
**Результаты при таких начальных данных** будут:\\
//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. Практическая работа: Составление программы вычисления суммы бесконечного ряда (12 мин) ====
Учащиеся **самостоятельно** составляют программу вычисления суммы бесконечного ряда{{:metodika_prepodavanija_informatiki._06.12.2008_-_27.04.2009:formula_8.doc|формула}} с заданной точностью //ε// (суммировать до 1000 членов ряда) и протестировать эту программу для значений //ε//, равных 10-2, 10-10 и 10-20.
**Программа имеет вид:**\\
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.\\
**Результаты вычислений:**\\
При //ε// = 10-2: //π// = 3,1410256322, //z// = 1,6 • 10-3, //k// = 2;\\
При //ε// = 10-10: //π// = 3,1415926496, //z// = 9,9029127142 • 10-11, //k// = 158;\\
При //ε// = 10-20: //π// = 3,1415926535, //z// = 6,2375156094 • 10-14, //k// = 1000.\\
В последнем случае 1000 членов недостаточно для достижения точности, и число //N// необходимо увеличить до 50000 (изменив при этом тип константы //N// и переменной //k// на LongInt, а тип переменной //pi// на Double, поскольку
//N// в данном случае превышает 32767, а число //π// вычисляется с 20-ю знаками после запятой).\\
**После внесения изменений в программу получаем:**\\
//π// = 3,14159265350132, //z// = 9,99960001000003 • 10-21, //k// = 50000.\\
Т. о., **точность //ε// = 10-20 достигается ровно на //50000-й// итерации**.
==== 5. Подведение итогов урока. Закрепление пройденного на уроке. (4 мин) ====
**Учащимся предлагается ответить на контрольные вопросы:**\\
1) Какой цикл называется итерационным?\\
2) Какие задачи решаются с помощью итерационных циклов?\\
3) Какими способами можно реализовать итерационный процесс?\\
4) Какой способ предпочтительнее и почему?\\
5) Каким образом проверяется критерий достижения заданной точности?\\
6) Как следует поступать в случаях, когда максимальное количество итераций исчерпано, но требуемая точность не достигнута?\\
==== 6. Домашнее задание. (2 мин) ====
Составить программу вычисления бесконечного произведения //P// = {{:metodika_prepodavanija_informatiki._06.12.2008_-_27.04.2009:formula_10.doc|формула}} . Аргумент //x// и точность //ε// вводятся с клавиатуры. Протестировать программу при различных значениях аргумента и точности, а именно:
1) При //x// = 0.05 и //ε// = 10-3;\\
2) При //x// = 0.5 и //ε// = 10-4;\\
3)
**Программа должна иметь вид:**\\
PROGRAM IterPrzv;\\
CONST N : integer = 1000;\\
VAR x, eps, P, z : real;\\
i : integer;\\
BEGIN\\
readln (x, eps);\\
P := 1.;\\
FOR i := 1 TO N DO\\
BEGIN\\
z := 2 * sin (i * x);\\
P := P * z;\\
IF (abs (z) < eps) THEN Break;\\
END;\\
writeln ('P = ', P, ', z = ', z, ', i = ', i);\\
END.\\
**Результаты вычислений:**
При //x// = 0.05 и //ε// = 10-3 : //P// = 3,13826971361323 • 10-1, //z// = 8,88156901861947 • 10-4, //i// = 377;\\
при //x// = 0.5 и //ε// = 10-4 : //P// = -4.26745750894497 • 10-2, //z// = -6.02887067189806 • 10-5, //i// = 710;\\
при //x// = 1.57 и //ε// = 10-5 : //P// = 0, //z// = -1.42958422156516, //i// = 1000;\\.
В последнем случае никакое увеличение числа //N// не приводит к достижению требуемой точности: при данном значении //x// ряд расходится.\\
[[http://wiki.likt590.ru/doku.php/metodika_prepodavanija_informatiki._06.12.2008_-_27.04.2009:fedorov_konstantin_pavlovich_gou_97_vyborgskij_rajon|на главную]]\\