Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
21 ошибка прогр... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
ТЕХНОЛОГИИ ДОСТ... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Имитационное мо... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Реклама
Итальянская женская одежда интернет магазин брендовая одежда www.yakonastore.ru.
Сейчас на сайте
Гостей: 7
Пользователь: dimafikas

Пользователей: 13,372
новичок: vausoz
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

База данных электронного документооборота на Delphi + бд Intebase
Моделирование работы участка термической обработки шестерен на GPSS + По...
Обратное размещение элементов ЭВС на Delphi + Пояснительная записка

Нерекурсивное вычисление чисел Фибоначчи
К сожалению, содержит
не только . Алгоритм использует два рекурсивных обращения
для вычисления значения. Второй вызов следует после завершения первого. По-
скольку первый вызов находится не в самом конце функции, это не хвостовая ре-
курсия, поэтому ее нельзя удалить обычным способом.
Возможно, рекурсии нельзя избежать еще потому, что рекурсивный алгоритм
Фибоначчи ограничен скорее вычислением слишком большого количества проме-
жуточных значений, чем глубиной рекурсии. Удаление хвостовой рекурсии умень-
шает глубину рекурсии, но это не изменяет время выполнения алгоритма. Даже
без хвостовой рекурсии он все равно будет чрезвычайно медленным.
Проблема заключается в том, что алгоритм повторно вычисляет одни и те же
значения много раз. Значения Fib(l) и Fib(0) просчитываются Fib(N +1) раз при
вычислении Fib(N). Для определения Fib(29) алгоритм вычисляет значения Fib(0)
и Fib( 1) 832 040 раз.
Поскольку алгоритм повторно высчитывает одни и те же значения много раз,
необходимо отыскать способ, который бы позволил избежать повторных вычисле-
ний. Простой и конструктивный прием - сформировать таблицу расчетных значе-
ний. Когда потребуется промежуточное значение, можно взять его из таблицы, а не
вычислять заново.
В этом примере показано, как создать таблицу для хранения значений функ-
ции Фибоначчи Fib(N) для N < 1477. Для N > 1477 происходит переполнение пе-
ременных типа Double, используемых функцией. В следующем коде представле-
на функция Фибоначчи с соответствующими изменениями:
Const
MAX_FIB=1476; // Самое большое значение, которое можно вычислить.
var
FiboValues : Array [O..MAX_FIB] of Double;
function Fibofn : Integer) : Double;
begin
// Вычисление значения, если его нет в таблице.
if (FiboValues[n]<0.0) then
FiboValues[n] := Fibo(n-1)+Fibo(n-2);
Fibo := FiboValues[n];
end;



При запуске программа присваивает каждому элементу массива FiboValues
значение - единицу. Затем она устанавливает значение FiboValues [ 0 ] в нуль,
a FiboValues [ 1 ] - в единицу. Эти значения составляют основное условие ре-
курсии.
При выполнении функции массив проверяется на наличие необходимого зна-
чения. Если его там нет, функция рекурсивно вычисляет это значение и сохраняет
его для дальнейшего использования.
Программа Fibo2 использует этот метод для подсчета чисел Фибоначчи. Про-
грамма может быстро вычислять Fib(N) для N порядка 100 или 200. Но если вы
попробуете определить Fib(1476), то программа выполнит последовательность
рекурсивных вызовов глубиной 1476 уровней, в результате чего стек вашей систе-
мы, скорее всего, переполнится.
Альтернативный метод заполнения таблицы чисел Фибоначчи позволяет из-
бежать такой глубокой рекурсии. Когда программа инициализирует массив Fibo-
Values, она заранее вычисляет все числа Фибоначчи.
// Инициализация таблицы соответствия.
procedure TFiboForm.FormCreate(Sender : TObject);
var
i : Integer;
begin
FiboValues [0] := 0;
FiboValues [ 1 ] := 1;
for i := 2 to MAX_FIB do
FiboValues[i] := FiboValues[i-1]+FiboValues[i-2];
end;
// Поиск чисел Фибоначчи в таблице.
function Fibofn : Integer) : Double;
begin
Fibo : = FiboValues[n] ;
end;



При выполнении этого алгоритма определенное время занимает создание мас-
сива поиска. Как только массив готов, для обращения к значению массива требу-
ется всего один шаг. Ни процедура инициализации, ни функция Fib не использу-
ют рекурсию, поэтому ни одна из них не исчерпывает память стека. Программа
Fibo3 демонстрирует предложенный подход.
Стоит рассмотреть еще один метод вычисления чисел Фибоначчи. Первое ре-
курсивное определение функции Фибоначчи использует нисходящий способ.
Чтобы получить значение для Fib(N), алгоритм рекурсивно вычисляет Fib(N - 1)
и Fib(N - 2) и складывает их.
Процедура InitializeFibValues работает снизу вверх. Она начинает со
значений Fib(O) и Fib(l). Затем она использует меньшие значения для вычисле-
ния больших, пока таблица не заполнится.
Можно использовать эту стратегию, чтобы непосредственно вычислять значе-
ние функции Фибоначчи. Данный метод занимает больше времени, чем поиск
значений в массиве, но не требует дополнительной памяти для размещения масси-
ва. Это пример пространственно-временного компромисса. Чем больше памяти
используется для хранения таблицы, тем быстрее выполняется алгоритм.
function Fibo(n : Integer) : Double;
var
fib_i, fib_i_minus_1, fib_i_minus_2 : Double;
i : Integer;
begin
if (n<=l) then
Fibo := n
else
begin
fib_i := 0; // Предотвращает предупреждение компилятора.
fib_i_minus_2 := 0; //Начальное значение fib(0).
fib_i_minus_1 := 1; //Начальное значение fib(1).
for i := 2 to n do
begin
fib_i := fib_i_minus_l+fib_i_minus_2;
fib_i_itiinus_2 := f ib_i_minus_1 ;
fib_i_minus_1 := fib_i;
end;
Fibo := fib_i;
end;
end;



Для вычисления значения Fib(N) этой версии необходимо O(N) шагов. Это
больше, чем один шаг, который требовался в предыдущей версии, но гораздо быс-
трее, чем O(Fib(N)) в исходной версии алгоритма.
На компьютере, имеющем процессор Pentium с тактовой частотой 133 МГц,
первоначальный рекурсивный алгоритм вычислял бы Fib(40) = 1.02E + 8 более
155 с. Новый алгоритм не требует большого количества времени, чтобы опреде-
лить fib(1476) = 1,31Е + 308.
Опубликовал Kest October 20 2009 20:20:11 · 0 Комментариев · 13278 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Нет комментариев.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
PDJXPPack
IconCut [Исходник...
Delphi и технолог...
DelphiXIsoDemo1
Базы данных в Инт...
De Knop
Панель случайной ...
Пример работы с ф...
Заставка. Изображ...
PolyFlow
Меню проводника в...
AUTOWEB
Простой текстовый...
Delphi World 6.0
AlignEdit
Создание фракталов
Delphi 2005 Учимс...
SysInfo [Исходник...
Animation Effect ...
KOL & MCK v1.69

Топ загрузок
Приложение Клие... 100793
Delphi 7 Enterp... 98031
Converter AMR<-... 20298
GPSS World Stud... 17060
Borland C++Buil... 14244
Borland Delphi ... 10376
Turbo Pascal fo... 7392
Калькулятор [Ис... 6082
Visual Studio 2... 5232
Microsoft SQL S... 3674
Случайные статьи
Определение шаблон...
Управляемая инициа...
Премия за завершение
Шаблоны
• тип службы (_lda...
Доступ к переменны...
Реализация вызова ...
Слабоструктуриров...
Сайдбар сайта тепе...
Отношения между уч...
Маленькие кухни
Теперь выньте плат...
к ресурсам для уче...
Too many open files
Редактирование диз...
Где светодиодные л...
Создание приложени...
Структура простого...
Специальный маршалинг
Технология Frame R...
League for Program...
Вычислительные мо...
Небольшие изменени...
Определение списка
Современные телеко...
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?