Я думаю, что важная часть программы расходуется на неэффективные вычисления.
Вы профилировали свой код? Как общий принцип, не оптимизируйте преждевременно; измерить, какие части замедляют его. Таким образом, когда вы пытаетесь оптимизировать, вы можете сказать, помогла оптимизация или помешала (часто хорошая звуковая оптимизация ухудшит ее работу; как, например, компилятор не сможет выполнить оптимизацию, или вы не сможете использовать свой метод оптимизации). регистры / кэш процессора как оптимально).
Если это то, что вас тормозит, я бы сделал то же самое, что и отличное решение Пенга, но предварительно вычислил все числа Фибоначчи до вашего наибольшего значения и сохранил их в массив, индексированный соответствующей экспозицией (n) из закрытого form (phi^**n - (1-phi)**n)/sqrt(5)
. Его метод будет неправильно вычислять числа Фибоначчи для больших n с арифметикой с плавающей запятой; если только вы не используете произвольную высокую точность (что является медленным). Таким образом, ваш начальный массив равен fib_array = [0,1,1,2,3,5,8,13,... ]
. Затем пренебрегая небольшим членом (1-phi)**n
, инвертируйте fib, чтобы найти n (например, fib_inv
Пенга), и возьмите fib_array[n]
в качестве первой границы. Если эта граница меньше (больше) вашего значения, вы нашли нижнюю (верхнюю) границу и так другая граница должна быть fib_array[n+1]
(fib_array[n-1]
).
Или, если вы хотите вычислить его, используйте что-то из заданного N, которое лучше, чем формула Бине. http://en.literateprograms.org/Fibonacci_numbers_%28Python%29
Лично я бы удостоверился, что вторая граница находится на противоположной стороне термина от первой границы (в редких случаях, когда мы не должны были пренебрегать термином (1-phi)**n
; вы могли бы сделать к другому поиску, видя, ограничен ли термин, например, fib_array[n+1]
и fib_array[n+2]
). (Эта проверка может быть излишней; но сначала вам нужно будет это доказать, и одно дополнительное сравнение для обеспечения безопасности, похоже, стоит в моей книге).