Рекурсия - смерть процессора (Зависание программы использующей рекурсию)

Модератор: Модераторы разделов

Ardes
Сообщения: 50
ОС: Fedora Core GNU/Linux

Рекурсия - смерть процессора

Сообщение Ardes »

Совсем недавно начал изучать Си++. После изучения некоторых управляющих структур решил написать программу вычисляющую сотый член последовательности Фибоначи. Написал, работает. Вычисляет очень быстро, сразу после нажатия на клавишу ВВОД. Сегодня дошел до темы Рекурсия и решил на ее основе написать еще одну прогу. Она также должна вычислять соты член последовательности. Написал, скомпилировал без ошибок. Но после запуска она виснет! Процессор на сто процентов, и в месте где должен высветиться результат просто мигает курсор. Не понимаю! Подскажите плиз, в чем моя ошибка или так и должно быть???
Обычная прога:

Код:

//Последовательность Фибоначи #include <iostream> using namespace std; main() { int counter, a, b, c; counter = 1; a = b = 1; while (counter <= 100) { c = a + b; a = b; b = c; counter++; } cout << c << endl; return 0; }


Прога с использованием рекурсии:

Код:

//Вычисление члена последовательности Фибоначи с помощью рекурсии #include <iostream> using namespace std; unsigned long fibonachi(unsigned long); main() { unsigned long number = 100, result; result = fibonachi(number); cout << result << endl; return 0; } unsigned long fibonachi(unsigned long n) { if (n == 0 || n == 1) return n; else return fibonachi(n-1) + fibonachi(n - 2); }
Спасибо сказали:
Аватара пользователя
Subj
Сообщения: 151
Статус: Useful
ОС: win

Re: Рекурсия - смерть процессора

Сообщение Subj »

упс
Building better software with Ada
Спасибо сказали:
Ardes
Сообщения: 50
ОС: Fedora Core GNU/Linux

Re: Рекурсия - смерть процессора

Сообщение Ardes »

Результат тот же)) зависание)
Спасибо сказали:
Аватара пользователя
Subj
Сообщения: 151
Статус: Useful
ОС: win

Re: Рекурсия - смерть процессора

Сообщение Subj »

Ardes писал(а):
17.07.2008 18:28
Результат тот же)) зависание)

ошибочка вышла ))

Слишком много рекурсивных вызовов может? Начальное значение 100 уменьшать не пробовали?
Building better software with Ada
Спасибо сказали:
Аватара пользователя
KiWi
Бывший модератор
Сообщения: 2521
Статус: статус, статус, статус

Re: Рекурсия - смерть процессора

Сообщение KiWi »

В такой реализации -- да.
Потому что _каждый_ раз при вычислении члена последовательности _заново_ вычисляются все предыдущие.
То есть количество операций сводится где-то к факториалу... Что для 100 при самой грубой оценке -- больше 10^90.
Спасибо сказали:
Ardes
Сообщения: 50
ОС: Fedora Core GNU/Linux

Re: Рекурсия - смерть процессора

Сообщение Ardes »

Странно, ведь этот пример был использован в книге. Значит в коде ошибки нет?
Спасибо сказали:
Аватара пользователя
Crazy
Сообщения: 862
Статус: Адепт Дзен.
ОС: Mint, Win7.

Re: Рекурсия - смерть процессора

Сообщение Crazy »

Даю наводку

Код: Выделить всё

fibonachi(n-1) + fibonachi(n - 2)

Desipere in loco
Спасибо сказали:
Ardes
Сообщения: 50
ОС: Fedora Core GNU/Linux

Re: Рекурсия - смерть процессора

Сообщение Ardes »

Crazy, если честно не очень НАВЕЛО)))
Спасибо сказали:
Аватара пользователя
Subj
Сообщения: 151
Статус: Useful
ОС: win

Re: Рекурсия - смерть процессора

Сообщение Subj »

Ardes писал(а):
17.07.2008 18:40
Crazy, если честно не очень НАВЕЛО)))

у тебя получается 2**100 (мож поменьше на степень) рекурсивных вызовов (навскидку )) )
Building better software with Ada
Спасибо сказали:
Ardes
Сообщения: 50
ОС: Fedora Core GNU/Linux

Re: Рекурсия - смерть процессора

Сообщение Ardes »

а по-моему побольше)) 2*!100 вызовов))) очень много)) наверное у автора книги дома компьютер НАСА стоит)_
Спасибо сказали:
Аватара пользователя
Crazy
Сообщения: 862
Статус: Адепт Дзен.
ОС: Mint, Win7.

Re: Рекурсия - смерть процессора

Сообщение Crazy »

Число вызовов растет экспотенциально.
При рекурсии используется скрытый стек. Количество памяти выделяется около 64 кб, в зависимости от компилятора.
Итак, урок таков: следует избегать рекурсии там, где есть очевидное итерационное решение.

P.S
Читай Никлаус Вирт "Алгоритмы и структуры данных",
Дональд Кнут "Искусство программирования"
У вас нет необходимых прав для просмотра вложений в этом сообщении.

Desipere in loco
Спасибо сказали:
Ardes
Сообщения: 50
ОС: Fedora Core GNU/Linux

Re: Рекурсия - смерть процессора

Сообщение Ardes »

Спасибо за детальное объяснение и литературу! Обязательно почитаю!
Спасибо сказали:
KernelPanic
Бывший модератор
Сообщения: 2060
Статус: Brain Атаке
ОС: Debian squeeze/sid/exp

Re: Рекурсия - смерть процессора

Сообщение KernelPanic »

Andres, какой-то код второй у вас странный, первый член = 1, и второй член последовательности = 1.
Спасибо сказали:
Ardes
Сообщения: 50
ОС: Fedora Core GNU/Linux

Re: Рекурсия - смерть процессора

Сообщение Ardes »

Код правильный! Последовательность Фибоначи: 1, 1, 2, 3, 5 и т.д. ))
Спасибо сказали:
Аватара пользователя
uptime
Сообщения: 1661
Статус: Drinker with computing problems
ОС: kubuntu 8.04

Re: Рекурсия - смерть процессора

Сообщение uptime »

Похоже, что автор торопился и не успел прогнать свой код. В любом случае, пример для рекурсии он выбрал не удачный.
The answer, my friend, is blowin' in the wind.
The answer is blowin' in the wind.
Спасибо сказали:
Аватара пользователя
MUTOgen
Сообщения: 343
Статус: i like the way you move
ОС: OpenSuse 11.1

Re: Рекурсия - смерть процессора

Сообщение MUTOgen »

По теме хочу согласиться Crazy, рекурсия вещь опасная и ошибки в алгоритме действий очень трудно отследить, особенно кодгда одна, вде или более рекурсивных активно взаимодействующих функций... Помню всего один случай у себя где ее нельзя было никак обойти (решал тогда задачу изображения фракталов :) )... ну а вообще частота столкновений с рекурсией это дело сугубо индивидуальное.
Спасибо сказали:
KernelPanic
Бывший модератор
Сообщения: 2060
Статус: Brain Атаке
ОС: Debian squeeze/sid/exp

Re: Рекурсия - смерть процессора

Сообщение KernelPanic »

Зато красиво ;) это тоже своего рода искусство.
Спасибо сказали:
Аватара пользователя
Crazy
Сообщения: 862
Статус: Адепт Дзен.
ОС: Mint, Win7.

Re: Рекурсия - смерть процессора

Сообщение Crazy »

Вообще это банальная ошибка переполнения стека. Нужно всегда заботится о завершения рекурсии.
Не всегда есть простое итерационное решение, например задача о восьми ферзях, стабильных браков, оптимального выбора.

Desipere in loco
Спасибо сказали: