Программа Java последовательность Fibonacci

bool псевдоним для System.Boolean, как int псевдоним для System.Int32. Посмотрите полный список псевдонимов здесь: Встроенная Таблица Типов (Ссылка C#) .

5
задан jackrabbit 23 May 2011 в 19:48
поделиться

8 ответов

Проблема в том, что из-за того, что вы используете простую рекурсию, вы многократно переоцениваете F (n), поэтому время выполнения экспоненциально.

Есть два простых способа исправить это. :

1) Кэшировать значения F (n), когда они оцениваются в первый раз. Прежде чем оценивать F (n), проверьте кеш, чтобы убедиться, что вы уже рассчитали его для этого n.

2) Используйте итерационный подход: вычислите F (1), F (2), F (3) и т. Д. .. пока не наберете нужный номер.

10
ответ дан 18 December 2019 в 05:33
поделиться

Если вы воспользуетесь наивным подходом, вы получите огромное количество одинаковых вычислений, т.е. для вычисления fib (n) вам нужно вычислить fib (n-1) и fib (n-2). Затем, чтобы вычислить fib (n-1), вы должны вычислить fib (n-2) и fib (n-3) и т. Д. Лучше сделать обратное. Вы вычисляете, начиная с fib (0), fib (1), fib (2), и сохраняете значения в таблице. Затем для вычисления последующих значений используются значения, хранящиеся в таблице (массиве). Это также называется мемоизацией. Попробуйте это, и вы сможете вычислять большие числа Фиби.

0
ответ дан 18 December 2019 в 05:33
поделиться

Проблема в не JAVA, а то, как вы реализуете свой алгоритм Фибоначчи. Вы вычисляете одни и те же значения много раз, что замедляет вашу программу.

Попробуйте что-нибудь вроде этого: Фибоначчи с мемоизацией

1
ответ дан 18 December 2019 в 05:33
поделиться

Создайте массив со 100 значениями, затем, когда вы вычисляете значение для Fib (n), сохраните его в массиве и используйте этот массив для получения значений Fib (n-1) и Fib (n-2).

Если вы вызываете Fib (100) без сохранения каких-либо ранее вычисленных значений, вы заставите свою среду выполнения Java взорваться.

Псевдокод:

array[0] = 0;
array[1] = 1;
for 2:100
array[n] = array[n-1] + array[n-2];
2
ответ дан 18 December 2019 в 05:33
поделиться

Есть несколько решений. Самый простой - использовать мемоизацию . Также существует формула Бине , которая даст вам n-е число Фибоначчи за постоянное время.

Для мемоизации вы сохраняете свои результаты для F [a_i] на карте или в каком-либо списке. В наивной рекурсии, например, вы вычисляете F [4] сотни тысяч раз. Сохраняя все эти результаты по мере их нахождения, рекурсия перестает развиваться как дерево и выглядит как простое итеративное решение.

Если это не домашнее задание, используйте формулу Бине. Это самый быстрый из доступных методов.

6
ответ дан 18 December 2019 в 05:33
поделиться

Проблема в том, что ваш алгоритм, хотя и математически чистый (и красивый), не очень хорош.
Для каждого числа, которое он хочет вычислить, он должен вычислить два меньших, которые, в свою очередь, должны вычислить два меньших, и т.д. Ваш текущий алгоритм имеет нотацию Big O сложность примерно O (1.6 n ) , поэтому для очень больших чисел (например, 100) это занимает много времени.

В этой книге, Структура и интерпретация компьютерных программ есть хорошая диаграмма : показывает, что происходит, когда вы генерируете fib 5 с помощью вашего алгоритма

(источник: mit.edu )

Самый простой способ - сохранить F - 1 и F - 2, чтобы не приходилось каждый раз рассчитывать их с нуля. Другими словами, вместо рекурсии используйте цикл. Тогда означает, что сложность алгоритма изменяется от O (1,6 n ) до O (n).

7
ответ дан 18 December 2019 в 05:33
поделиться

Попробуйте этот пример, он вычисляет миллионное число Фибоначчи за разумный промежуток времени без какой-либо потери точности.

import java.math.BigInteger;

/*
250000th fib # is: 36356117010939561826426 .... 10243516470957309231046875
Time to compute: 3.5 seconds.
1000000th fib # is: 1953282128707757731632 .... 93411568996526838242546875
Time to compute: 58.1 seconds.
*/
public class Fib {
    public static void main(String... args) {
        int place = args.length > 0 ? Integer.parseInt(args[0]) : 1000 * 1000;
        long start = System.nanoTime();
        BigInteger fibNumber = fib(place);
        long time = System.nanoTime() - start;

        System.out.println(place + "th fib # is: " + fibNumber);
        System.out.printf("Time to compute: %5.1f seconds.%n", time / 1.0e9);
    }

    private static BigInteger fib(int place) {
        BigInteger a = new BigInteger("0");
        BigInteger b = new BigInteger("1");
        while (place-- > 1) {
            BigInteger t = b;
            b = a.add(b);
            a = t;
        }
        return b;
    }
}
5
ответ дан 18 December 2019 в 05:33
поделиться

Это код на Python, который можно легко преобразовать в C / Java. Первое рекурсивное, второе - итеративное решение.

def fibo(n, i=1, s=1, s_1=0):
    if n <= i: return s
    else: return fibo(n, i+1, s+s_1, s)


def fibo_iter_code(n):
    s, s_1 = 1, 0
    for i in range(n-1):
       temp = s
       s, s_1 = s+s_1, temp
       print(s)
0
ответ дан 18 December 2019 в 05:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: