Навигация
Главная
Поиск
Форум
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
Реклама
Сейчас на сайте
Гостей: 12
На сайте нет зарегистрированных пользователей

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

База данных междугородних телефонных разговоров на Delphi
База данных электронного документооборота на Delphi + бд Intebase
Моделирование круглосуточного интернет кафе на GPSS + Отчет

Нерекурсивное вычисление чисел Фибоначчи
К сожалению, содержит
не только . Алгоритм использует два рекурсивных обращения
для вычисления значения. Второй вызов следует после завершения первого. По-
скольку первый вызов находится не в самом конце функции, это не хвостовая ре-
курсия, поэтому ее нельзя удалить обычным способом.
Возможно, рекурсии нельзя избежать еще потому, что рекурсивный алгоритм
Фибоначчи ограничен скорее вычислением слишком большого количества проме-
жуточных значений, чем глубиной рекурсии. Удаление хвостовой рекурсии умень-
шает глубину рекурсии, но это не изменяет время выполнения алгоритма. Даже
без хвостовой рекурсии он все равно будет чрезвычайно медленным.
Проблема заключается в том, что алгоритм повторно вычисляет одни и те же
значения много раз. Значения 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 Комментариев · 12906 Прочтений · Для печати

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


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



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

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

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

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

Пароль



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

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

Случайные загрузки
Проигрыватель Mp3
Dynamic Titles дл...
PBEditPack
XPmenu
VFW
3d Tank [Исходник...
AntiRus
3D Октаэдр
Atb
Delphi 2005 Учимс...
Converter AMR<->W...
Delphi 2005 для W...
Философия C++. Пр...
HTMLredaktor
AJAX и PHP. разра...
DemoEdit [Исходни...
Turbo Pascal for ...
Пятнашки и крести...
Основы Delphi. Пр...
Аватары в комме...

Топ загрузок
Приложение Клие... 100774
Delphi 7 Enterp... 97833
Converter AMR<-... 20268
GPSS World Stud... 17014
Borland C++Buil... 14191
Borland Delphi ... 10291
Turbo Pascal fo... 7373
Калькулятор [Ис... 5984
Visual Studio 2... 5207
Microsoft SQL S... 3661
Случайные статьи
Формы расширенного...
Век 7800 оказался ...
Работа с переменны...
Повышаем тИЦ
Проект VirtualSOMA
Проверка достоверн...
Программирование: ...
Основанные принцип...
Пример на создан»—...
Виртуальные машины...
Удаление индекса (...
Компиляторы MIPS
Методы и их резуль...
Шаг к реализации с...
Простые свойства
Ваш выбор заметноп...
Ввод и вывод. Чтен...
Класс TCanvas
Рабочая площадка р...
Поиск максимальног...
File: are not allo...
Свойства триггера
Почему пользовател...
Шесть тепловых стр...
OrderID — номер за...
Статистика



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


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