Pemrograman Kompetitif
  • Menu utama
    • Selamat Datang
  • Umum
    • Pengenalan Pemrograman
    • Pengenalan Pemrograman Kompetitif
    • Pengenalan Kontes
    • Sumber Belajar
    • Pengenalan C++
  • Pemrograman Dasar
    • Struktur Program
    • Variabel dan Tipe Data
    • Masukan dan Pengeluaran
    • Operator
    • Percabangan
    • Perulangan
      • While Loop
      • For Loop
        • Nested For Loop
        • Ranged-based for loop
      • Break dan Continue
    • Array
    • Pendalaman String
    • Fungsi
    • Rekursi
    • Analisis Kompleksitas
  • Struktur Data
    • Struktur Data Linear
      • Array Dinamis
      • Stack dan Queue
      • Struktur Set
      • Struktur Map
    • Struktur Data Non-Linear
      • Disjoint Set Union
      • Binary Heap
      • Hash Table
      • Segment Tree
  • Pencarian dan Pengurutan
    • Algoritma Pengurutan
      • Bubble Sort
      • Selection Sort
      • Insertion Sort
      • Counting Sort
      • Merge Sort
      • Bogosort
    • Algoritma Pencarian
      • Linear Search
      • Binary Search
  • Paradigma Penyelesaian Masalah
    • Complete Search
      • Complete Search Iteratif
      • Complete Search Rekursif
    • Divide and Conquer
    • Greedy
    • Dynamic Programming
  • Graf
    • Representasi Graf
      • Adjacency list
      • Adjacency matrix
      • Edge list
    • Penjelajahan Graf
      • DFS (Depth-first search)
      • BFS (Breadth-first search)
    • Tree
  • Matematika
  • Geometri
  • Teori Bilangan
  • Kombinatorika
  • Tentang
    • Tentang Website Ini
    • Tim Kami
Powered by GitBook
On this page
  1. Pemrograman Dasar

Analisis Kompleksitas

Penulis : Benedict_p

PreviousRekursiNextStruktur Data Linear

Last updated 2 years ago

Dalam dunia pemrograman, sering sekali kita harus memperkirakan kecepatan suatu program atau memori yang diperlukan untuk menjalankan suatu program. Terdapat beberapa cara untuk merepresentasikan perkiraan tersebut. Cara yang paling sering digunakan dalam pemrograman kompetitif adalah dengan menggunakan Big O Notation. Di bab ini kita akan membahas cara melakukan analisis kompleksitas dengan Big O Notation.

Big O Notation

Notasi O besar atau Big O Notation dalam pemrograman kompetitif adalah suatu notasi yang memperkirakan banyaknya operasi yang perlu dilakukan oleh suatu program dari awal sampai akhir bergantung pada inputnya. Banyaknya operasi yang dapat dilakukan oleh komputer pada umumnya dengan bahasa C++ adalah sekitar 108 10^8\,108operasi tiap detik. Dengan informasi ini dan notasi O besar, kita bisa memperkirakan waktu berjalannya suatu program. Selanjutnya kita akan membahas pembagian Big O Notation.

Gambar:

O(1)O(1)O(1)

O(1)O(1)O(1)menyatakan bahwa waktu yang diperlukan untuk menjalankan suatu program tidak tergantung pada variabel apapun, disebut juga konstan. Perhatikan contoh di bawah.

#include<iostream>
using namespace std;

int main(){
    int x;
    cin >> x;
    
    // Mencari apakah x adalah bilangan ganjil atau genap.
    
    if(x % 2 == 1){
        cout << "ganjil\n";
    }
    else{
        cout << "genap\n";
    }
    
    return 0;
}

Untuk x bernilai apapun, program tetap hanya menjalankan 2 operasi, yaitu menghitung x % 2 kemudian mengecek apakah nilainya sama dengan 1. Maka program di atas disebut memiliki kompleksitas konstan dan dinotasikan dengan O(1)O(1)O(1).

O(N)O(N)O(N)

Jika suatu program menjalankan NNN buah operasi untuk suatu input NNN, program tersebut memiliki kompleksitas O(N)O(N)O(N). Disebut juga memiliki kompleksitas linear. Perhatikan contoh di bawah.

#include<iostream>
using namespace std;

int main(){
    int N;
    cin >> N;
    
    int sum = 0;
    for(int i = 1; i <= N; ++i){
        sum += i;
    }
    
    return 0;
}

Program melakukan perulangan sebanyak NNN kali dan menjalankan 1 operasi pada tiap perulangan, sehingga program melakukan NNN buah operasi. Kita dapat menuliskan kompleksitas program sebagai O(N)O(N)O(N). Meskipun nantinya program menjalankan lebih dari 1 operasi pada tiap perulangan, kita tetap menuliskan kompleksitas program sebagai O(N)O(N)O(N). Hal ini dikarenakan Big O Notation, tidak mempertimbangkan faktor konstan. Contoh,

#include<iostream>
using namespace std;

int main(){
    int N;
    cin >> N;
    
    int num = 0, sum = 0, product = 1;
    for(int i = 1; i <= N; ++i){
        num++;
        sum += i;
        product *= i;
    }
    
    return 0;
}

Meskipun program melakukan perulangan terjadi sebanyak NNN kali dan pada tiap perulangan melakukan 3 operasi, kompleksitas program tetap dituliskan O(N)O(N)O(N)dan bukan O(3N)O(3N)O(3N).

O(N2)O(N^2)O(N2)

Jika suatu program menjalankan sekitar N2N^2N2 operasi untuk suatu input NNN, maka program memiliki kompleksitas O(N2)O(N^2)O(N2). Contoh,

#include<iostream>
using namespace std;

int main(){
    int N; cin >> N;
    
    int sum = 0;
    for(int i = 1; i <= N; ++i){
        for(int j = 1; j <= N; ++j){
            sum += 2*i - j;
        }
    }
    
    return 0;
}

Program di atas melakukan NNNkali perulangan, kemudian pada tiap perulangan melakukan NNNkali perulangan lagi. Kompleksitas program adalah O(N×N)O(N \times N)O(N×N) atau O(N2)O(N^2)O(N2).

#include<iostream>
using namespace std;

int main(){
    int N; cin >> N;
    
    int sum = 0;
    for(int i = 1; i <= N; ++i){
        for(int j = 1; j <= i; ++j){
            sum += 2*i - j;
        }
    }
    
    return 0;
}

Program di atas melakukan NNN kali perulangan. Pada perulangan pertama terjadi 1 kali perulangan, pada perulangan kedua terjadi 2 kali perulangan, pada perulangan ketiga terjadi 3 kali perulangan, dan selanjutnya. Total operasi yang terjadi adalah 1+2+3+…+N=N(N+1)21 + 2 + 3 + … + N = \dfrac{N(N+1)}{2}1+2+3+…+N=2N(N+1)​. Kita tetap menuliskan kompleksitasnya sebagai O(N2)O(N^2)O(N2). Ingat bahwa notasi O besar tidak mempertimbangkan faktor konstan, sehingga kita tidak perlu menuliskan 12.\dfrac{1}{2}.21​. Kemudian jika kita jabarkan N(N+1)=N2+NN(N+1) = N^2 + NN(N+1)=N2+N. Perhatikan untuk NNN yang besar, nilai + N+\,N+Ntidak signifikan karena ukuran N2N^2N2 jauh lebih besar.

O(NM)O(NM)O(NM)

Program menjalankan sekitar N×MN \times MN×Muntuk input NNNdanMMM. Contoh,

#include<iostream>
using namespace std;

int main(){
    int N, M;
    cin >> N >> M;
    
    int sum = 0;
    for(int i = 1; i <= N; ++i){
        for(int j = 1; j <= M; ++j){
            sum += i + j;    
        }
    }
}

O(N!)O(N!)O(N!)

Jika suatu program menjalankan sekitarN!N!N! operasi, maka program tersebut memiliki kompleksitas O(N!)O(N!)O(N!). Contohnya adalah pada persoalan mencetak semua permutasi untuk bilangan 111 sampai NNN. (Lihat rekursi)

#include<iostream>
using namespace std;

int N;
int perm[20];
bool used[20];

void generate_permutation(int index){
    if(index >= N){
        // print perm
    }
    else{
        for(int i = 1; i <= N; ++i){
            if(used[i] == false){
                used[i] = true;
                perm[index] = i;
                generate_permutation(index + 1);
                used[i] = false;
            }
        }
    }
}

int main(){
    int N;
    cin >> N;
    
    generate_permutation(0);
    
    return 0;
}

Program di atas mencetak semua permutasi untuk bilangan 111 sampai NNN. Karena terdapat N!N!N! permutasi, maka program di atas memiliki kompleksitas O(N!)O(N!)O(N!).

The Coding Bay