Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Turbo Pascal / Stud_1_1 / LecRus / Supplement.doc
Скачиваний:
109
Добавлен:
03.03.2016
Размер:
2.13 Mб
Скачать

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



Соседние файлы в папке LecRus