Rekursiv algoritmning murakkabligini hisoblash ko’pincha juda murakkab. Hattoki, ba’zan to’g’ri yechimni yozishning o’zi ham kam bo’lib qolishi mumkin. Chunki, uni iterativ yechim bilan solishtirishda uning murakkabligini hisoblash kerak bo’ladi. Rekursiv algoritmlarda bu ko’pincha juda murakkab va yaxshigina matematika talab qiladi
Keling quyidagi misolda rekursiyani asimptotik tahlil qilamiz
T(1) = 1, (*)
T(n) = 1 + T(n/2), when n > 1. (**)
(**) tenglama funktsiyaning doimiy ish olib borishini (ya'ni bitta) va n / 2 kattalikdagi bitta rekursiv chaqiruvni qabul qilishini hisobga oladi.
(Aslida, n / 2 + 1 elementlarga ega bo'lishi ham mumkin. Biz bundan xavotirlanmaymiz, chunki biz asimptotik taxminlarni qidirmoqdamiz.)
Yana bir bor, takroriy almashtirish orqali echimni topish mumkin.
T(n) = (**)
1 + T(n/2) = (**)
1 + (1 + T(n/4)) = 2 + T(n/4) = (**)
2 + (1 + T(n/8)) = 3 + T(n/8) = ...
k + T(n/2k) = ...
log n + T(n/2log n) = log n + T(1) = (*)
log n + 1 = Θ(log n).
Magistr teoremasi rekursiv algoritmlarni tahlil qilganda tez-tez paydo bo'ladigan takrorlanish munosabatlari sinfi uchun assimptomatik baho beradigan retsepti.
A ≥ 1 va b> 1 turg'unlik bo'lsin, f (n) funktsiya bo'lsin, T (n) esa qaytarilish bilan aniqlangan musbat sonlar ustida funktsiya bo'lsin.
T(n) = aT(n/b) + f(n).
If f(n) = Θ(nd), where d ≥ 0, then
T(n) = Θ(nd) if a < bd,
T(n) = Θ(ndlog n) if a = bd,
T(n) = Θ(nlogba) if a > bd.
Biz isbotni o'tkazib yuboramiz. Bu qiyin emas, lekin uzoq. Aslida, siz avvalgi misollardagi kabi takroriy almashtirishdan foydalanishingiz mumkin.
Bosh teorema ikkilik izlash misolida takrorlanishning to'g'ri echimini topishini tekshirib ko'raylik. Bu holda a = 1, b = 2 va f (n) = 1. funktsiyasi shundan dalolat beradiki, f (n) = Θ (n0), ya'ni d = 0. A = bd ekanligini ko'ramiz va undan foydalanishimiz mumkin. xulosa qilish uchun bosh teoremaning ikkinchi o'qi
T(n) = Θ(n0log n),
Birinchi funktsiya asosiy holatga kelguncha n marta rekursiv ravishda chaqiriladi, shuning uchun uning O (n) chizig'i ko'pincha chiziqli deb nomlanadi.
Ikkinchi funktsiya har safar n-5 deb nomlanadi, shuning uchun funktsiyani chaqirishdan oldin n dan beshtani ajratamiz, ammo n-5 ham O (n) dir. (Aslida n / 5 marta deyiladi. Va O (n / 5) = O (n)).
Bu funktsiya log (n) baza 5 dir, har safar funktsiyani chaqirishdan oldin 5 ga bo'lamiz, shuning uchun uni O (log (n)) (5-sonli), ko'pincha logaritmik deb nomlanadi va ko'pincha Katta O notasi va murakkablik tahlili 2-bazadan foydalanadi. .
To'rtinchidan, u O (2 ^ n) yoki eksponentdir, chunki har bir funktsiya ikki marta takrorlanadi, agar u n marta takrorlanmagan bo'lsa.
Oxirgi funktsiyaga kelsak, nolga teng bo'lmagan n 2 qiymatni qabul qilamiz, chunki biz 2 ga ko'payyapmiz va rekursiya n-5 ga teng, va bu tsikl rekursiv deb nomlanadi, shuning uchun vaqt murakkabligi (n-5) * (n / 2) = (2n-10) * n = 2n ^ 2- 10n, asimptotik xatti-harakatlar va eng yomon holatlar stsenariylari yoki katta O tomon intilayotgan yuqori chegara tufayli biz faqat eng katta atamani bilamiz, shuning uchun O (n) ^ 2).
int recursiveFun1(int n)
{
if (n <= 0)
return 1;
else
return 1 + recursiveFun1(n-1);
}
int recursiveFun2(int n)
{
if (n <= 0)
return 1;
else
return 1 + recursiveFun2(n-5);
}
int recursiveFun3(int n)
{
if (n <= 0)
return 1;
else
return 1 + recursiveFun3(n/5);
}
void recursiveFun4(int n, int m, int o)
{
if (n <= 0)
{
printf("%d, %d\n",m,o);
}
else
{
recursiveFun4(n-1, m+1, o);
recursiveFun4(n-1, m, o+1);
}
}
int recursiveFun5(int n)
{
for (i = 0; i < n; i += 2) {
}
if (n <= 0)
return 1;
else
return 1 + recursiveFun5(n-5);
}
11-java faylida rekursiv funksiyaga misol keltirilgan
Do'stlaringiz bilan baham: |