Если я правильно понимаю, что вам нужно сделать (вместо того, чтобы писать из первых п чисел Фибоначчей) заключается в определении того, является ли n - числом Фибоначчи.
Поэтому вы должны изменить свой метод, чтобы продолжать генерировать последовательность Фибоначчи, пока не получите число> = n. Если он равен, n - номер Фибоначчи, в противном случае нет.
public static void main(String[] args) {
measureExecutionTimeForGeneratorAlgorithm(1);
measureExecutionTimeForFormulaAlgorithm(1);
measureExecutionTimeForGeneratorAlgorithm(10);
measureExecutionTimeForFormulaAlgorithm(10);
measureExecutionTimeForGeneratorAlgorithm(100);
measureExecutionTimeForFormulaAlgorithm(100);
measureExecutionTimeForGeneratorAlgorithm(1000);
measureExecutionTimeForFormulaAlgorithm(1000);
measureExecutionTimeForGeneratorAlgorithm(10000);
measureExecutionTimeForFormulaAlgorithm(10000);
measureExecutionTimeForGeneratorAlgorithm(100000);
measureExecutionTimeForFormulaAlgorithm(100000);
measureExecutionTimeForGeneratorAlgorithm(1000000);
measureExecutionTimeForFormulaAlgorithm(1000000);
measureExecutionTimeForGeneratorAlgorithm(10000000);
measureExecutionTimeForFormulaAlgorithm(10000000);
measureExecutionTimeForGeneratorAlgorithm(100000000);
measureExecutionTimeForFormulaAlgorithm(100000000);
measureExecutionTimeForGeneratorAlgorithm(1000000000);
measureExecutionTimeForFormulaAlgorithm(1000000000);
measureExecutionTimeForGeneratorAlgorithm(2000000000);
measureExecutionTimeForFormulaAlgorithm(2000000000);
}
static void measureExecutionTimeForGeneratorAlgorithm(int x) {
final int count = 1000000;
final long start = System.nanoTime();
for (int i = 0; i < count; i++) {
isFibByGeneration(x);
}
final double elapsedTimeInSec = (System.nanoTime() - start) * 1.0e-9;
System.out.println("Running generator algorithm " + count + " times for " + x + " took " +elapsedTimeInSec + " seconds");
}
static void measureExecutionTimeForFormulaAlgorithm(int x) {
final int count = 1000000;
final long start = System.nanoTime();
for (int i = 0; i < count; i++) {
isFibByFormula(x);
}
final double elapsedTimeInSec = (System.nanoTime() - start) * 1.0e-9;
System.out.println("Running formula algorithm " + count + " times for " + x + " took " +elapsedTimeInSec + " seconds");
}
static boolean isFibByGeneration(int x) {
int a=0;
int b=1;
int f=1;
while (b < x){
f = a + b;
a = b;
b = f;
}
return x == f;
}
private static boolean isFibByFormula(int num) {
double first = 5 * Math.pow((num), 2) + 4;
double second = 5 * Math.pow((num), 2) - 4;
return isWholeNumber(Math.sqrt(first)) || isWholeNumber(Math.sqrt(second));
}
private static boolean isWholeNumber(double num) {
return num - Math.round(num) == 0;
}
Результаты удивили даже меня:
Running generator algorithm 1000000 times for 1 took 0.007173537000000001 seconds
Running formula algorithm 1000000 times for 1 took 0.223365539 seconds
Running generator algorithm 1000000 times for 10 took 0.017330694 seconds
Running formula algorithm 1000000 times for 10 took 0.279445852 seconds
Running generator algorithm 1000000 times for 100 took 0.030283179 seconds
Running formula algorithm 1000000 times for 100 took 0.27773557800000004 seconds
Running generator algorithm 1000000 times for 1000 took 0.041044322 seconds
Running formula algorithm 1000000 times for 1000 took 0.277931134 seconds
Running generator algorithm 1000000 times for 10000 took 0.051103143000000004 seconds
Running formula algorithm 1000000 times for 10000 took 0.276980175 seconds
Running generator algorithm 1000000 times for 100000 took 0.062019335 seconds
Running formula algorithm 1000000 times for 100000 took 0.276227007 seconds
Running generator algorithm 1000000 times for 1000000 took 0.07422898800000001 seconds
Running formula algorithm 1000000 times for 1000000 took 0.275485013 seconds
Running generator algorithm 1000000 times for 10000000 took 0.085803922 seconds
Running formula algorithm 1000000 times for 10000000 took 0.27701090500000003 seconds
Running generator algorithm 1000000 times for 100000000 took 0.09543419600000001 seconds
Running formula algorithm 1000000 times for 100000000 took 0.274908403 seconds
Running generator algorithm 1000000 times for 1000000000 took 0.10683704200000001 seconds
Running formula algorithm 1000000 times for 1000000000 took 0.27524084800000004 seconds
Running generator algorithm 1000000 times for 2000000000 took 0.13019867100000002 seconds
Running formula algorithm 1000000 times for 2000000000 took 0.274846384 seconds
Короче говоря, алгоритм генератора путь обгоняет решение на основе формулы на всех положительных ИНТ значений - даже близко к максимальное значение int больше, чем в два раза быстрее! Так много для веры на основе оптимизации производительности ;-)
Для записи, модифицирующих приведенный выше код, чтобы использовать long
переменные вместо int
, алгоритм генератора (теперь, как и следовало ожидать, так как он должен сложить long
значения) становится медленнее , и точка пересечения, где формула начинает быть быстрее, составляет около 1000000000000L, то есть 10 .
Update2: Как IVlad и Морон отметило, я не совсем эксперта в области вычислений с плавающей точкой :-) на основе их предложения, которые я улучшил формулу следующим образом:
private static boolean isFibByFormula(long num)
{
double power = (double)num * (double)num;
double first = 5 * power + 4;
double second = 5 * power - 4;
return isWholeNumber(Math.sqrt(first)) || isWholeNumber(Math.sqrt(second));
}
Это обрушило выработанное точка прибл. 10 (для версии long
- генератор с int
все еще быстрее для всех значений int).Несомненно, что замена звонков sqrt
с помощью чего-то вроде предложенного @Moron еще больше снизит точку перехода.
Моей точкой (и IVlad's) было просто, что всегда будет точка пересечения, ниже которой алгоритм генератора будет быстрее. Поэтому утверждения о том, что один из них лучше работает, не имеют никакого значения вообще, только в контексте.
Что именно вы пытаетесь сделать? получить n-й номер фибоначчи? получить следующее число фибоначчи, которое больше n? выяснить, является ли n числом фибоначчи? – shoosh
См. Http://stackoverflow.com/questions/2432669/test-if-a-number-is-fibonacci. – kennytm
Ничего себе, глядя на комментарии, есть много аргументов, по которым решение лучше всего с алгоритмической точки зрения. Но помните, что это домашнее задание, и, судя по коду, это не совсем продвинутый курс алгоритмов. Скорее всего, это самый простой код для понимания *. @Emily, ваш инструктор дал вам какое-либо руководство относительно того, как вы должны решить эту проблему? –