
- •Основы Алгоритмизации и Программирования
- •Цели :
- •Литература
- •Методические пособия
- •Тема 1 Программирование с
- •Рекуррентные соотношения и стратегии решения задачи разбиением ее на подзадачи
- •• Определение 1.
- •Определение 2.
- ••Любое правильное рекуррентное уравнение при задании начального условия описывает некую счетную бесконечную последовательность
- •Примеры описания объектов с помощью рекуррентных уравнений
- •Примеры описания объектов с помощью рекуррентных уравнений
- •Примеры описания объектов с помощью рекуррентных уравнений
- ••Все выше приведенные определения являются рекурсивными, т.е. представляют объект соотношением, выражающим объект через
- ••В общем виде рекурсивный алгоритм P можно
- •Решать задачу рекурсивно (т.е. составить рекурсивный алгоритм)
- •Вычисление n-го числа Фиббоначи
- •Две стратегии разбиения на подзадачи
- •Стратегия
- •Недостаток стратегии РиВ
- •Стратегия
- •Суть стратегии ДП
- •Программирование рекуррентных соотношений
- •Вычисление n!
- •Найдем максимум a1...an
- •Нахождение max(a1..an) (как метод класса)
- •Нахождение max(a1..an)
- ••Итерация - от человека.
- •Класс c методом ввода массива
- •Найти max делением пополам
- •Найти номер max делением пополам
- •Работа с методами класса Tob
- •Замечание
- •Особенности выполнения рекурсивной подпрограммы
- •Особенности выполнения
- •Особенности выполнения
- •Рекурсивный вызов может быть прямым,
- •Организация выхода из рекурсии
- •Условия окончания рекурсии
- •О целесообразности использования рекурсивных подпрограмм
- •Неподходящий пример
- •Решение с помощью итерационного алгоритма по стратегии динамического программирования
- •рекомендация
- •Задача о Ханойской башне
- •Ханойская башня
- •Ханойская башня из 2 дисков
- •Ханойская башня из n дисков
- •Рекурсивный алгоритм
- •Рекурсивная подпрограмма
- •Hanoi(3,1,2,3) вызовет следующее дерево активаций и печати
- •результат
- •Три диска
- •Функция Аккермана
- •Матрица Аккермана
- •Рекурсивная функция
- ••procedure TForm1.Button1Click(Sender: TObject);
- •Правила выбора программной реализации рекуррентных соотношений
- •если возникающие подзадачи на каждом шаге независимы, то каждая из них будет решаться
- ••Контрольные вопросы
- •Задачи для контроля
- •Задачи для контроля
- •Конец темы 1
Рекурсивный вызов может быть прямым,
икосвенным
•Procedure B(j:byte);Forward;
•Procedure A(i:byte);
• |
begin |
• |
... |
• |
B(i); |
• |
end; |
•Procedure B;
• |
begin |
• |
... |
• |
A(j); |
• |
end; |
•используется опережающее описание с помощью стандартной директивы Forward
02.07.19 |
41 |
Организация выхода из рекурсии
•Function F(i:integer):<тип>;
•Var …
•Begin
•If i=i0 then F:=ao
• |
else begin |
|
• |
|
. . . |
• |
|
F:=F(i 1); |
• |
|
. . . |
• |
|
end; |
• End; |
|
|
|
02.07.19 |
42 |
Условия окончания рекурсии
Подобно любым циклическим алгоритмам рекурсивные подпрограммы могут приводить к своеобразному зацикливанию, когда в процессе последовательного перехода к нижнему уровню не выполняется условие, обеспечивающее нахождение тривиальной подзадачи.
Обычно окончание реализуют след. образом:
Рекурсивный параметр n при каждом обращении уменьшают
n-1 или увеличивают n+1
проверяют условие достижения тривиальной задачи
if (n=Nmin) или if(n=Nmax).
Важно также сделать оценку максимальной глубины рекурсии чтобы убедиться, что она достаточно мала и не приводит к переполнению программного стека
02.07.19 |
43 |
О целесообразности использования рекурсивных подпрограмм
Как мы видели, рекурсивные алгоритмы особенно подходят для задач, допускающих рекурсивное разбиение на элементарные подзадачи.
Однако это не означает, что для решения таких задач бесспорно употребление рекурсивных подпрограмм.
Более того, опыт рекурсивного программирования алгоритмов на неподходящих для этого примерах вызвал широко распространенное предубеждение, что их использование абсолютно неэффективно.
02.07.19 |
44 |

Неподходящий пример
-вычисление чисел Фибоначчи
• а) b0=0; b1=1; |
б) bn=bn-1+bn-2 |
•Изящная рекурсивная подпрограмма:
•Function Fb(n:word):word;
• |
begin |
• |
if n=0 then Fb:=0 |
• |
else if n=1 then Fb:=1 |
• |
else Fb:=Fb(n-1)+Fb(n-2) |
• |
end; |
02.07.19 |
Элементарные |
45 |
подзадачи |

Работа подпрограммы для F=Fb(5) Дерево из 2n-1 обращений
|
|
|
b5=5 |
|
|
|
b3=2 |
|
|
|
|
b4=3 |
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
b2=1 |
|
|
b3=2 |
|
|
|
|
b =1 |
|
|
||
|
|
|
|
2 |
|
|
b1=1 |
|
|
|
|
|
b2=1 |
b =0 |
b1=1 |
b0=0 |
b1=1 |
b1=1 |
|
|
0 |
|
|
|
|
|
|
|
|
|
|
|
b0=0 |
b1=1 |
Из этого представления видно, что не выполняется основное
требование стратегии «разделяй и властвуй» – разбиение производится на зависимые подзадачи, решение которых при
рекурсивной реализации многократно повторяются
02.07.19 |
46 |
Решение с помощью итерационного алгоритма по стратегии динамического программирования
•Function Fb(n:word):word;
• |
Var i,x,y,z:word; |
• |
begin if n=0 then Result:=0 |
•else if n=1 then Result:=1 else
•begin
•x:=0; y:=1
•for i:=2 to n do
•begin
•z:=x+y;
•x:=y;
• |
y:=z; |
•end end;
•Result:=y;
• end;
• Промежуточные решения запоминаются в x,y,z и нет |
|
повторов |
47 |
02.07.19 |
рекомендация
Из этого примера следует, что не нужно применять рекурсию там, где есть очевидное итерационное (табличное) решение.
В принципе, любую рекурсивную подпрограмму можно преобразовать в чисто итеративную (табличную). Однако во многих случаях это требует явной организации стека и преобразования настолько затуманивают суть программы, что ее бывает трудно понять.
Решение следующей задачи является примером разумного применения рекурсии.
02.07.19 |
48 |
Задача о Ханойской башне
•Имеются три стержня s1,s2,s3.
•На первом из них нанизаны n дисков различных диаметров, образующих правильную пирамиду чем выше расположен диск, тем меньше его диаметр.
•Требуется переместить всю башню на второй стержень, причем диски можно переносить по одному, нельзя помещать диск на диск меньшего диаметра, для промежуточного хранения можно использовать третий диск
02.07.19 |
49 |

Ханойская башня
02.07.19 |
50 |