Contoh algoritma rekursif canggih

14

Saya sedang menjelaskan algoritma pemilihan waktu linear deterministik yang terkenal (median algoritma median) kepada seorang teman.

Rekursi dalam algoritma ini (walaupun sangat sederhana) cukup canggih. Ada dua panggilan rekursif, masing-masing dengan parameter berbeda.

Saya mencoba untuk menemukan contoh lain dari algoritma rekursif yang menarik, tetapi tidak dapat menemukannya. Semua algoritme rekursif yang dapat saya buat adalah rekursi ekor sederhana atau pembagian sederhana dan taklukkan (di mana kedua panggilan itu "sama").

Bisakah Anda memberikan beberapa contoh rekursi canggih?

elektronaj
sumber
Melintasi labirin atau lebih umum grafik dengan pencarian pertama-lebar adalah contoh sederhana dari rekursi yang menarik.
utdiscant, saya berpikir bahwa BFS tidak memenuhi syarat untuk pertanyaan saya, karena dapat dengan mudah dan alami diimplementasikan menggunakan antrian dan loop sementara.
elektronaj
Bagaimana dengan mundur dalam memecahkan teka-teki dan parsing? Dan Algoritma Ranking dan Unranking memiliki rekursi non-standar juga.
uli
Algoritma Memoisasi ?
Kaveh
2
@ vzn: Antrian tidak dapat menggantikan tumpukan. BFS adalah kasus khusus.
Raphael

Jawaban:

15

Perulangan favorit saya muncul dalam algoritma output-sensitif untuk komputasi lambung cembung, pertama oleh Kirkpatrick dan Seidel , tetapi kemudian diulang oleh yang lain. Misalkan menunjukkan waktu untuk menghitung lambung cembung dari n poin dalam pesawat, ketika lambung cembung memiliki h simpul. (Nilai h tidak diketahui sebelumnya, selain dari batasan sepele h n .) Algoritma Kirkpatrick dan Seidel menghasilkan rekurensi T ( n , h ) = { O ( n ) jika T(n,h)nhhhn jikan1,n23n/4dann1+n2=ndanh1+h2=h.

T(n,h)={HAI(n)jika n3 atau h3T(n1,h1)+T(n2,h2)+HAI(n)jika tidak
n1,n23n/4n1+n2=nh1+h2=h

Solusinya adalah . Ini sedikit mengejutkan, karena h bukan parameter yang dibagi secara merata. Tapi pada kenyataannya, terburuk kasus kekambuhan terjadi ketika h 1 dan h 2 keduanya sekitar jam / 2 ; jika entah bagaimana secara ajaib h 1 selalu konstan, solusinya adalah T ( n , h ) = O ( n ) .T(n,h)=HAI(ncatatanh)hh1h2h/2h1T(n,h)=HAI(n)

Saya menggunakan varian pengulangan ini di salah satu makalah topologi komputasi pertama saya : mana

T(n,g)={HAI(n)jika n3 atau g=0T(n1,g1)+T(n2,g2)+HAI(min{n1,n2})jika tidak
dan g 1 + g 2 = g . Sekali lagi, solusinya adalah O ( n log g ) , dankasusterburukterjadi ketika n dan g selalu dibagi secara merata.n1+n2=ng1+g2=gHAI(ncatatang)ng
JeffE
sumber
Saya memiliki masalah dengan kondisi "jika atau h = O ( 1 ) "; Apa yang dimaksud O di sini? Apakah ada konstanta yang terikat secara global yang n dan h harus dipotong untuk berakhir dalam kasus satu (dan penulis tidak repot-repot memberikannya). Karena jika saya membacanya secara literal (yaitu menafsirkan O ( 1 ) dengan cara yang sama dengan O ( n ) di baris yang sama), kasus dua tidak pernah atau selalu terjadi (saya bahkan tidak yakin). Penyalahgunaan notasi terlalu jauh, imho. n=O(1)h=O(1)OnhO(1)O(n)
Raphael
1
Maaf, saya sudah mengedit jawaban saya untuk menjelaskan. berarti "konstanta favorit Anda". Saya telah menggunakan 3 dalam revisi saya, tetapi 10 10 100 ! akan bekerja dengan baik juga. HAI(1)31010100!
JeffE
Bagaimana Anda menggambar diagram itu dalam makalah topologi komputasi?
user119264
12

Rekursi yang saya gunakan dalam makalah saya "Algoritma linear-waktu untuk menghitung diagram Voronoi dari poligon cembung" oleh Aggarwal et al juga cukup rumit.

Berikut adalah deskripsi algoritma dari makalah kami. Jika tidak jelas dari deskripsi, pada langkah 3 titik merah dipartisi menjadi titik merah dan garnet. Langkah 1, 3, dan 6 semuanya merupakan waktu linier. Kita juga tahu bahwa jika adalah jumlah total poin, | B | α n , | R | β n , dan | C | γ n untuk beberapa α , β , γ > 0 .n|B|αn|R|βn|C|γnα,β,γ>0

Saya akan memberi tahu Anda mengapa seluruh algoritma membutuhkan waktu linier.

  1. Partisi titik asli menjadi set biru dan merah B dan R.
  2. Secara rekursif menghitung lambung cembung dari titik biru.
  3. Dengan menggunakan struktur lambung biru, pilih titik merah C.
  4. Tambahkan poin crimson ke lambung biru satu per satu.
  5. Secara rekursif menghitung cembung titik garnet G.
  6. Gabungkan lambung garnet ini dengan lambung biru yang diperluas dari langkah 4.

Apa yang membuat algoritma linier adalah kemampuan untuk menambahkan fraksi tetap dari titik merah ke lambung biru dengan biaya konstan per titik. Poin yang ditambahkan adalah poin crimson.

T(n)=T(|B|)+T(|G|)+HAI(n)
|B||G||B|+|G|(1-γ)n
Peter Shor
sumber
7

Ada variasi pada rekurensi temuan median yang berasal dari rentang pencarian dengan setengah pesawat. Perulangan itu sendiri berbentuk

T(n)=T(n/2)+T(n/4)+cn
Suresh
sumber
1
Jawaban saya di sini ( cs.stackexchange.com/questions/332/… ) kebetulan memiliki pengulangan yang sama persis untuk waktu berjalan :)
Alex ten Brink
6

Ada banyak algoritma rekursif keren [1], [2] yang digunakan dalam prediksi struktur sekunder RNA. Jika dibiarkan sendiri, untaian RNA akan membentuk pasangan basa dengan dirinya sendiri; satu contoh yang relatif sederhana dari [3] menghitung jumlah maksimum basis berpasangan yang bersarang pada string RNA dengan sendirinya:

M(i,j)=maxik<jLmin{M(i,k1)+M(k+1,j1)+1M(i,j1)


  1. Lipat komputer optimal dari sekuens RNA besar menggunakan termodinamika dan informasi tambahan oleh M. Zuker, P. Stiegler (1981)

  2. Algoritma Pemrograman Dinamis untuk Prediksi Struktur RNA Termasuk Pseudoknots oleh E. Rivas, SR Eddy (1999)

  3. Algoritma cepat untuk memprediksi struktur sekunder RNA untai tunggal oleh R. Nussinov, AB Jacobson (1980)

rphv
sumber
Yang terkait diusulkan di sini cukup rumit karena olahraga tiga rekursi yang saling bergantung (pemrograman dinamis).
Raphael
4

Saya masih tidak benar-benar mengerti apa yang Anda maksud dengan "rekursi canggih". Misalnya, langkah rekursi dalam algoritma FFT canggih!

Tetapi jika Anda ingin mencari rekursi yang lebih rumit , maka rekursi bersama mungkin menjadi salah satu jawaban yang mungkin. Rekursi timbal balik berguna ketika bekerja dengan bahasa pemrograman fuctional . Rekursi timbal balik adalah fitur kunci dari parser keturunan rekursif .

Dai
sumber
Nah, rekursi dalam FFT (bentuk paling sederhana dari Cooley-Tukey) adalah membagi dan menaklukkan "standar". Ini terlihat dari kompleksitas O (nlogn). 2 panggilan rekursif (1 untuk genap, 1 untuk peluang) agak "sama".
elektronaj
3

Dari atas kepala saya, fungsi McCarthy 91

F(N) = 
    n - 100    if n > 100
    F(F(n+11)) if n <= 100

dan fungsi Ackermann

A(m, n) = 
    n + 1             if m = 0
    A(m-1, 1)         if m > 0 and n = 0
    A(m-1, A(m, n-1)) if m > 0 and n > 0

mungkin dianggap sebagai offbeat, meskipun toy-ish, fungsi rekursif.

hugomg
sumber