Apakah ada cara untuk mengukur seberapa daftar diurutkan?
Maksud saya, ini bukan tentang mengetahui apakah suatu daftar diurutkan atau tidak (boolean), tetapi sesuatu seperti rasio "penyortiran", sesuatu seperti koefisien korelasi dalam statistik.
Sebagai contoh,
Jika item daftar berada dalam urutan menaik, maka nilainya adalah 1,0
Jika daftar diurutkan secara turun, nilainya akan -1.0
Jika daftar hampir diurutkan naik, nilainya akan menjadi 0,9 atau nilai mendekati 1.
Jika daftar tidak diurutkan sama sekali (acak), nilainya akan mendekati 0
Saya sedang menulis perpustakaan kecil di Scala untuk latihan. Saya pikir tingkat penyortiran akan berguna, tetapi saya tidak menemukan informasi tentang sesuatu seperti itu. Mungkin saya tidak tahu istilah yang memadai untuk konsep ini.
Jawaban:
Anda cukup menghitung jumlah inversi dalam daftar.
Inversi
Suatu inversi dalam suatu urutan elemen-elemen tipe
T
adalah sepasang elemen-elemen sekuens yang muncul tidak sesuai dengan beberapa pemesanan<
pada set elemenT
.Dari Wikipedia :
Untuk membuat definisi ini lebih jelas, pertimbangkan urutan contoh
9, 5, 7, 6
. Urutan ini memiliki inversi(0,1), (0,2), (0,3), (2,3)
dan nomor inversi4
.Jika Anda menginginkan nilai antara
0
dan1
, Anda dapat membagi nomor inversi denganN choose 2
.Untuk benar-benar membuat algoritma untuk menghitung skor ini untuk bagaimana diurutkan daftar itu, Anda memiliki dua pendekatan:
Pendekatan 1 (Deterministik)
Ubah algoritma penyortiran favorit Anda untuk melacak berapa banyak inversi yang dikoreksi saat dijalankan. Meskipun ini bukan trivial dan memiliki implementasi yang bervariasi tergantung pada algoritma pengurutan yang Anda pilih, Anda akan berakhir dengan algoritma yang tidak lebih mahal (dalam hal kompleksitas) daripada algoritma pengurutan yang Anda mulai.
Jika Anda mengambil rute ini, perlu diketahui bahwa tidak sesederhana menghitung "swap". Mergesort, misalnya, adalah kasus terburuk
O(N log N)
, namun jika dijalankan pada daftar yang diurutkan dalam urutan menurun, itu akan memperbaiki semuaN choose 2
inversi. ItuO(N^2)
inversi diperbaiki diO(N log N)
operasi. Jadi beberapa operasi pasti mengoreksi lebih dari satu inversi pada suatu waktu. Anda harus berhati-hati dengan implementasi Anda. Catatan: Anda dapat melakukan ini denganO(N log N)
kerumitan, itu hanya rumit.Terkait: menghitung jumlah "inversi" dalam permutasi
Pendekatan 2 (Stochastic)
(i,j)
, di manai != j
list[min(i,j)] < list[max(i,j)]
(0 atau 1)N choose 2
Saya pribadi akan pergi dengan pendekatan stokastik kecuali jika Anda memiliki persyaratan ketepatan - jika hanya karena sangat mudah diimplementasikan.
Jika yang benar-benar Anda inginkan adalah nilai (
z'
) antara-1
(diurutkan menurun) ke1
(diurutkan naik), Anda cukup memetakan nilai di atas (z
), yang antara0
(diurutkan naik) dan1
(diurutkan turun), ke rentang ini menggunakan rumus ini :sumber
Ukuran tradisional tentang bagaimana diurutkan daftar (atau struktur berurutan lainnya) adalah, adalah jumlah inversi.
Jumlah inversi adalah jumlah pasangan (a, b) st indeks a <b DAN b
<<
a. Untuk tujuan ini<<
mewakili hubungan pemesanan apa pun yang Anda pilih untuk jenis khusus Anda.Daftar yang sepenuhnya diurutkan tidak memiliki inversi, dan daftar yang sepenuhnya terbalik memiliki jumlah inversi maksimum.
sumber
5 4 3 2 1
sepenuhnya disortir karena pesanan tidak ditentukan, tapi saya menjadi pedantic :-)<
.n choose 2
.Anda dapat menggunakan korelasi aktual.
Misalkan untuk setiap item dalam daftar diurutkan, Anda menetapkan peringkat integer mulai dari nol. Perhatikan bahwa grafik indeks posisi elemen versus peringkat akan terlihat seperti titik-titik dalam garis lurus (korelasi 1,0 antara posisi dan peringkat).
Anda dapat menghitung korelasi pada data ini. Untuk pengurutan terbalik, Anda akan mendapatkan -1 dan seterusnya.
sumber
Ada jawaban yang bagus, dan saya ingin menambahkan aspek matematika untuk kelengkapan:
Anda dapat mengukur seberapa daftar diurutkan dengan mengukur seberapa banyak itu berkorelasi dengan daftar yang diurutkan. Untuk melakukan itu, Anda dapat menggunakan korelasi peringkat (yang paling dikenal adalah Spearman's ), yang persis sama dengan korelasi biasa, tetapi menggunakan peringkat elemen dalam daftar, bukan nilai analog dari item-itemnya.
Ada banyak ekstensi, seperti koefisien korelasi (+1 untuk pengurutan yang tepat, -1 untuk inversi yang tepat)
Ini memungkinkan Anda untuk memiliki properti statistik untuk ukuran ini, seperti teorema batas pusat permutasional, yang memungkinkan Anda untuk mengetahui distribusi ukuran ini untuk daftar acak.
sumber
Terlepas dari jumlah inversi, untuk daftar angka, jarak kuadrat rata-rata dari status yang diurutkan dapat dibayangkan:
sumber
Saya tidak yakin dengan metode "terbaik", tetapi yang sederhana adalah membandingkan setiap elemen dengan yang sesudahnya, menambah penghitung jika elemen2> elemen 1 (atau apa pun yang ingin Anda uji) dan kemudian dibagi dengan jumlah total elemen. Itu akan memberi Anda persentase.
sumber
Saya akan menghitung perbandingan dan membaginya dengan jumlah total perbandingan. Berikut ini adalah contoh Python sederhana .
sumber
Bagaimana dengan sesuatu yang seperti ini?
sumber
Jika Anda mengambil daftar Anda, menghitung peringkat nilai-nilai dalam daftar itu dan memanggil daftar peringkat
Y
dan daftar lain,X
yang berisi bilangan bulat dari1
hinggalength(Y)
, Anda bisa mendapatkan ukuran pengurutan yang Anda cari dengan menghitung koefisien korelasi ,, dir
antara dua daftar.Untuk daftar yang sepenuhnya diurutkan
r = 1.0
,, untuk daftar yang diurutkan terbalikr=-1.0
,, dan perbedaanr
antara batas-batas ini untuk berbagai tingkat pengurutan.Masalah yang mungkin terjadi dengan pendekatan ini, tergantung pada aplikasinya, adalah bahwa menghitung peringkat setiap item dalam daftar sama dengan menyortirnya, sehingga ini merupakan operasi O (n log n).
sumber