Bagaimana waktu untuk mengurutkan array berubah secara dramatis di Java berdasarkan Ukuran Gap?

Saya pada dasarnya membuat 10 array acak dari ukuran: 8000,16000,32000,64000,128000,256000

Yang saya maksud adalah saya memiliki 10 array berukuran 8000, 10 array berukuran 16000, dst.

Ini semua diisi dengan angka acak mulai dari 0 hingga ukuran array.

Saya memiliki implementasi untuk shell sort:

public static void sortMyArray(int[] a){
for (int gap = a.length / 2; gap > 0; gap = (gap / 2)) {
    for (int i = gap; i < a.length; i++) {
        int tmp = a[i];
        int j = i;
        for (; j >= gap && tmp < (a[j - gap]); j -= gap) {
            a[j] = a[j - gap];
        }
        a[j] = tmp;
     }
}
}

Bila selisihnya adalah gap = a.length / a. panjangnya Saya hanya punya semacam penyisipan. Inilah waktu untuk mengurutkan array ini:

Number of Elements  Milliseconds
8000                13
16000               53
32000               217
64000               828
128000              3311
256000              13352

Jadi ini kira-kira O(N^2). Ketika jumlah elemen berlipat ganda, waktu penyelesaian meningkat hampir 4 kali lipat.

Namun, ketika saya menggunakan gap = a.length / 2 saya mendapatkan nilai seperti:

Number of Elements  Milliseconds
8000                2
16000               2
32000               4
64000               10
128000              25
256000              60

Jadi ini lebih baik dari O(N) menurutku? Bagaimana ini mungkin? Saya mencoba mematikan prosesor dari Windows, dan saya mencoba menjalankan komputer hanya pada 1 prosesor, namun nilainya masih tidak logis.

Ini kode lengkap saya jika Anda tertarik:

int[] arraySizes = new int[]{8000,16000,32000,64000,128000,256000};
Random rn = new Random(1);

for(int i=0;i<arraySizes.length;i++){
    int[] arrayToBeSorted = new int[arraySizes[i]];
    System.out.println("Solving array with: " + arraySizes[i] + " elements with first sorting algorithm.");
    for (int c = 0; c < 10; c++) {
        for(int t=0;t<arraySizes[i];t++){
            int randomNumber = rn.nextInt(arrayToBeSorted.length);
            arrayToBeSorted[t] = randomNumber;
        }
        Long initialTime = (new Date().getTime());
        sortMyArray(arrayToBeSorted);
        Long finalTime = (new Date().getTime());
        System.out.println("Time in milliseconds:" + (finalTime - initialTime));
    }
}

person Koray Tugay    schedule 15.05.2013    source sumber
comment
Acak rn = baru Acak(1); ini tampaknya mencurigakan. cukup gunakan default Random rn = new Random(); atau masukkan benih acak besar seperti Random rn = new Random(730495);   -  person tgkprog    schedule 16.05.2013
comment
Bagaimana efek benihnya, mengapa mencurigakan?   -  person Koray Tugay    schedule 16.05.2013
comment
saya tidak cukup tahu tentang generator acak tetapi benih yang penting adalah apa yang saya baca. Saya membuat aplikasi sampel tetapi bagi saya waktunya tidak berubah -› Memecahkan array dengan: 256000 elemen dengan algoritma pengurutan pertama. Waktu dalam milidetik: 213 (selalu dapatkan 207 hingga 223) untuk gap = a.length dan gap = a.length / 2   -  person tgkprog    schedule 16.05.2013
comment
Perhatikan bahwa menggunakan benih tetap menyebabkan hasil menjadi bias terhadap urutan angka yang dihasilkan oleh benih tersebut.   -  person nhahtdh    schedule 16.05.2013


Jawaban (1)


Meskipun implementasi Anda tampaknya benar, asumsi Anda tidak.

Anda berasumsi bahwa jika suatu fungsi memiliki kompleksitas O(n^2) dan waktu berjalan 3311 detik, maka beberapa fungsi lain dengan kompleksitas O(n) harus berjalan sekitar 57 detik pada data yang sama.

Namun notasi O besar memberikan gambaran tentang laju pertumbuhan fungsi, bukan waktu berjalan sebenarnya. Oleh karena itu, Anda tidak bisa hanya membandingkan waktu pengoperasian berbagai fungsi berdasarkan tingkat pertumbuhannya.

person bsrykt    schedule 16.05.2013
comment
Halo, Yang ingin saya katakan adalah, dalam Sortir Penyisipan ketika ukuran array bertambah kelipatan 2, waktu berjalan bertambah 4 derajat. Jadi waktu berjalan bergantung pada kuadrat jumlah elemen dalam array. Namun, ketika ukuran celah sama dengan 2, ketika jumlah elemen dalam array berlipat ganda, waktu berjalan juga berlipat ganda. - person Koray Tugay; 16.05.2013
comment
Apa yang Anda maksud dengan ukuran celah sama dengan 2? - person bsrykt; 16.05.2013
comment
Maaf, a.length / 2 maksud saya. Ukuran celah sama dengan setengah array.. Dalam situasi pengurutan geser. - person Koray Tugay; 16.05.2013
comment
Ini tidak benar: ketika jumlah elemen dalam array berlipat ganda, waktu berjalan juga berlipat ganda. 60/25 = 2,4, 25/10 = 2,5 dst. - person bsrykt; 16.05.2013