Saya memiliki Midterm Ilmu Komputer besok dan saya perlu bantuan menentukan kompleksitas fungsi rekursif ini. Saya tahu bagaimana menyelesaikan kasus-kasus sederhana, tetapi saya masih mencoba belajar bagaimana menyelesaikan kasus-kasus sulit ini. Ini hanya beberapa contoh masalah yang saya tidak tahu. Bantuan apa pun akan sangat dihargai dan akan sangat membantu dalam studi saya, Terima kasih!
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) {
// do something
}
if (n <= 0)
return 1;
else
return 1 + recursiveFun5(n-5);
}
recursion
big-o
complexity-theory
Michael_19
sumber
sumber
Jawaban:
Kompleksitas waktu, dalam notasi O Besar, untuk setiap fungsi, adalah dalam urutan numerik:
O(n)
sering disebut linier .O(n)
. (Sebenarnya disebut urutan n / 5 kali. Dan, O (n / 5) = O (n)).O(log(n))
(basis 5), sering disebut logaritmik dan paling sering notasi O Besar dan analisis kompleksitas menggunakan basis 2.O(2^n)
, atau eksponensial , karena masing-masing panggilan fungsi panggilan itu sendiri dua kali kecuali telah berulang n kali.Sedangkan untuk fungsi terakhir, for loop membutuhkan n / 2 karena kita meningkat 2, dan rekursi mengambil n-5 dan karena for loop disebut secara rekursif karena itu kompleksitas waktu dalam (n-5) * (n / 2) = (2n-10) * n = 2n ^ 2- 10n, karena perilaku asimptotik dan pertimbangan skenario terburuk atau batas atas yang diperjuangkan oleh O besar, kami hanya tertarik pada istilah terbesar sehingga
O(n^2)
.Semoga berhasil di ujian tengah semester Anda;)
sumber
n/2
iterasi darifor
loop, mengapa pengurangan 5 tidak menghasilkann/5
panggilan rekursif? Ini masih akan menghasilkanO(n^2)
tetapi sepertinya penjelasan yang lebih intuitif. Mengapa mencampur pengurangan dan pembagian ketika mereka penting melakukan hal yang sama?n/5
tidakn-5
. Dan pada akhirnya, keseluruhan akan menjadiO(N^2)
.Untuk kasus di mana
n <= 0
,T(n) = O(1)
. Oleh karena itu, kompleksitas waktu akan tergantung pada kapann >= 0
.Kami akan mempertimbangkan kasus ini
n >= 0
di bagian di bawah ini.1.
di mana a adalah konstanta.
Dengan induksi:
di mana a, b adalah beberapa konstanta.
2.
di mana a adalah konstanta
Dengan induksi:
di mana a, b adalah beberapa konstanta dan k <= 0
3.
di mana a adalah konstanta
Dengan induksi:
di mana a, b adalah beberapa konstanta
4.
di mana a adalah konstanta
Dengan induksi:
di mana a, b adalah beberapa konstanta.
5.
di mana n adalah konstanta
Tulis ulang di
n = 5q + r
mana q dan r adalah bilangan bulat dan r = 0, 1, 2, 3, 4Kami sudah
q = (n - r) / 5
, dan karena r <5, kami dapat menganggapnya konstan, jadiq = O(n)
Dengan induksi:
Sejak r <4, kita dapat menemukan beberapa konstanta b sehingga
b >= T(r)
sumber
Salah satu cara terbaik yang saya temukan untuk memperkirakan kompleksitas algoritma rekursif adalah menggambar pohon rekursi. Setelah Anda memiliki pohon rekursif:
n
dan jumlah simpul daun1
sehingga kompleksitasnyan*1 = n
Fungsi kedua akan memiliki panjang
n/5
dan jumlah node daun lagi1
sehingga kompleksitasnyan/5 * 1 = n/5
. Itu harus diperkirakann
Untuk fungsi ketiga, karena
n
dibagi dengan 5 pada setiap panggilan rekursif, panjang pohon rekursif akanlog(n)(base 5)
, dan jumlah node daun lagi 1 sehingga kompleksitas akan menjadilog(n)(base 5) * 1 = log(n)(base 5)
Untuk fungsi keempat karena setiap simpul akan memiliki dua simpul anak, jumlah simpul daun akan sama dengan
(2^n)
dan panjang pohon rekursif akann
sangat rumit(2^n) * n
. Tetapi karenan
tidak signifikan di depan(2^n)
, itu dapat diabaikan dan kompleksitas hanya dapat dikatakan demikian(2^n)
.Untuk fungsi kelima, ada dua elemen yang memperkenalkan kompleksitas. Kompleksitas diperkenalkan oleh sifat fungsi rekursif dan kompleksitas yang diperkenalkan oleh
for
loop di setiap fungsi. Melakukan perhitungan di atas, kompleksitas yang diperkenalkan oleh sifat fungsi rekursif akan~ n
dan kompleksitas karena untuk loopn
. Total kompleksitas akan menjadin*n
.Catatan: Ini adalah cara penghitungan kompleksitas yang cepat dan kotor (tidak ada yang resmi!). Senang mendengar tanggapan tentang ini. Terima kasih.
sumber
2^n
maka tinggi pohon harusn
, bukanlog n
. Ketinggiannya hanyalog n
jikan
mewakili jumlah total node dalam pohon. Tapi ternyata tidak.Kita dapat membuktikannya secara matematis yang merupakan sesuatu yang saya lewatkan dalam jawaban di atas.
Ini secara dramatis dapat membantu Anda memahami cara menghitung metode apa pun. Saya sarankan membacanya dari atas ke bawah untuk memahami sepenuhnya bagaimana melakukannya:
T(n) = T(n-1) + 1
Ini berarti bahwa waktu yang diperlukan untuk menyelesaikan metode sama dengan metode yang sama tetapi dengan n-1 yangT(n-1)
sekarang kita tambahkan+ 1
karena itu waktu yang diperlukan untuk menyelesaikan operasi umum (kecualiT(n-1)
). Sekarang, kita akan temukanT(n-1)
sebagai berikut:T(n-1) = T(n-1-1) + 1
. Sepertinya kita sekarang dapat membentuk suatu fungsi yang dapat memberi kita semacam pengulangan sehingga kita dapat sepenuhnya memahami. Kami akan menempatkan sisi kananT(n-1) = ...
bukannyaT(n-1)
di dalam metodeT(n) = ...
yang akan memberi kita:T(n) = T(n-1-1) + 1 + 1
yangT(n) = T(n-2) + 2
atau dengan kata lain kita perlu menemukan kami hilangk
:T(n) = T(n-k) + k
. Langkah selanjutnya adalah mengambiln-k
dan mengklaim bahwan-k = 1
karena pada akhir rekursi itu akan memakan waktu tepat O (1) kapann<=0
. Dari persamaan sederhana ini kita sekarang tahu ituk = n - 1
. Mari kita tempatkank
di metode terakhir kita:T(n) = T(n-k) + k
yang akan memberi kita: .T(n) = 1 + n - 1
yang persisn
atauO(n)
O(n)
.T(n) = T(n/5) + 1
seperti sebelumnya, waktu untuk menyelesaikan metode ini sama dengan waktu dengan metode yang sama tetapi dengann/5
alasan mengapa terikatT(n/5)
. Mari kita temukanT(n/5)
seperti pada 1:T(n/5) = T(n/5/5) + 1
yang manaT(n/5) = T(n/5^2) + 1
. Tempat MariT(n/5)
dalamT(n)
untuk perhitungan akhir:T(n) = T(n/5^k) + k
. Sekali lagi seperti sebelumnya,n/5^k = 1
yangn = 5^k
persis seperti menanyakan apa yang berkuasa 5, akan memberi kita n, jawabannya adalahlog5n = k
(log basis 5). Mari kita menempatkan temuan kami diT(n) = T(n/5^k) + k
sebagai berikut:T(n) = 1 + logn
yangO(logn)
T(n) = 2T(n-1) + 1
apa yang kita miliki di sini pada dasarnya sama dengan sebelumnya tetapi kali ini kita menggunakan metode ini secara rekursif 2 kali sehingga kita gandakan dengan 2. Mari kita temukanT(n-1) = 2T(n-1-1) + 1
yang manaT(n-1) = 2T(n-2) + 1
. Tempat kita berikutnya seperti sebelumnya, mari kita tempatkan penemuan kita:T(n) = 2(2T(n-2)) + 1 + 1
yangT(n) = 2^2T(n-2) + 2
memberi kitaT(n) = 2^kT(n-k) + k
. Ayo temukank
dengan mengklaim apan-k = 1
yang adak = n - 1
. Mari kita tempatkank
sebagai berikut:T(n) = 2^(n-1) + n - 1
yang kira-kiraO(2^n)
T(n) = T(n-5) + n + 1
Ini hampir sama dengan 4 tetapi sekarang kami menambahkann
karena kami memiliki satufor
loop. Ayo cariT(n-5) = T(n-5-5) + n + 1
yang manaT(n-5) = T(n - 2*5) + n + 1
. Mari kita tempatkan:T(n) = T(n-2*5) + n + n + 1 + 1)
yang manaT(n) = T(n-2*5) + 2n + 2)
dan untuk yang k:T(n) = T(n-k*5) + kn + k)
lagi:n-5k = 1
yangn = 5k + 1
kira-kiran = k
. Ini akan memberi kita:T(n) = T(0) + n^2 + n
yang kira-kiraO(n^2)
.Saya sekarang merekomendasikan membaca sisa jawaban yang sekarang, akan memberi Anda perspektif yang lebih baik. Semoga berhasil memenangkan O besar :)
sumber
Kuncinya di sini adalah untuk memvisualisasikan pohon panggilan. Setelah selesai, kompleksitasnya adalah:
istilah terakhir dapat dihitung dengan cara yang sama kita lakukan untuk fungsi iteratif normal.
Alih-alih, total node pohon lengkap dihitung sebagai
Di mana C adalah jumlah anak dari setiap simpul dan L adalah jumlah tingkatan pohon (termasuk root).
Sangat mudah untuk memvisualisasikan pohon itu. Mulai dari panggilan pertama (root node) kemudian gambar sejumlah anak yang sama dengan jumlah panggilan rekursif dalam fungsi. Juga bermanfaat untuk menulis parameter yang diteruskan ke panggilan sub-sebagai "nilai node".
Jadi, dalam contoh di atas:
sumber