RECURSIVE ALGORITM
(DIVIDE & CONQUER)
• Əliyev İsmayıl
CƏDVƏL
 Divide & Conquer Strategiyası
 Recursion nədir?
 Rekursiv metodların əhəmiyyəti nədir və nə üçün istifadə
edilir?
 Rekursiv metodların müsbət və mənfi tərəfləri
 Tail recursion və non-tail recursion
 Bəzi məsələlərin Recursive metodla həlli
DIVIDE & CONQUER STRATEGIYASI
Komputer
elmlərində
çox-budaqlı
rekursiyaya
əsaslanan
çox vacib
bir
strategiyadır
Problem 2 və daha çox
olan kiçik alt-
problemlərə bölünür
Bu kiçik problemlər
ayrılıqda həll edilir
Ümumi həllin alınması üçün
bu həllər sonda birləşdirilir
Divide and conquer texnikası:
 Merge Sort
 Quick Sort
 Binary Search
 Strassen's
MatrixMultiplication
 Closest pair (points)
kimi problemlərin həlli üçün
olan algortimlərin əsasını təşkil
edir
5
/* Solve a problem P */
Solve(P){
/* Base case(s) */
if P is a base case problem
return the solution immediately
/* Divide P into P1, P2, ..Pn each of smaller scale (n>=2) */
/* Solve subproblems recursively */
S1 = Solve(P1); /* Solve P1 recursively to obtain S1 */
S2 = Solve(P2); /* Solve P2 recursively to obtain S2 */
…
Sn = Solve(Pn); /* Solve Pn recursively to obtain Sn */
/* Merge the solutions to subproblems */
/* to get the solution to the original big problem */
S = Merge(S1, S2, …, Sn);
/* Return the solution */
return S;
} //end-Solve
RECURSION NƏDIR?
Programlaşdırmada funksiyalar 2-cür yazıla bilər:
 İteratif
 Recursive
İteretif funksiyalar əməliyyatı tək addımda edər və nəticəni ekrana
qaytarar.Recursive funksiya isə öz-özünü təkrar təkrar çağıran bir
funksiyadır
Rekursiv funksiya döngüyə oxşayır onun kimi sonsuza
qədər davam edə bilər.Bunun qarşısını almaq üçün Rekursiv
funksiylarda 3 təməl ünsür nəzərə alınmalıdır Bunlar:-
Başlanğıc
AddımBitiş dəyərləridir
REKURSIV METODLARIN ƏHƏMIYYƏTI
NƏDIR, NƏ ÜÇÜN ISTIFADƏ EDILIR?
Bəzi alqoritmlər quruluş baxımından rekursiv struktura
çox yaxındır və onların rekursiv metodlar istifadə
olunaraq kodlaşdırılması həm rahat, həm də oxunaqlılıq
baxımından anlaşıqlıdır. Həmçinin rekursiya
əsasən “divide and conquer” yanaşması tətbiq edilən
alqoritmlərdə istifadə olunur ki, bunlardan da ən
klassiki Merge Sort alqoritmidir.
Rekursiv metodların müsbət və mənfi tərəfləri
Müsbət:
Daha az kodla və daha anlaşıqlı şəkildə problemi həll etmək mümkündür.
Mənfi:
Rekursiv metodlar stack yaddaş istifadə edir və stack yaddaşın həcmi
limitlidir. Rekursiv çağrıların sayı çox olarsa, stack yaddaş dola
və StackOverflowError baş verə bilər. Həmçinin rekursiyanın bitməsini
bildirən şərti təyin edərkən də diqqətli olmaq lazımdır, şərt düzgün təyin
edilməzsə, rekursiya tamamlanmaya və nəticədə
yenə StackOverflowError baş verə bilər.
TAIL RECURSION VƏ NON-TAIL RECURSION
Bəs metodun tail recursion yaxud non-tail recursion
olmasının nə önəmi var?
Əgər rekursiv çağrı metodun sonuncu sətrində olarsa və həmin
sətirdə başqa heç bir əməliyyat olmazsa, bu “tail recursion”,
digər hallarda isə “non-tail recursion” adlanır.
Tail recursion performans baxımından non-tail recursion-dan
daha yaxşıdır.Çünki modern kompilyatorlar tail recursion-u
təyin edə və kodu optimallaşdıra bilirlər.Tail recursionun əsas
özəlliyi odur ki, dəyərlərin stack yaddaşa əlavə edilməsinə
ehtiyac yoxdur. Bu səbəbdən də yaddaşa və vaxta qənaət edilir
RECURSION TREE FOR POWER(3, 4)
12
/* Computes a^n */
double Power(double a, int n){
/* Base cases */
if (n == 0) return 1;
else if (n == 1) return a;
return a * Power(a, n-1);
} /* end-Power */
main(String args[]){
double x;
x = Power(3, 4);
} /* end-main */
Power(3,4)
x=Power(3,4)
main
return 3*Power(3,3)
Power(3,3)
return 3*Power(3,2)
Power(3,2)
return 3*Power(3,1)
Power(3,1)
return 3
=9
=27
return 9
=81
return 27
=81
return 81
BƏZI MƏSƏLƏLƏRIN RECURSIVE
METODLA HƏLLI
main
---- printArtan (10)
---- printArtan (9)
---- printArtan (8)
---- printArtan (7)
---- printArtan (6)
---- printArtan (5)
---- printArtan (4)
---- printArtan (3)
---- printArtan (2)
---- printArtan (1)
---------------------------------- Rekursiyanin sonu
---- Çapet 1
---- Çapet 2
---- Çapet 3
---- Çapet 4
---- Çapet 5
---- Çapet 6
---- Çapet 7
---- Çapet 8
---- Çapet 9
---- Çapet 10
Sizcə yuxarıdakı PrintArtan
metodunda tail Recursion var
idi Yoxsa non-tail-Recursion?
Tail Yoxsa non Tail-Recursion ?
Yuxarıdakı məslənin bunun kimi digər məsələlərin Recursive methodla həlli
tamamən stack yaddaş ilə əlaqəli məsələdir. Metod rekursiv olaraq təkrar-təkrar
çağırıldıqca həmin metoda ötürülən parametrlər stack yaddaşa əlavə edilir.
Rekursiya bitdikdən sonra həmin parametrlərə müraciət edildikdə isə stack`ə ən son
əlavə edilən ən birinci çağırılır
Fikirləşinki, siz stolun üstünə kitablarınızı bir-bir üst-üstə yığmağa başlayırsınız.
Sonra stolun üzərindən bir-bir götürüb rəfə qoyursunuz. Kitablarınızı götürərkən
qoyduğunuz ardıcıllığın tam tərsi baş verir. İlk qoyduğunuz kitablar altlarda qalır,
son qoyduğunuz kitablar isə üstlərdə. Və beləliklə əvvəlcə son qoyduğunuz
kitabları və sonda isə ilk qoyduğunuz kitabları götürürsünüz
Yəni, bir sözlə stack öz işində LIFO (last-in, first-out) siyasətini tətbiq edir
F(5)
F(4)+F(3)
F(4)
F(3)+F(2)
F(3)
F(2)+F(1)
F(2)
F(1)+F(0)
F(1) F(0)
01
1 1
F(1)
F(1)+F(0)
F(1) F(0)
01
F(2)+F(1)
F(2)
F(1)+F(0)
F(1) F(0)
01
1 1
F(1)F(2)
2
1
3
F(3)
2
5
Yazdiğımız kodlarda yaddaş və
zaman arasında tradeoff
vardır.Yəni ya vaxtda udub
yaddaşda itirəcik
yadaki yaddaşda udub zamanda
itirəcik.yazdığımız bu kod nə
qədər sadə görünsədə zaman və
yaddaş itkisinə səbəb olur
20
TƏŞƏKKÜRLƏR

Recursive Algorithm (in Azerbaijani)

  • 1.
    RECURSIVE ALGORITM (DIVIDE &CONQUER) • Əliyev İsmayıl
  • 2.
    CƏDVƏL  Divide &Conquer Strategiyası  Recursion nədir?  Rekursiv metodların əhəmiyyəti nədir və nə üçün istifadə edilir?  Rekursiv metodların müsbət və mənfi tərəfləri  Tail recursion və non-tail recursion  Bəzi məsələlərin Recursive metodla həlli
  • 3.
    DIVIDE & CONQUERSTRATEGIYASI Komputer elmlərində çox-budaqlı rekursiyaya əsaslanan çox vacib bir strategiyadır Problem 2 və daha çox olan kiçik alt- problemlərə bölünür Bu kiçik problemlər ayrılıqda həll edilir Ümumi həllin alınması üçün bu həllər sonda birləşdirilir
  • 4.
    Divide and conquertexnikası:  Merge Sort  Quick Sort  Binary Search  Strassen's MatrixMultiplication  Closest pair (points) kimi problemlərin həlli üçün olan algortimlərin əsasını təşkil edir
  • 5.
    5 /* Solve aproblem P */ Solve(P){ /* Base case(s) */ if P is a base case problem return the solution immediately /* Divide P into P1, P2, ..Pn each of smaller scale (n>=2) */ /* Solve subproblems recursively */ S1 = Solve(P1); /* Solve P1 recursively to obtain S1 */ S2 = Solve(P2); /* Solve P2 recursively to obtain S2 */ … Sn = Solve(Pn); /* Solve Pn recursively to obtain Sn */ /* Merge the solutions to subproblems */ /* to get the solution to the original big problem */ S = Merge(S1, S2, …, Sn); /* Return the solution */ return S; } //end-Solve
  • 6.
    RECURSION NƏDIR? Programlaşdırmada funksiyalar2-cür yazıla bilər:  İteratif  Recursive İteretif funksiyalar əməliyyatı tək addımda edər və nəticəni ekrana qaytarar.Recursive funksiya isə öz-özünü təkrar təkrar çağıran bir funksiyadır
  • 7.
    Rekursiv funksiya döngüyəoxşayır onun kimi sonsuza qədər davam edə bilər.Bunun qarşısını almaq üçün Rekursiv funksiylarda 3 təməl ünsür nəzərə alınmalıdır Bunlar:- Başlanğıc AddımBitiş dəyərləridir
  • 8.
    REKURSIV METODLARIN ƏHƏMIYYƏTI NƏDIR,NƏ ÜÇÜN ISTIFADƏ EDILIR? Bəzi alqoritmlər quruluş baxımından rekursiv struktura çox yaxındır və onların rekursiv metodlar istifadə olunaraq kodlaşdırılması həm rahat, həm də oxunaqlılıq baxımından anlaşıqlıdır. Həmçinin rekursiya əsasən “divide and conquer” yanaşması tətbiq edilən alqoritmlərdə istifadə olunur ki, bunlardan da ən klassiki Merge Sort alqoritmidir.
  • 10.
    Rekursiv metodların müsbətvə mənfi tərəfləri Müsbət: Daha az kodla və daha anlaşıqlı şəkildə problemi həll etmək mümkündür. Mənfi: Rekursiv metodlar stack yaddaş istifadə edir və stack yaddaşın həcmi limitlidir. Rekursiv çağrıların sayı çox olarsa, stack yaddaş dola və StackOverflowError baş verə bilər. Həmçinin rekursiyanın bitməsini bildirən şərti təyin edərkən də diqqətli olmaq lazımdır, şərt düzgün təyin edilməzsə, rekursiya tamamlanmaya və nəticədə yenə StackOverflowError baş verə bilər.
  • 11.
    TAIL RECURSION VƏNON-TAIL RECURSION Bəs metodun tail recursion yaxud non-tail recursion olmasının nə önəmi var? Əgər rekursiv çağrı metodun sonuncu sətrində olarsa və həmin sətirdə başqa heç bir əməliyyat olmazsa, bu “tail recursion”, digər hallarda isə “non-tail recursion” adlanır. Tail recursion performans baxımından non-tail recursion-dan daha yaxşıdır.Çünki modern kompilyatorlar tail recursion-u təyin edə və kodu optimallaşdıra bilirlər.Tail recursionun əsas özəlliyi odur ki, dəyərlərin stack yaddaşa əlavə edilməsinə ehtiyac yoxdur. Bu səbəbdən də yaddaşa və vaxta qənaət edilir
  • 12.
    RECURSION TREE FORPOWER(3, 4) 12 /* Computes a^n */ double Power(double a, int n){ /* Base cases */ if (n == 0) return 1; else if (n == 1) return a; return a * Power(a, n-1); } /* end-Power */ main(String args[]){ double x; x = Power(3, 4); } /* end-main */ Power(3,4) x=Power(3,4) main return 3*Power(3,3) Power(3,3) return 3*Power(3,2) Power(3,2) return 3*Power(3,1) Power(3,1) return 3 =9 =27 return 9 =81 return 27 =81 return 81
  • 13.
  • 15.
    main ---- printArtan (10) ----printArtan (9) ---- printArtan (8) ---- printArtan (7) ---- printArtan (6) ---- printArtan (5) ---- printArtan (4) ---- printArtan (3) ---- printArtan (2) ---- printArtan (1) ---------------------------------- Rekursiyanin sonu ---- Çapet 1 ---- Çapet 2 ---- Çapet 3 ---- Çapet 4 ---- Çapet 5 ---- Çapet 6 ---- Çapet 7 ---- Çapet 8 ---- Çapet 9 ---- Çapet 10 Sizcə yuxarıdakı PrintArtan metodunda tail Recursion var idi Yoxsa non-tail-Recursion?
  • 16.
    Tail Yoxsa nonTail-Recursion ?
  • 17.
    Yuxarıdakı məslənin bununkimi digər məsələlərin Recursive methodla həlli tamamən stack yaddaş ilə əlaqəli məsələdir. Metod rekursiv olaraq təkrar-təkrar çağırıldıqca həmin metoda ötürülən parametrlər stack yaddaşa əlavə edilir. Rekursiya bitdikdən sonra həmin parametrlərə müraciət edildikdə isə stack`ə ən son əlavə edilən ən birinci çağırılır Fikirləşinki, siz stolun üstünə kitablarınızı bir-bir üst-üstə yığmağa başlayırsınız. Sonra stolun üzərindən bir-bir götürüb rəfə qoyursunuz. Kitablarınızı götürərkən qoyduğunuz ardıcıllığın tam tərsi baş verir. İlk qoyduğunuz kitablar altlarda qalır, son qoyduğunuz kitablar isə üstlərdə. Və beləliklə əvvəlcə son qoyduğunuz kitabları və sonda isə ilk qoyduğunuz kitabları götürürsünüz Yəni, bir sözlə stack öz işində LIFO (last-in, first-out) siyasətini tətbiq edir
  • 19.
    F(5) F(4)+F(3) F(4) F(3)+F(2) F(3) F(2)+F(1) F(2) F(1)+F(0) F(1) F(0) 01 1 1 F(1) F(1)+F(0) F(1)F(0) 01 F(2)+F(1) F(2) F(1)+F(0) F(1) F(0) 01 1 1 F(1)F(2) 2 1 3 F(3) 2 5 Yazdiğımız kodlarda yaddaş və zaman arasında tradeoff vardır.Yəni ya vaxtda udub yaddaşda itirəcik yadaki yaddaşda udub zamanda itirəcik.yazdığımız bu kod nə qədər sadə görünsədə zaman və yaddaş itkisinə səbəb olur
  • 20.
  • 22.