Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Хитрый алгоримт для вычисления чисел Фибоначи, Не могу найти решение 
:(
    Опции темы
Proger89
Дата 17.11.2009, 00:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 77
Регистрация: 13.12.2007

Репутация: нет
Всего: нет



Доброго времени суток.
Нашел в книге по программированию одну интересную задачу, долго бился и никак не могу её решить.
Вот как она звучит:

"Существует хитрый алгоритм получения чисел Фибоначчи за логарифмическое число шагов.
Вспомните трансформацию переменных состояния a и b процесса fib-iter из раздела 1.2.2:
a ← a + b и b ← a. Назовем эту трансформацию T и заметим, что n-кратное применение T, начи-
ная с 1 и 0, дает нам пару Fib(n + 1) и Fib(n). Другими словами, числа Фибоначчи получаются
путем применения Tn, n-ой степени трансформации T, к паре (1,0). Теперь рассмотрим T как
частный случай p = 0, q = 1 в семействе трансформаций Tpq, где Tpq преобразует пару (a, b) по
правилу a ← bq + aq + ap, b ← bp + aq. Покажите, что двукратное применение трансформации
Tpq равносильно однократному применению трансформации Tp′q′ того же типа, и вычислите p′ и
q′ через p и q. Это дает нам прямой способ возводить такие трансформации в квадрат, и таким
образом, мы можем вычислить Tn с помощью последовательного возведения в квадрат, как в
процедуре fast-expt. Используя все эти идеи, завершите следующую процедуру, которая дает
результат за логарифмическое число шагов"

Далее приведен незаконченный код на языке LISP:

Код

(define (fib n)
   (fib-iter 1 0 0 1 n))

(define (fib-iter a b p q count)
   (cond ((= count 0) b)
             ((even? count)
             (fib-iter a
                          b           
                          h??i ; вычислить p’
                          h??i ; вычислить q’
                          (/ count 2)))
             (else (fib-iter (+ (* b q) (* a q) (* a p))
                                  (+ (* b p) (* a q))
                                   p
                                   q
                                   (- count 1)))))



Помогите найти решение.
Заранее благодарен.
PM   Вверх
esperanto
Дата 17.11.2009, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 194
Регистрация: 31.5.2003

Репутация: 2
Всего: 4



Есть закрытая формула для вычисления чисел Фиобоначи.

По этой формуле можно быстро посчитать

--------------------
B.Sc ->M.Sc.->Microsoft SDE-> (Ph.D. student + Intel SDE + psyсhology B.A) - > Skype SDET
PM MAIL   Вверх
Proger89
Дата 17.11.2009, 23:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 77
Регистрация: 13.12.2007

Репутация: нет
Всего: нет



Цитата(esperanto @ 17.11.2009,  15:42)
Есть закрытая формула для вычисления чисел Фиобоначи.

По этой формуле можно быстро посчитать

А где найти эту формулу? Гугл ничего не дал.
Кроме того, мой вопрос состоял в решении конкретной задачи, а не в поиске формулы.
PM   Вверх
maxdiver
Дата 22.11.2009, 01:07 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 381
Регистрация: 29.1.2008
Где: Саратов

Репутация: 16
Всего: 18



Если более полно - то для нахождения решения надо возвести матрицу 2x2 ( (0,1), (1,1) ) в n-ю степень, и тогда ответом будет число во второй строке, первой колонке. Как возводить матрицу в степень за логарифмическое время - метод бинарного возведения (или по книге "fast-exp"). Чаще всего его описывают применительно к числам, но он применим и для матриц:
Код
matrix binpow (matrix a, int n) {
    int res = 1;
    while (n)
        if (n % 2 == 1) {
            res *= a;
            --n;
        }
        else {
            a *= a;
            n /= 2;
        }
    return res;
}


Добавлено через 2 минуты и 48 секунд
Собственно одна такая матрица ( (0,1), (1,1) ) - она описывает однократное применение преобразования, о котором идёт речь в книге. Применяя n раз это преобразование, получаем матрицу, которая исходный вектор чисел Фибоначчи (F0, F1) = (0, 1) преобразует при умножении на себя в вектор (Fn, F{n+1}). Отсюда как раз и следует, что первый элемент результирующего вектора, Fn = 0 * A[1][1] + 1 * A[2][1] = A[2][1], и даст ответ.
PM MAIL WWW ICQ   Вверх
de14
Дата 26.12.2009, 11:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 26.12.2009

Репутация: нет
Всего: нет



p'=(+ (* p p ) (* q q))
q'=(+ (* 2 p q) (* q q))

Все что требовалось при решении задачи - это посчитать
  a'(i+1)=bq+aq+ap
  b'(i+1)=bp+aq
где
   a=b'q+a'q+a'p
   b=b'p+a'q
тогда получиться
  a'<-...
  b'<-b'(p*p+q*q)+a'(2pq+q*q) <=> b'p'+a'q'
следовательно
  p'=p*p+q*q
  q'=2pq+q*q
(Это можно проверить посчитав a' или подставив значения в программу или посчитав в матричном виде)

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Алгоритмы"

maxim1000

Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Алгоритмы | Следующая тема »


 




[ Время генерации скрипта: 0.0789 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.