1 / 1 / 0
Регистрация: 21.04.2014
Сообщений: 65
1

Создание последовательности чисел Фибоначчи (оптимизация)

23.06.2015, 15:59. Показов 2279. Ответов 10
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет.
Сразу хочу сказать спасибо постояльцам форума за помощь, которую я получил почти год назад, когда только начинал изучать программирование. С вашей помощью вошел в 25% сдавших профильный экзамен, хотя изначально знания стремились к нулю

Вопрос у меня сегодня такой: как можно оптимизировать мою функцию по созданию последовательности чисел Фибоначчи?
Вот что я написал:

Haskell
1
fib x = foldl (\x y -> x++[(head (tail(reverse x)))+(last x)] ) [1,1] (replicate (x-2) 1)
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.06.2015, 15:59
Ответы с готовыми решениями:

Найти сумму четных чисел последовательности Фибоначчи до миллиона
Уважаемые форумчане прошу помочь, так как в Хаскеле я ни бум бум. Заранее спасибо. 1) Сумму...

Определить в заданной последовательности целых чисел количество чисел Фибоначчи
Выполнить задания, если задана последовательность целых чисел длиной n. Определить в заданной...

Определить в заданной последовательности целых чисел количество чисел Фибоначчи
Определить в заданной последовательности целых чисел количество чисел Фибоначчи.

Составить программу поиска первых n четных чисел (n - с клавы), в последовательности чисел Фибоначчи
Нужно составить программу используя do while. У меня не получается, это всё что смог написать. ...

10
4817 / 2278 / 287
Регистрация: 01.03.2013
Сообщений: 5,947
Записей в блоге: 28
23.06.2015, 16:16 2
Да как угодно. Для начала, без ++, ластов и реверсов. Для продолжения - вам именно последовательность или число с определенным порядковым номером? Если первое, то есть много красивых алгоритмов, мне нравится через поток. Если второе, то есть пара не менее красивых алгоритмов.
0
650 / 260 / 16
Регистрация: 02.03.2014
Сообщений: 587
23.06.2015, 16:18 3
На удивление годный способ, я нашёл в своё время на вики...
Haskell
1
fibs = 0 : 1 : [a + b | (a,b) <- zip fibs (tail fibs)]
0
1 / 1 / 0
Регистрация: 21.04.2014
Сообщений: 65
23.06.2015, 16:33  [ТС] 4
Да, интересная функция, но она считает все числа. Можно добавить считалку по индексу, для выбора конкретного числа или последовательности. Будет это побыстрей работать. Но главная проблема, как я понял из-за того, что одно число это сумма дувух предыдущих. как обратиться к пред-предпоследнему числу не пробегая по всему списку чисел?
0
Модератор
Эксперт функциональных языков программированияЭксперт Python
36590 / 20320 / 4218
Регистрация: 12.02.2012
Сообщений: 33,621
Записей в блоге: 13
23.06.2015, 20:00 5
Haskell
1
2
3
4
fib :: Integer -> Integer
fib n = fib' n 1 1
        where fib' n c p | (n<=2) = c
                         | otherwise = fib' (n-1) (c+p) c
0
4817 / 2278 / 287
Регистрация: 01.03.2013
Сообщений: 5,947
Записей в блоге: 28
23.06.2015, 20:22 6
Araneo, этому способу скоро будет 100 лет (буквально), он основан на мемоизации вычислений в ленивых потоках и в классическом варианте (безо всякого сахара типа лист компрехеншенс) записывается так:
Haskell
1
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
В таком виде он (и еще много интересного) приведен в SICP (реализация конечно на Scheme, безо всяких листомонад и туплей), в таком же виде я его нарисовал в своем лискрипте на ленивых потоках. И тут самое интересное - у меня ленивые вычисления не мемоизируются при расчете (навскидку не удалось сделать), так что тот же самый код у меня выполняется экспоненциальное время, в на Scheme и в Haskell - линейное. Достаточно забавно, учитывая что код один и тот же, а его "годность" различается в зависимости от языка выполнения. Но конечно существует другой вариант реализации, который выполняется даже на моем скрипте линейное время, и третий - за логарифмическое.

А последний код Catstail, к примеру, запросто может в строгом языке выполняться оптимально, а в ленивом хаскеле (в котором и приведен) может сначала долго нагребать санк последовательных вычислений в аргументе функции, и вынудиться к вычислениям только в самом конце, когда он будет щедро развернут в памяти.

И это только пара моментов, касательно вышеувиденного.

Добавлено через 3 минуты
https://github.com/Ivana-/Lisc... /test1.txt
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- поток Фибоначчи - нульарная функция
-- НЕ экспоненциальный расчет
(defn fibgen (a b) (s-cons a (fibgen b (+ a b))))
(def fibs (fibgen 0 1))
(printLn "")
(printLn "первые 25 членов потока ряда Фибоначчи:")
(printLn (s-take 25 fibs))
 
-- экспоненциальный расчет
-- первый конс обычный, второй - потоковый отложенный, через макрос
(defn fibsexp () (cons 0 (s-cons 1 (s-sum (s-tail (fibsexp)) (fibsexp)))))
(printLn "")
(printLn "первые 10 членов потока ряда Фибоначчи:")
(printLn (s-take 10 (fibsexp)))
0
Модератор
Эксперт функциональных языков программирования
3051 / 2193 / 459
Регистрация: 26.03.2015
Сообщений: 8,469
23.06.2015, 20:36 7
Цитата Сообщение от Kvintero Посмотреть сообщение
Да, интересная функция, но она считает все числа.
В сабже "Создание последовательности чисел Фибоначчи"

Цитата Сообщение от Kvintero Посмотреть сообщение
Но главная проблема, как я понял из-за того, что одно число это сумма дувух предыдущих. как обратиться к пред-предпоследнему числу не пробегая по всему списку чисел?
Чтобы не вычислять предыдущие числа по нескольку раз, нужно их запомнить (в аргументах функции).
Haskell
1
2
3
fib n = iter 1 0 n where
    iter a b k | k == 0    = b
               | otherwise = iter (a + b) a (k - 1)
Но можно вычислить число Фибоначчи и без вычисления всех предшествующих чисел:
Haskell
1
2
3
4
fib2 n = iter 1 0 0 1 n where
    iter a b p q k | k == 0    = b
                   | even k    = iter a b (p*p+q*q) (2*p*q+q*q) (div k 2)
                   | otherwise = iter (b*q+a*q+a*p) (b*p+a*q) p q (k-1)
0
_Ivana
23.06.2015, 20:52
  #8

Не по теме:

Началось котомеряние, жаль тема про Фибоначчи а не про факториал - у меня есть хорошая такая ссылка насчет котомеряния факториалами. Хотя и про Фибоначчи можно не хуже собрать подборку :)

0
Shamil1
24.06.2015, 09:21
  #9

Не по теме:

Цитата Сообщение от _Ivana Посмотреть сообщение
Началось котомеряние,
Да тут даже не котомеряние, а просто использование O(logN) алгоритма вместо O(N). Быстрое возведение в степень вместо перемножения N раз.

0
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
24.06.2015, 13:21 10
Цитата Сообщение от Shamil1 Посмотреть сообщение
Но можно вычислить число Фибоначчи и без вычисления всех предшествующих чисел
ага Ряд Фибоначчи
0
_Ivana
24.06.2015, 15:11     Создание последовательности чисел Фибоначчи (оптимизация)
  #11

Не по теме:

Shamil1, да это все понятно, кэп. Плавали, писали, в тех же примерах для моего лискрипта на гитхабе реализовано. Еще про алгоритм на основе перемножения матриц (тот же, только из другой теоретической формализации) расскажите. Просто я назвал эту ситуацию котомерянием. Причем, не в плохом смысле этого слова :)

0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.06.2015, 15:11

Вычисление чисел последовательности Фибоначчи
По заданию программа, выполняет вычисление 500 первых чисел последовательности Фибоначчи. Элементы...

Вывод последовательности чисел Фибоначчи
Ввести целое число N &gt; 1. Последовательность чисел Фибоначчи FK (целого типа) определяется...

Формирования последовательности чисел Фибоначчи
Напишите программу на языке Python для формирования последовательности чисел Фибоначчи, конечное...

Найти сумму чисел Фибоначчи в последовательности
Помогите, пожалуйста решить : Задана последовательность чисел, которая заканчивается 0-ем. Нужно...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru