- •Задания для самостоятельной работы
- •2.0. Общие замечания.
- •Задания для самостоятельной работы
- •3. Числа и системы счисления
- •Задания для самостоятельной работы
- •4. Итерационные циклы
- •Задания для самостоятельной работы
- •5.0. Общие замечания.
- •Задания для самостоятельной работы
- •Задания для самостоятельной работы
- •7.0. Общие замечания.
- •Задания для самостоятельной работы
4. Итерационные циклы
4.0. В общем случае итерационным называется такой вычислительный процесс, в котором нельзя заранее определить количество повторных вычислений (количество циклов). Это количество зависит от значений исходных данных и в большинстве случаев от требуемой точности вычислений.
Критерием окончания вычислений является достижение некоторого заранее заданного условия.
4.1. Определить порядковый номер и значение наибольшего члена ряда Фибоначчи, для которого сумма предыдущих элементов этого ряда не превышает заданной величины S.
Ряд Фибоначчи формируется по правилу
В
программе Task401 цикл While,
реализующий поиск требуемого значения,
прекращает работу, когда будет достигнуто
.
Поэтому результатом решения является
значение
.
Program Task401;
Var f0,f1,f2, { члены ряда Фибоначчи }
n : word; { количество выполнений цикла }
S,Sum : longint;
Begin
Read(S); Writeln('S = ',S);
f0:=0; f1:=1; f2:=1;
n:=1; Sum:=2;
While Sum<=S do
Begin
f0:=f1; f1:=f2;
f2:=f0+f1;
Inc(n); Sum:=Sum+f2;
End;
Writeln('f1 = ',f1,' n = ',n);
End.
При b = 700 получим f1 = 610, n = 15.
4.2. Золотое сечение, используемое в задачах оптимизации, определяется как предел отношения
,
где
- два последовательных члена ряда
Фибоначчи. Требуется вычислить значение
с погрешностью, не превышающей заданного
значения
.
Сравнить полученный результат с точным
значением
Program Task402;
Const eps = 0.001;
Var f0,f1,f2, { члены ряда Фибоначчи }
n : word; { номер члена ряда Фибоначчи }
V, { текущее значение параметра V }
Vold, { предыдущее значение параметра V }
V1 : real; { точное значение золотого сечения }
Begin
f0:=0; f1:=1; f2:=1;
n:=1; V:=0;
Repeat
Vold:=V;
f0:=f1; f1:=f2; f2:=f0+f1;
Inc(n); V:=f2/f1;
Until abs(V-Vold)<=eps;
V1:=0.5*(1+sqrt(5));
Writeln('V = ',V:10:8,' V1 = ',V1:10:8,' n = ',n);
End.
Полученные результаты:
eps n V V1
0.001 10 1.61818182 1.61803399
0.0001 12 1.61805556 1.61803399
0.00001 15 1.61803279 1.61803399
0.000001 17 1.61803381 1.61803399
0.0000001 19 1.61803396 1.61803399
0.00000001 22 1.61803399 1.61803399
4.3.
Определить длину кривой
на интервале
с погрешностью, не превышающей заданного
значения
.
Решение
задачи выполнено в двух вариантах: в
виде программы для конкретной функции
и в виде подпрограммы для произвольной
функции
.
Вариант 1.
Решение
выполняется по отношению к функции
.
Длина кривой приближенно определяется
как длина ломаной, количество отрезков
которой равно количеству делений
заданного интервала
.
Начальное значение
принято равным 10. При каждом повторении
цикла Repeat
это
количество увеличивается вдвое. Цикл
работает до тех пор, пока разность между
значением LOld
длины
кривой в предыдущем цикле и значением
L
этой
длины в текущем цикле превышает допустимую
погрешность
(разность между "старым" и "новым"
значениями длины кривой).
Program Task403a;
Const eps = 0.001;
Var i,
n : word; { кол-во отрезков разделения интервала }
a,b, { границы интервала }
x1,y1,x2,y2, { конечные точки отрезка }
h, { шаг по оси абсцисс }
d, { длина отрезка }
L,LOld : real; { длина кривой }
Begin
Read(a,b);
n:=5; L:=0;
Repeat
n:=2*n; LOld:=L;
h:=(a+b)/n; L:=0;
x1:=a; y1:=sqr(sin(sqrt(x1)));
For i:=1 to n do
Begin
x2:=x1+h; y2:=sqr(sin(sqrt(x2)));
d:=sqrt(sqr(x2-x1)+sqr(y2-y1));
L:=L+d; x1:=x2; y1:=y2;
End;
Until abs(L-LOld)<=eps;
Writeln('n=',n,' L=',L:12);
End.
Для интервала [1,4] получены следующие результаты:
eps = 0.001 n = 40 L = 5.09598
eps = 0.0001 n = 80 L = 5.09606
eps = 0.00001 n = 320 L = 5.09609
Вариант 2.
Вычисление длины кривой оформлено в виде функции LengthCurve, одним из аргументов которой является имя функции F, для которой определяется длина кривой. Формальный аргумент F является функциональным параметром типа Fun, описанным в разделе Type. При обращении к функции LengthCurve аргументу F соответствуют имена конкретных функций F1 и F2, являющихся функциональными константами. Поскольку имена F1 и F2 воспринимаются как константы, аргумент F в списке формальных параметров является параметром-значением (перед именем F не ставится слово Var).
С точки зрения машинного представления параметр F - это указатель, определяющий адрес точки входа соответствующей функции. Для указателя всегда выделяется 4 байта памяти, в которых записывается полный адрес поля памяти (адрес сегмента и смещение).
Для процедур и функций обычно генерируется краткий адрес точки входа размером 2 байта, в которых записывается только смещение. Чтобы было обеспечено соответствие между функциональным параметром F и функциональными константами F1 и F2, перед описанием функций F1 и F2 установлена директива F+, предписывающая компилятору генерировать полные адреса процедур и функций.
Функция
F1
вычисляет значение
,
функция
F2
-
.
Program Task403b;
Type Fun = function(x:real):real;
Var L1,L2 : real; { длины кривых }
{ -------------------------------------- }
{$F+}
Function F1(x:real):real;
Begin
F1:=sqr(sin(sqrt(x)));
End { F1 };
{ -------------------------------------- }
Function F2(x:real):real;
Begin
F2:=exp(sqrt(x+sin(x)));
End { F2 };
{$F-}
{ -------------------------------------- }
Function LengthCurve(F:Fun; a,b,eps:real):real;
{ F - имя функции; a,b - границы интервала; }
{ eps - допустимая погрешность }
Var i,
n : word; { кол-во отрезков разделения интервала }
x1,y1,x2,y2, { конечные точки отрезка }
h, { шаг по оси абсцисс }
d, { длина отрезка }
L,LOld : real; { длина кривой }
Begin
n:=5; L:=0;
Repeat
n:=2*n; LOld:=L;
h:=(a+b)/n; L:=0;
x1:=a; y1:=F(x1);
For i:=1 to n do
Begin
x2:=x1+h; y2:=F(x2);
d:=sqrt(sqr(x2-x1)+sqr(y2-y1));
L:=L+d; x1:=x2; y1:=y2;
End;
Until abs(L-LOld)<=eps;
LengthCurve:=L;
End { LengthCurve };
{ -------------------------------------- }
Begin
L1:=LengthCurve(F1,1,4,0.001);
L2:=LengthCurve(F2,1,4,0.001);
Writeln('L1 = ',L1:12,' L2 = ',L2:12);
End.
В результате работы программы Task403b получены следующие значения:
L1 = 5.09598 L2 = 9.41317
