Saya sudah memikirkan masalah berikut untuk sementara waktu, dan saya belum menemukan solusi polinomial untuk itu. Hanya sumber kasar. Saya sudah mencoba untuk mengurangi masalah NP-Complete ke dalamnya juga tanpa keberhasilan.
Inilah masalahnya :
Anda memiliki set yang diurutkan dari pasangan bilangan bulat positif.
Operasi berikut dapat diterapkan untuk sepasang: Swap(pair)
. Ini menukar elemen pasangan, sehingga akan menjadi
Ketika pasangan di set ditukar, set secara otomatis akan diurutkan lagi (pasangan bertukar tidak pada tempatnya dan itu akan dipindahkan ke tempatnya di set)
Masalahnya terdiri pada melihat apakah ada urutan yang, dimulai pada beberapa pasangan, menukar seluruh rangkaian, dengan kondisi berikut:
Setelah satu pasangan ditukar, pasangan berikutnya yang akan ditukar harus menjadi penerus atau pasangan predecesor di set.
Akan sangat bagus untuk menemukan solusi waktu polinomial untuk masalah ini, atau pengurangan masalah NP-Complete ke dalamnya.
Catatan:
Ini sudah menjadi masalah keputusan. Saya tidak ingin tahu urutan mana: hanya jika ada urutan.
Contoh bagaimana set akan diurutkan setelah bertukar pasangan
Jika saya menukar pasangan pertama, itu menjadi: , dan setelah mengurutkan set (menempatkan pasangan yang diurutkan di posisi baru), kita memiliki:
Maka saya harus menukar salah satu (pendahulu) atau ( 7 , 8 ) (penerus), dan ulangi prosesnya sampai semua pasangan bertukar (jika memungkinkan).
Penting:
Anda tidak dapat menukar pasangan yang sudah ditukar.
Jika ada urutan operasi 'swap', maka semua pasangan harus diganti namanya menjadi sekali dan hanya sekali.
Contoh di mana tidak mungkin untuk menukar semua pasangan
( 1 , 4 ) ( 3 , 2 )
sumber
Jawaban:
... Saya mencari beberapa pola untuk membuat pengurangan dari masalah NPC, tetapi tidak menemukan cara untuk mewakili "aliran" dengan "garpu" ...
Jadi (setelah beberapa pekerjaan) ini adalah algoritma polinomial ...
ALGORITMA
Daftar awal dapat dilihat sebagai larik " lubang " berurutan . Untuk setiap pasangan awal ( a j , b j ) , letakkan " elemen " b j pada nomor lubang a j . Setiap pasangan dapat dilihat sebagai tepi diarahkan dari posisi suatu j ke posisi b j . Sebuah langkah terdiri dalam memilih sebuah elemen b j pada posisi yang j dan pindah ke nya posisi tujuan b jN∗2 (aj,bj) bj aj aj bj bj aj bj (lubang tujuan menjadi pasak tidak bergerak ). Kami menghapus tepi, dan lanjutkan untuk memilih langkah selanjutnya yang akan dimulai dari salah satu dari dua unsur dicapai terdekat dari posisi b j (hanya lubang antara b j dan b k diperbolehkan). Kami harus menemukan urutan gerakan N berturut-turut.bk bj bj bk N
Untuk masing-masing pertimbangkan b j (pada posisi larik a j ) sebagai elemen awal s t a r t .(aj,bj) bj aj start
Untuk masing-masing pertimbangkan a k sebagai elemen terakhir e n d (tepi dari posisi a k ke posisi b k(ak,bk),ak≠aj ak end ak bk akan menjadi ujung akhir).
Ketika Anda bergerak, Anda mematok pasak pada posisi dan array dibagi menjadi dua partisi L (kiri) dan R (kanan) dan satu-satunya cara untuk beralih dari L ke R (atau dari R ke L ) menggunakan tepi yang melompat di pasak. Setbj L R L R R L
Kasus:
A) jika maka salah satu dari dua partisi akan menjadi tidak terjangkau, berhenti|flow|>1
Sekarang anggaplah bahwa , yaitu e n d ∈ Rend>bj end∈R
B) jika maka ada keunggulan tambahan dari kiri ke kanan, Anda harus pergi kiri (memilih elemen terdekat dari L ), jika tidak, anda tidak akan pernah mencapai e n dflow=1 L end
C) jika maka ada tepi ekstra dari kanan ke kiri dan simpul apa pun yang Anda pilih, Anda tidak akan pernah mencapai e n dflow=−1 end , berhenti
D) jika Anda harus pergi ke kanan (memilih elemen terdekat dari R ), jika tidak Anda akan neve jangkauan e n dflow=0 R end
Jika ( e n d ∈ L ), B, C, D terbalik.end<bj end∈L
CATATAN: saat bergerak ke kiri atau ke kanan, Anda harus mempertimbangkan sebagai pasak. Misalnya, jika Anda harus berbelok ke kanan, tetapi elemen terdekat pada R adalah e n d maka langkah tersebut tidak mungkin (dan Anda harus melanjutkan dengan pasangan lain ( s t a r t , e n d ) )end R end (start,end)
Terapkan pengubahan ulang yang sama di setiap gerakan.
KOMPLEKSITAS
Aliran pada setiap lubang dapat dihitung ulang dalam O (N) dan digunakan kembali pada setiap pemindaian.
Loop adalah:
Tidak ada pilihan yang dibuat selama perhitungan, sehingga kompleksitas algoritma adalahO(N3)
KODE
Ini adalah implementasi algoritma Java yang berfungsi:
sumber
Ini bukan solusi, tetapi reformulasi yang menghindari penyebutan secara eksplisit operasi swapping dan sortasi. Mulailah dengan menyortir seluruh daftar nama file gabungan dan versi bertukar mereka, dan mengidentifikasi setiap nama file dengan indeks dalam daftar itu. Lalu dua file bertetangga jika semua nama file lama di antara mereka telah dihancurkan, dan jika belum ada nama file baru di antara mereka. Masalah yang dirumuskan kembali adalah sebagai berikut:
Mengingat satu set menguraikan tepi diarahkan ( a , b ) dengan a , b ∈ { 1 , 2 , ... , 2 n } , apakah ada pemesanan ( a 1 , b 1 ) , ( a 2 , b 2 ) , . . . , ( a n , b n ) dari tepi ini sedemikian rupa sehinggan (a,b) a,b∈{1,2,…,2n} (a1,b1),(a2,b2),...,(an,bn)
sumber