Mustika Langit
Portofolio ini membahas penerapan dua pendekatan algoritmik, yaitu metode iteratif dan rekursif (divide and conquer), dalam proses pengolahan data sensor pada sistem Internet of Things (IoT). Pada bagian pertama, dilakukan analisis terhadap dua fungsi algoritma untuk melihat bagaimana struktur perulangan memengaruhi jumlah iterasi dan efisiensi waktu eksekusi. Hasil analisis ini menjadi dasar untuk memahami perbedaan tingkat efisiensi antara kedua metode. Selanjutnya, bagian kedua menerapkan konsep tersebut pada kasus perusahaan smart city yang mengelola ribuan sensor suhu dan polusi udara setiap detik. Melalui simulasi dan perhitungan jumlah iterasi untuk beberapa ukuran data, portofolio ini menampilkan perbandingan kinerja kedua algoritma serta menilai kesesuaian penerapannya pada perangkat edge dan cloud dalam sistem IoT.
Dalam dunia komputasi, algoritma memiliki peran penting dalam menentukan kecepatan dan efisiensi suatu proses pemrosesan data. Setiap algoritma dirancang dengan struktur logika dan perulangan tertentu yang secara langsung memengaruhi kinerja program, terutama ketika ukuran data semakin besar. Pada bagian pertama portofolio ini, dilakukan analisis terhadap dua fungsi algoritma sederhana yang saya beri nama FUN1 dan FUN2. Keduanya digunakan sebagai contoh untuk memahami bagaimana perbedaan pola perulangan memengaruhi jumlah iterasi dan kompleksitas waktu eksekusi. Melalui perbandingan ini, diharapkan kita dapat memahami dengan lebih jelas mengenai hubungan antara struktur algoritmik dan efisiensi komputasi, yang nantinya menjadi dasar dalam penerapan algoritma pada sistem yang lebih kompleks, seperti pengolahan data sensor pada perangkat Internet of Things (IoT).
Mari kita bedah algoritma pertama. Algoritmanya adalah sebagai berikut:
Algoritma di atas, yang akan kita namakan FUN1 (kependekan dari function), merupakan algoritma yang cukup menarik. Pada algoritma FUN1, terdapat dua lapisan perulangan bersarang (nested loop). Perulangan luar (i) berjalan sebanyak n/2 kali, sedangkan perulangan dalam (j) berjalan tetap sebanyak m * 1000, yaitu 2.000.000 kali. Artinya, jumlah total iterasi berbanding lurus dengan nilai n, karena hanya loop luar yang bergantung pada n. Algoritma ini bisa dianalogikan sebagai seorang robot yang sudah sangat canggih dan memiliki kecerdasan layaknya manusia yang dipekerjakan di kantor Pos Indonesia (loop luar) yang tugasnya harus memproses sebanyak n tumpukan surat. Untuk setiap tumpukan, robot tersebut harus melakukan tugas standar yang sangat panjang yang sangat sulit bahkan mustahil dilakukan manusia, yaitu mengecap 2 juta dokumen (loop dalam). Jumlah tumpukan surat bisa berubah, tapi tugas mengecapnya selalu sama. Berikut penjelasan lebih detailnya:
Lalu, untuk algoritma kedua adalah sebagai berikut:
Algoritma 2 di atas akan kita namakan FUN2. FUN2, layaknya FUN1, juga memiliki dua loop bersarang, tetapi perilakunya cukup berbeda. Jumlah iterasi FUN2 dalam (while j < m) bergantung pada nilai n secara tidak langsung melalui m = n/10000. Karena j bertambah 20 setiap iterasi, jumlah pengulangan bagian dalam adalah m/20 = (n/10000)/20 = n / 200000. Algoritma di atas bisa dibayangkan seorang manajer proyek (loop luar) yang menangani n proyek. Untuk setiap proyek, ia harus mengadakan rapat dengan m stakeholder, di mana jumlah stakeholder m itu sendiri juga ditentukan oleh n. Berikut penjelasan detailnya:
Selanjutnya, kita akan menghitung perhitungan jumlah iterasi untuk n=10 dan n= 20. Di sini kita akan menghitung berapa kali Console.print(i+j) dieksekusi untuk nilai n yang kecil:
Dari hasil di atas, terdapat perbedaan dari kedua algoritma tersebut. Untuk nilai n yang sangat kecil, FUN2 tampak jauh lebih unggul karena loop dalamnya belum di-trigger. Penyebabnya adalah variabel m yang bergantung pada n dengan pembagi yang sangat besar (10.000). Namun, untuk n yang besar, jumlah langkah akan terpengaruh secara kuadratik. Sebaliknya, FUN1 menunjukkan hubungan linear yang jelas, yaitu saat n berlipat ganda dari 10 ke 20, jumlah iterasinya juga berlipat ganda. Jadi, pertambahan n akan selalu berbanding lurus dengan jumlah langkah untuk FUN1. Namun, pertambahan n tidak akan selalu berbanding lurus untuk FUN2, melainkan mengikuti kurva kuadratik.
Dari hasil perhitungan sebelumnya, FUN1 memiliki jumlah iterasi yang bergantung secara linear terhadap n → O(n), sedangkan FUN2 memiliki jumlah iterasi yang bergantung secara kuadrat terhadap n → O(n²).
Algoritma dengan tingkat pertumbuhan yang lebih rendah (seperti FUN1 yang linear) secara fundamental akan lebih efisien dan dapat diandalkan untuk data berukuran sangat besar (n mendekati tak terhingga) dibandingkan algoritma dengan pertumbuhan yang lebih tinggi (seperti FUN2 yang kuadratik) karena pertumbuhan waktu eksekusinya meningkat sebanding dengan ukuran input. Sedangkan, algoritma dengan pertumbuhan waktu yang lebih cepat (misalnya O(n²)) dapat menyebabkan algoritma menjadi semakin lambat saat input bertambah besar. Dalam konteks sistem nyata, terutama pada perangkat dengan sumber daya terbatas seperti IoT, hal ini menjadi sangat penting karena algoritma yang lebih kompleks akan menyebabkan keterlambatan pengambilan data sensor, sehingga mempengaruhi performa sistem. Kedua algoritma tersebut memiliki kompleksitas waktu yang dapat dinyatakan dalam sebuah fungsi T(n). Untuk FUN1, kompleksitas waktunya adalah sebagai berikut:
Persamaan di atas linear terhadap n, yang artinya pertumbuhannya berupa garis lurus.
Untuk algoritma FUN2, kompleksitasnya adalah:
Persamaan di atas tumbuh kuadratik terhadap n, yang artinya memiliki pertumbuhan yang grafiknya akan membentuk parabola.
Lalu, bentuk di atas pun bisa disederhanakan menjadi seperti berikut:
Notasi asimptotik dari kedua algoritma adalah sebagai berikut:
Untuk melihat secara empiris perbandingan kedua algoritma, maka kita akan menjalankan simulasi. Simulasi akan dijalankan untuk nilai n dari kecil hingga besar. Berikut adalah hasil simulasi dengan Python di VSCode:
Untuk pertumbuhan kompleksitasnya, Jika kedua algoritma dibandingkan, maka seperti yang sudah dijelaskan sebelumnya, FUN2 memiliki kompleksitas yang lebih cepat karena notasi O besarnya adalah O(n²). Lalu untuk hasil simulasi, dari hasil di atas, bisa dilihat bahwa untuk n kecil (10²), FUN2 lebih cepat karena loop dalam sangat kecil. Untuk n menengah (10⁶), yaitu nilai yang diminta oleh soal, FUN2 masih lebih cepat karena n² belum mendominasi, FUN2 hanya memproses 2,5 juta operasi dibanding FUN1 yang memproses satu triliun operasi (10¹²). Jadi, untuk n = 1 juta, FUN2 lebih efisien karena meskipun pertumbuhannya kuadratik, konstanta pada Algoritma 1 (c = 1.000.000) sangat besar, sedangkan konstanta pada Algoritma 2 (c = 1/400.000) sangat kecil.
Namun, performa FUN2 menurun mulai dari nilai n tertentu. Untuk n ≈ 4×10¹¹, titik menjadi seimbang karena tight bound tercapai (T1 ≈ T2). Dan untuk n > 4×10¹¹, FUN2 tumbuh jauh lebih cepat, sehingga tidak seefisien FUN1. Lalu, jika kita ambil nilai ekstrem, misal n = 10²⁰, maka T₂ sekitar 10⁸ kali lebih besar dari T₁. Secara asimptotik, O(n) tumbuh jauh lebih lambat daripada O(n²).
Berikut adalah hasil visualisasi di Python menggunakan matplotlib:
Berikut adalah hasil visualisasinya:
Grafik perbandingan kedua algoritma akan menunjukkan bahwa garis FUN1 (y = 1.000.000x) akan menjadi garis lurus yang sangat curam sejak awal, sedangkan FUN2 akan membentuk kurva parabola (y = x²/400.000) yang awalnya sangat landai, namun pada akhirnya akan melampaui garis FUN1. Titik di mana Algoritma 2 menjadi lebih lambat adalah saat n²/400.000 > 1.000.000n, yaitu saat n > 400 Miliar.
Konsep Asymptotic Growth Rate menjelaskan perilaku algoritma untuk n yang sangat besar mendekati tak terhingga, dengan mengabaikan konstanta. Secara asimtotik, n² pasti akan tumbuh lebih cepat daripada n. Jadi, meskipun Algoritma 2 lebih cepat untuk n=1 juta, Algoritma 1 secara teoretis lebih scalable untuk n yang luar biasa besar (lebih dari 400 Miliar).
Setelah melakukan analisis teoritis terhadap dua algoritma pada bagian sebelumnya (FUN1 dan FUN2), diperoleh pemahaman bahwa struktur perulangan dan pertumbuhan kompleksitas waktu sangat berpengaruh terhadap efisiensi eksekusi program. Prinsip inilah yang kemudian menjadi dasar ketika konsep tersebut diterapkan dalam konteks dunia nyata, khususnya pada sistem Internet of Things (IoT).
Dalam skenario ini, sebuah perusahaan smart city mengelola ribuan sensor lingkungan yang tersebar di berbagai titik kota. Setiap sensor bertugas merekam data suhu dan polusi udara setiap detik, menghasilkan jutaan data yang harus segera diproses. Proses ini tidak hanya sekadar mengumpulkan data, tetapi juga menghitung total kumulatif harian serta mendeteksi tren peningkatan polusi dari waktu ke waktu. Tantangan muncul ketika data yang dihasilkan begitu besar dan harus diolah secara real-time dengan keterbatasan sumber daya di sisi perangkat sensor (seperti Raspberry Pi atau microcontroller). Untuk mengatasi hal ini, dua tim pengembang mengusulkan pendekatan algoritmik yang berbeda dalam menghitung total kumulatif data sensor:
Kedua pendekatan ini kemudian dibandingkan untuk menilai fungsi waktu eksekusi, kompleksitas algoritma, serta efisiensi penerapan dalam sistem pemantauan kualitas udara real-time. Melalui studi kasus ini, analisis yang sebelumnya bersifat abstrak kini diaplikasikan langsung pada permasalahan nyata yang dihadapi sistem IoT modern.Mari kita analisis kedua pilihan yang dihadapkan ke perusahaan smart city. Algoritma pertama adalah algoritma iteratif (Loop Bersarang pada Perangkat Lapangan). Berikut adalah algoritma yang pertama:
Fungsi waktu eksekusinya bisa dinyatakan dalam pernyataan seperti di bawah ini:
Bilangan satu dalam pembilangnya tidak disertakan karena akan insignifikan untuk angka yang besar. Untuk algoritma iteratif yang pertama ini, bisa dilihat bahwa notasi Big-O-nya adalah O(n²).
Selanjutnya, kita akan bahas algoritma kedua. Algoritma kedua yang akan kita sebut Algoritma B merupakan algoritma rekursif Divide and Conquer (Server Cloud). Algoritma ini digunakan Digunakan pada server pusat dengan kemampuan pemrosesan paralel yang lebih tinggi. Berikut adalah algoritma B:
Algoritma ini membagi array data menjadi dua bagian yang sama besar, lalu memanggil dirinya sendiri secara rekursif pada bagian kiri (Data[0:tengah]). Setelah itu, dia akan memanggil lagi pada bagian kanan (Data[tengah:n]). Dan akhirnya, hasilnya akan digabungkan dengan satu operasi penjumlahan (kiri + kanan). Nah, ini sudah bentuk umum dari Divide and Conquer, di mana, ada sebanyak a pemanggilan rekursif, masing-masing bekerja pada n/b ukuran input, dan ada f(n) pekerjaan tambahan untuk menggabungkan hasilnya. Intinya, Setiap pemanggilan fungsi membagi data menjadi dua bagian sama besar, lalu hasilnya digabung. Persamaan waktu eksekusinya bisa dinyatakan sebagai berikut:
Algoritma 1 memiliki fungsi waktu seperti berikut yang sudah disebutkan sebelumnya:
Berikut hasil iterasi untuk algoritma 1:
Berikut hasil iterasi untuk algoritma 2 yang bisa memakai rumus 2n-1 yang bisa didapat dari persamaan fungsi waktunya seperti berikut:
Kompleksitas Waktu dari kedua algoritma A dan B adalah sebagai berikut:
Untuk kedua algoritma ini, struktur perulangan dan pembagiannya tidak bergantung pada nilai data, hanya pada jumlah data (n). Oleh karena itu, Best Case, Worst Case, dan Average Case ketiganya memiliki kompleksitas yang sama.
SIMULASI DAN VISUALISASI
Untuk menguji performa kedua algoritma yang telah dibahas sebelumnya, dilakukan sebuah simulasi berbasis data sensor lingkungan yang menggambarkan kondisi nyata sistem Internet of Things (IoT) pada perusahaan smart city. Sistem ini terdiri atas ribuan sensor yang tersebar di berbagai titik kota dan berfungsi untuk merekam data suhu serta tingkat polusi udara setiap detik. Data yang diterima bersifat dinamis dan acak, karena kondisi lingkungan di lapangan selalu berubah dari waktu ke waktu.
Dalam simulasi ini, data sensor dibangkitkan secara acak menggunakan rentang nilai suhu antara 25–40°C dan nilai polusi udara (Air Quality Index/AQI) antara 30–100. Data tersebut kemudian diolah menggunakan dua pendekatan algoritmik, yaitu algoritma iteratif bersarang (Algoritma A) dan algoritma rekursif divide and conquer (Algoritma B). Untuk memperjelas perbedaan performa kedua algoritma, simulasi dilakukan pada dua kondisi ekstrem, yaitu n = 100 dan n = 50.000 data sensor. Tujuannya adalah untuk membandingkan efisiensi waktu eksekusi kedua metode dalam menghitung nilai kumulatif data sensor yang terus bertambah, mulai dari data yang sedikit hingga jumlah data yang signifikan. Hasil pengujian ditampilkan dalam bentuk grafik perbandingan waktu eksekusi terhadap jumlah data sensor (n). Dengan cara ini, dapat diamati bagaimana masing-masing algoritma merespons peningkatan volume data secara signifikan, sekaligus menunjukkan perilaku nyata yang akan dihadapi sistem IoT perusahaan smart city dalam pengolahan data lingkungan secara real-time.
Bisa dilihat dari hasil di atas, terlihat perbedaan performa yang sangat signifikan antara kedua algoritma. Pada saat jumlah data sensor masih kecil (n = 100), kedua algoritma menunjukkan waktu eksekusi yang hampir sama, yaitu mendekati nol detik. Hal ini terjadi karena ukuran data yang relatif kecil belum mampu memunculkan dampak kompleksitas yang signifikan terhadap kinerja masing-masing algoritma. Namun, ketika jumlah data meningkat secara drastis menjadi n = 50.000, perbedaan efisiensi menjadi sangat mencolok. Algoritma iteratif bersarang membutuhkan waktu sekitar 132,65 detik, sedangkan algoritma rekursif hanya sekitar 0,065 detik untuk menyelesaikan proses yang sama. Perbandingan ini menunjukkan bahwa algoritma rekursif bekerja lebih dari 2000 kali lebih cepat dibandingkan pendekatan iteratif. Hasil tersebut sesuai dengan analisis teoretis bahwa kompleksitas waktu algoritma iteratif bersifat kuadratik (O(n²)), sedangkan algoritma rekursif tumbuh linear (O(n)), sehingga menjadikannya jauh lebih efisien untuk pemrosesan data besar pada sistem IoT berskala luas.
Dalam konteks penerapan nyata pada sistem Internet of Things (IoT), hasil ini memiliki implikasi yang penting. Algoritma iteratif bersarang masih dapat digunakan pada perangkat lapangan (edge device) yang hanya menangani sejumlah kecil sensor lokal, karena strukturnya sederhana, tidak membutuhkan pengelolaan memori rekursif, dan mudah diimplementasikan pada perangkat dengan kemampuan komputasi terbatas seperti edge device Raspberry PI. Namun, untuk pemrosesan data berskala besar seperti di server pusat atau cloud computing, algoritma rekursif jauh lebih ideal karena mampu menangani volume data tinggi dengan waktu yang jauh lebih efisien. Dengan demikian, hasil simulasi ini tidak hanya membuktikan analisis kompleksitas secara teoretis, tetapi juga memberikan bukti empiris bahwa pendekatan rekursif lebih efisien dan skalabel untuk digunakan dalam sistem pengolahan data sensor IoT berskala besar, di mana kecepatan dan efisiensi waktu sangat krusial untuk menjaga performa pemantauan real-time.
Berikut adalah tabel yang menampilkan kasus terbaik, terburuk, dan rata-ratanya:
Rekursif memiliki pertumbuhan stabil di semua kasus, sedangkan iteratif melonjak drastis untuk n besar.
Untuk implementasi di Edge Device dan Server Cloud yang memproses 1 juta (10⁶) data sensor per jam, maka algoritma yang lebih cocok untuk masing-masing perangkat adalah sebagai berikut:
Ini terlalu berat untuk mikrokontroler Raspberry Pi. Algoritma ini jadi tidak cocok di edge device karena keterbatasan CPU dan memori. Untuk Edge Device lebih cocok menggunakan algoritma sederhana, seperti misalnya iteratif linear, dan bukan bersarang. Bisa dihilangkan sarangnya sehingga algoritma menjadi seperti ini:
Ini masih bisa dilakukan, terutama jika dilakukan pemecahan Server Cloud ke beberapa core / node di server cloud secara paralel. Algoritma ini adalah pilihan yang jauh lebih sesuai dan realistis untuk dijalankan di cloud, terutama contohnya di server pusat.
Untuk pemantauan kualitas udara secara realtime, respons cepat adalah kunci. Untuk sensor edge, algoritma A yang O(n²) sama sekali tidak cocok karena latensinya akan sangat tinggi, sedangkan pemantauan realtime perlu latensi rendah, dan algortima A sangat lambat. Algoritma B O(n) lebih baik dari segi kecepatan, namun memiliki risiko stack overflow pada perangkat dengan memori (RAM) terbatas, yang sangat umum terjadi di dunia IoT. Setiap pemanggilan fungsi rekursif akan menumpuk di memori dan untuk n yang besar bisa menyebabkan crash. Algoritma B lebih cocok untuk server pusat cloud Pendeknya, pada edge, efisiensi energi lebih penting daripada waktu absolut, sedangkan pada server, efisiensi throughput dan paralelisme lebih diutamakan. Berikut adalah tabel yang relevan:
Efisiensi algoritma ini memiliki implikasi terhadap waktu respons (latency), konsumsi daya, serta skalabilitas jumlah sensornya. Berikut penjelasannya:
Analisis kita menunjukkan bahwa Algoritma A (Iteratif) yang diusulkan memiliki cacat desain fundamental. Penggunaan loop bersarang untuk tugas penjumlahan kumulatif sederhana sangatlah tidak efisien. Di sisi lain, Algoritma B (Rekursif) sudah sangat efisien dari segi waktu (O(n)) tetapi memiliki kelemahan dari segi penggunaan memori. Algoritma optimal yang direkomendasikan bukanlah antara A atau B, melainkan sebuah algoritma baru yang menggabungkan keunggulan keduanya: kecepatan O(n) dan efisiensi memori dari pendekatan iteratif.
Analisisnya:
Jika sistem dioptimalkan, kombinasi kedua pendekatan IoT dapat digunakan:
Analisis terhadap kedua soal dalam proyek ini memberikan pelajaran fundamental mengenai konsep efisiensi dalam rekayasa perangkat lunak.
Pelajaran pertama dari Soal 1 menunjukkan bahwa Notasi Big-O, meskipun krusial untuk memahami skalabilitas jangka panjang, bukanlah satu-satunya penentu performa. Kita menemukan bukti konkret di mana algoritma O(n²) dengan konstanta kecil mampu bekerja jauh lebih cepat daripada algoritma O(n) dengan konstanta besar pada skala data yang sangat luas. Ini membuktikan pentingnya analisis praktis dan profiling untuk memahami kinerja nyata algoritma dalam domain operasional yang spesifik.
Selanjutnya, Soal 2 mengajarkan bahwa "efisiensi" adalah konsep yang multidimensional. Perbandingan antara pendekatan iteratif dan rekursif menyoroti adanya trade-off krusial antara efisiensi waktu (Time Complexity) dan efisiensi memori (Space Complexity). Solusi rekursif yang secara teoretis cepat (O(n)) ternyata membawa risiko stack overflow yang fatal untuk perangkat IoT, membuktikan bahwa kecepatan komputasi tidak ada artinya tanpa stabilitas dan keamanan memori.
Dengan demikian, kesimpulan utamanya adalah pemilihan algoritma yang tepat bukanlah sekadar pencarian solusi tercepat secara teoretis, melainkan sebuah tindakan penyeimbangan antara tiga pilar utama:
Secara keseluruhan, dapat disimpulkan bahwa algoritma iteratif bersarang kurang sesuai diterapkan pada perangkat edge IoT karena boros waktu dan daya, sementara algoritma rekursif lebih efisien pada sistem cloud yang mampu menjalankan proses paralel. Pemilihan algoritma yang tepat sangat penting agar sistem IoT dapat bekerja cepat, hemat sumber daya, dan mampu menangani pertambahan data sensor yang sangat besar secara berkelanjutan.