ЧиÑла ФибонаÑÑи
ÐоÑледоваÑелÑноÑÑÑ ÑиÑел ФибонаÑÑи опÑеделÑеÑÑÑ ÑоÑмÑлой Fn = Fn-1 + Fn-2. То еÑÑÑ, ÑледÑÑÑее ÑиÑло полÑÑаеÑÑÑ ÐºÐ°Ðº ÑÑмма двÑÑ
пÑедÑдÑÑиÑ
.
ÐеÑвÑе два ÑиÑла ÑÐ°Ð²Ð½Ñ 1, заÑем 2(1+1), заÑем 3(1+2), 5(2+3) и Ñак далее: 1, 1, 2, 3, 5, 8, 13, 21....
ЧиÑла ФибонаÑÑи ÑеÑно ÑвÑÐ·Ð°Ð½Ñ Ñ Ð·Ð¾Ð»Ð¾ÑÑм ÑеÑением и множеÑÑвом пÑиÑоднÑÑ Ñвлений вокÑÑг наÑ.
ÐапиÑиÑе ÑÑнкÑÐ¸Ñ fib(n) коÑоÑÐ°Ñ Ð²Ð¾Ð·Ð²ÑаÑÐ°ÐµÑ n-е ÑиÑло ФибонаÑÑи.
ÐÑÐ¸Ð¼ÐµÑ ÑабоÑÑ:
function fib(n) { /* Ð²Ð°Ñ ÐºÐ¾Ð´ */ }
alert(fib(3)); // 2
alert(fib(7)); // 13
alert(fib(77)); // 5527939700884757
P.S. ÐÑе запÑÑки ÑÑнкÑий из пÑимеÑа вÑÑе Ð´Ð¾Ð»Ð¶Ð½Ñ ÑабоÑаÑÑ Ð±ÑÑÑÑо. ÐÑзов fib(77) должен занимаÑÑ Ð½Ðµ более доли ÑекÑндÑ.
СнаÑала ÑеÑим ÑеÑез ÑекÑÑÑиÑ.
ЧиÑла ФибонаÑÑи ÑекÑÑÑÐ¸Ð²Ð½Ñ Ð¿Ð¾ опÑеделениÑ:
function fib(n) {
return n <= 1 ? n : fib(n - 1) + fib(n - 2);
}
alert( fib(3) ); // 2
alert( fib(7) ); // 13
// fib(77); // вÑÑиÑлÑеÑÑÑ Ð¾ÑÐµÐ½Ñ Ð´Ð¾Ð»Ð³Ð¾
ÐÑи болÑÑиÑ
знаÑениÑÑ
n Ñакое ÑеÑение бÑÐ´ÐµÑ ÑабоÑаÑÑ Ð¾ÑÐµÐ½Ñ Ð´Ð¾Ð»Ð³Ð¾. ÐапÑимеÑ, fib(77) Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾Ð²ÐµÑиÑÑ Ð±ÑаÑÐ·ÐµÑ Ð½Ð° некоÑоÑое вÑемÑ, ÑÑев вÑе ÑеÑÑÑÑÑ Ð¿ÑоÑеÑÑоÑа.
ÐÑо поÑомÑ, ÑÑо ÑÑнкÑÐ¸Ñ Ð¿Ð¾ÑÐ¾Ð¶Ð´Ð°ÐµÑ Ð¾Ð±ÑиÑное деÑево вложеннÑÑ Ð²Ñзовов. ÐÑи ÑÑом ÑÑд знаÑений вÑÑиÑлÑеÑÑÑ Ð¼Ð½Ð¾Ð³Ð¾ Ñаз Ñнова и Ñнова.
ÐапÑимеÑ, поÑмоÑÑим на оÑÑÑвок вÑÑиÑлений Ð´Ð»Ñ fib(5):
...
fib(5) = fib(4) + fib(3)
fib(4) = fib(3) + fib(2)
...
ÐдеÑÑ Ð²Ð¸Ð´Ð½Ð¾, ÑÑо знаÑение fib(3) нÑжно одновÑеменно и Ð´Ð»Ñ fib(5) и Ð´Ð»Ñ fib(4). Ркоде оно бÑÐ´ÐµÑ Ð²ÑÑиÑлено два Ñаза, ÑовеÑÑенно незавиÑимо.
Ðолное деÑево ÑекÑÑÑии:
Ðожно замеÑиÑÑ, ÑÑо fib(3) вÑÑиÑлÑеÑÑÑ Ð´Ð²Ð°Ð¶Ð´Ñ, а fib(2) â ÑÑиждÑ. ÐбÑее колиÑеÑÑво вÑÑиÑлений ÑаÑÑÑÑ Ð½Ð°Ð¼Ð½Ð¾Ð³Ð¾ бÑÑÑÑее, Ñем n, ÑÑо Ð´ÐµÐ»Ð°ÐµÑ ÐµÐ³Ð¾ огÑомнÑм даже Ð´Ð»Ñ n=77.
Ðожно ÑÑо опÑимизиÑоваÑÑ, Ð·Ð°Ð¿Ð¾Ð¼Ð¸Ð½Ð°Ñ Ñже вÑÑиÑленнÑе знаÑениÑ: еÑли знаÑение, Ñкажем, fib(3) вÑÑиÑлено однаждÑ, заÑем Ð¼Ñ Ð¿ÑоÑÑо пеÑеиÑполÑзÑем ÑÑо знаÑение Ð´Ð»Ñ Ð¿Ð¾ÑледÑÑÑиÑ
вÑÑиÑлений.
ÐÑÑгим ваÑианÑом бÑло Ð±Ñ Ð¾ÑказаÑÑÑÑ Ð¾Ñ ÑекÑÑÑии и иÑполÑзоваÑÑ ÑовеÑÑенно дÑÑгой алгоÑиÑм на оÑнове Ñикла.
ÐмеÑÑо Ñого, ÑÑÐ¾Ð±Ñ Ð½Ð°ÑинаÑÑ Ñ n и вÑÑиÑлÑÑÑ Ð½ÐµÐ¾Ð±Ñ
одимÑе пÑедÑдÑÑие знаÑениÑ, можно напиÑаÑÑ Ñикл, коÑоÑÑй наÑнÑÑ Ñ 1 и 2, заÑем из ниÑ
полÑÑÐ¸Ñ fib(3) как иÑ
ÑÑммÑ, заÑем fib(4)как ÑÑÐ¼Ð¼Ñ Ð¿ÑедÑдÑÑиÑ
знаÑений, заÑем fib(5) и Ñак далее, до ÑиналÑного ÑезÑлÑÑаÑа. Ðа каждом Ñаге нам нÑжно помниÑÑ ÑолÑко знаÑÐµÐ½Ð¸Ñ Ð´Ð²ÑÑ
пÑедÑдÑÑиÑ
ÑиÑел поÑледоваÑелÑноÑÑи.
ÐÐ¾Ñ Ð´ÐµÑалÑнÑе Ñаги нового алгоÑиÑма.
ÐаÑало:
// a = fib(1), b = fib(2), ÑÑи знаÑÐµÐ½Ð¸Ñ Ð¿Ð¾ опÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ ÑÐ°Ð²Ð½Ñ 1
let a = 1, b = 1;
// полÑÑим c = fib(3) как иÑ
ÑÑммÑ
let c = a + b;
/* ÑепеÑÑ Ñ Ð½Ð°Ñ ÐµÑÑÑ fib(1), fib(2), fib(3)
a b c
1, 1, 2
*/
ТепеÑÑ Ð¼Ñ Ñ
оÑим полÑÑиÑÑ fib(4) = fib(2) + fib(3).
ÐеÑеÑÑавим пеÑеменнÑе: a,b, пÑиÑвоим знаÑÐµÐ½Ð¸Ñ fib(2),fib(3), Ñогда c можно полÑÑиÑÑ ÐºÐ°Ðº иÑ
ÑÑммÑ:
a = b; // ÑепеÑÑ a = fib(2)
b = c; // ÑепеÑÑ b = fib(3)
c = a + b; // c = fib(4)
/* имеем поÑледоваÑелÑноÑÑÑ:
a b c
1, 1, 2, 3
*/
СледÑÑÑий Ñаг даÑÑ Ð½Ð¾Ð²Ð¾Ðµ ÑиÑло поÑледоваÑелÑноÑÑи:
a = b; // now a = fib(3)
b = c; // now b = fib(4)
c = a + b; // c = fib(5)
/* поÑледоваÑелÑноÑÑÑ ÑепеÑÑ (на одно ÑиÑло болÑÑе):
a b c
1, 1, 2, 3, 5
*/
â¦Ð Ñак далее, пока не полÑÑим иÑкомое знаÑение. ÐÑо намного бÑÑÑÑее ÑекÑÑÑии и не ÑÑебÑÐµÑ Ð¿Ð¾Ð²ÑоÑнÑÑ Ð²ÑÑиÑлений.
ÐолнÑй код:
function fib(n) {
let a = 1;
let b = 1;
for (let i = 3; i <= n; i++) {
let c = a + b;
a = b;
b = c;
}
return b;
}
alert( fib(3) ); // 2
alert( fib(7) ); // 13
alert( fib(77) ); // 5527939700884757
Цикл наÑинаеÑÑÑ Ñ i=3, поÑÐ¾Ð¼Ñ ÑÑо пеÑвое и вÑоÑое знаÑÐµÐ½Ð¸Ñ Ð¿Ð¾ÑледоваÑелÑноÑÑи Ð·Ð°Ð´Ð°Ð½Ñ a=1, b=1.
Такой ÑпоÑоб назÑваеÑÑÑ Ð´Ð¸Ð½Ð°Ð¼Ð¸ÑеÑкое пÑогÑаммиÑование ÑÐ½Ð¸Ð·Ñ Ð²Ð²ÐµÑÑ .
