Saya memiliki satu set pasangan. Setiap pasangan berbentuk (x, y) sedemikian rupa sehingga x, y milik bilangan bulat dari kisaran [0,n)
.
Jadi, jika n adalah 4, maka saya memiliki pasangan berikut:
(0,1) (0,2) (0,3)
(1,2) (1,3)
(2,3)
Saya sudah memiliki pasangan. Sekarang, saya harus membangun kombinasi menggunakan n/2
pasangan sehingga tidak ada bilangan bulat yang diulang (dengan kata lain, setiap bilangan bulat muncul setidaknya sekali dalam kombinasi akhir). Berikut ini adalah contoh kombinasi yang benar dan salah untuk pemahaman yang lebih baik
1. (0,1)(1,2) [Invalid as 3 does not occur anywhere]
2. (0,2)(1,3) [Correct]
3. (1,3)(0,2) [Same as 2]
Dapatkah seseorang menyarankan saya cara untuk menghasilkan semua kombinasi yang mungkin, begitu saya memiliki pasangan.
algorithms
graphics
data-structures
computational-geometry
operating-systems
process-scheduling
algorithms
sorting
database-theory
relational-algebra
finite-model-theory
logic
automata
linear-temporal-logic
buchi-automata
complexity-theory
np-complete
decision-problem
machine-learning
algorithms
pattern-recognition
logic
formal-languages
formal-grammars
context-free
Ankit
sumber
sumber
Jawaban:
Salah satu cara langsung adalah prosedur rekursif yang melakukan hal berikut pada setiap doa. Input ke prosedur adalah daftar pasangan yang telah dipilih dan daftar semua pasangan.
Cara untuk memvisualisasikan algoritma ini adalah dengan pohon yang jalurnya adalah urutan pasangan yang tidak tumpang tindih. Tingkat pertama pohon berisi semua pasangan yang berisi 0. Untuk contoh di atas, pohonnya adalah
Dalam contoh ini semua jalur melalui pohon benar-benar memberikan koleksi yang benar, tetapi misalnya jika kita meninggalkan pasangan (1,2) maka jalur paling kanan hanya akan memiliki satu simpul dan akan sesuai dengan pencarian di langkah 3 gagal.
Algoritme pencarian tipe ini dapat dikembangkan untuk banyak masalah yang sama dalam penghitungan semua objek dari tipe tertentu.
Disarankan bahwa mungkin OP berarti bahwa semua pasangan berada di input, bukan hanya satu set dari mereka seperti yang dikatakan dalam pertanyaan. Dalam hal ini algoritma lebih mudah karena tidak perlu lagi memeriksa pasangan mana yang diperbolehkan. Bahkan tidak perlu untuk menghasilkan set semua pasangan; pseudocode berikut akan melakukan apa yang diminta OP. Di sini adalah nomor input, "daftar" dimulai sebagai daftar kosong, dan "tertutup" adalah array dengan panjang diinisialisasi ke 0. Ini bisa dibuat agak lebih efisien tetapi itu bukan tujuan langsung saya.nn n
sumber
Anda dapat membuat daftar semua pasangan dengan menelepon
sumber
Pembaruan : jawaban saya sebelumnya berkaitan dengan grafik bipartit, yang tidak ditanyakan oleh OP. Saya meninggalkannya untuk saat ini, sebagai info terkait. tetapi informasi yang lebih relevan berkaitan dengan pencocokan sempurna dalam grafik non-bipartit.
Dalam hal ini, ada survei yang bagus dari Propp yang menguraikan kemajuan (hingga 1999). Beberapa gagasan dalam artikel itu, dan tautan terkait, mungkin terbukti bermanfaat. TL; DR adalah - itu rumit :)
--- Mulai dari jawaban lama
Perhatikan bahwa yang Anda minta lakukan adalah menghitung semua kemungkinan pencocokan sempurna pada grafik bipartit. Ada banyak algoritma yang berbeda untuk melakukan ini, dan khususnya yang lebih baru adalah dari ISAAC 2001 .
Ide dasarnya adalah menemukan satu pencocokan sempurna dengan menggunakan aliran jaringan, dan kemudian berulang kali memodifikasi ini dengan menggunakan siklus bolak-balik (lihat bab algoritma buku teks tentang aliran jaringan untuk informasi lebih lanjut).
sumber
Setiap pasangan yang Anda pilih menghilangkan dua baris yang tidak dapat Anda pilih lagi. Ide ini dapat digunakan untuk mengatur algoritma rekursif (dalam Scala):
Ini tentunya dapat diekspresikan dengan cara yang lebih efisien. Secara khusus, gagasan tidak harus mempertimbangkan seluruh baris untuk kombinasi tidak digunakan oleh panggilan ke
filter
.sumber
Meskipun sudah ada banyak jawaban bagus untuk pertanyaan itu, saya pikir akan lebih baik untuk menunjukkan trik dasar, umum, di belakang mereka.
Jauh lebih mudah untuk menghasilkan kombinasi unik jika Anda dapat memiliki urutan total elemen yang akan digabungkan . Dengan cara ini, keunikan dijamin jika kami hanya mengizinkan kombinasi yang diurutkan. Tidak sulit untuk menghasilkan kombinasi yang diurutkan - cukup lakukan pencarian enumerasi brute force yang biasa, tetapi pada setiap langkah hanya pilih elemen yang lebih besar dari yang sudah diambil pada setiap langkah.
Komplikasi ekstra dalam masalah khusus ini adalah keinginan untuk mendapatkan hanya kombinasi panjang n / 2 (panjang maksimal). Ini tidak sulit dilakukan jika kita memutuskan strategi penyortiran yang bagus. Misalnya, seperti yang ditunjukkan dalam jawaban Carl Mummet, jika kita mempertimbangkan jenis leksikografis, (top-down, kiri-kanan dalam diagram dalam pertanyaan), kita memperoleh strategi untuk selalu mengambil elemen berikutnya sehingga digit pertamanya adalah nomor terkecil masih belum digunakan.
Kami juga dapat memperluas strategi ini jika kami ingin menghasilkan urutan panjang lainnya. Ingatlah bahwa setiap kali kita memilih elemen berikutnya yang nomor pertamanya bukan yang terkecil yang tersedia, kita mengesampingkan satu atau lebih barisan elemen agar tidak muncul pada urutan berikutnya, sehingga panjang maksimum praputasi akan berkurang.
sumber
sumber