Bagaimana cara mempartisi suatu himpunan ke dalam sejumlah himpunan bagian terputus yang tunduk pada beberapa kondisi?

11

Saya diberi himpunan , integer , dan integer non-negatif a_ {ij} . Masalah saya adalah menemukan s himpunan bagian himpunan S_j dari \ {1, \ ldots, k \} sedemikian rupa sehingga:A{1,,k}skaijsSj{1,,k}

  1. j=1sSj=A ; dan
  2. |Sj|aij untuk semua iSj dan j=1,,s .

Bagaimana cara mengatasi masalah ini? Apakah sulit menemukan solusi yang layak?

Saya pikir itu tidak mudah untuk menyelesaikan masalah karena saya mencoba beberapa prosedur yang dimulai oleh beberapa j{1,,n} dan menetapkan i{1,,k} hingga angka of i ditugaskan ke j lebih besar dari aij untuk beberapa i ditugaskan. Tetapi ini tidak benar karena saya dapat meninggalkan beberapa i yang tidak dapat ditugaskan ke j (karena aij yang tidak dapat dipenuhi).

Metode brute force, ketika saya harus menghasilkan semua himpunan bagian A dan menguji masing-masing, bekerja untuk saya ( k=8,n=3 ) tetapi sangat tidak efisien.

drzbir
sumber
Periksa apakah hasil edit sesuai dengan pertanyaan yang ingin Anda tanyakan. Juga, dari mana berasal? Apakah itu konstanta tetap (bukan bagian dari input, tetapi tetap untuk semua waktu), atau apakah itu bagian dari input? Akhirnya, apakah Anda mencari solusi praktis? atau Anda mencari kompleksitas teoretis dari masalah ini? Jika yang pertama, sudahkah Anda mencoba menggunakan integer linear programming? amax
DW

Jawaban:

10

Masalah ini NP-keras dengan reduksi dari Vertex Cover.

Dalam masalah Vertex Cover, kita diberi grafik dan sejumlah , dan tugas kita adalah untuk menentukan apakah ada beberapa subset paling banyak simpul dari sehingga setiap tepi dalam adalah kejadian pada setidaknya satu titik di . (Setara: Apakah mungkin untuk membunuh setiap sisi dalam dengan menghapus paling banyak simpul?)G=(V,E)rUrVEUGr

Pertama, partisi menjadi himpunan bagian menguraikan setara dengan menugaskan setiap elemen dalam tepat satu dari label mungkin. Ide dasar reduksi adalah untuk membuat label untuk setiap vertex di , dan untuk "memungkinkan" setiap sisi diberi hanya satu dari dua label yang sesuai dengan titik akhir, dalam arti berikut: menetapkan tepi yang sesuai label tidak memperkenalkan batasan (asli) pada tepi mana yang dapat diberi label yang sama, sementara menetapkan tepi pada label yang tidak sesuai mencegah tepi lainnya diberi label yang sama - yang tentu saja memiliki efek mendorong nomor tersebut diperlukan label berbeda.AsAsSjvjV

Untuk membuat instance masalah Anda dari instance Vertex Cover:(A,a,s)(G,r)

  1. Set ke, Dan menciptakan sebuah elemen di untuk setiap tepi di . (Pasangan-pasangan ini dapat dianggap sebagai bilangan bulat ; setiap penambangan di antara keduanya akan dilakukan.)k|E|(i,j)AvivjE1,,k
  2. Set kejika atau ; jika tidak, atur ke 1.a(b,c),d|E|d=bd=ca(b,c),d
  3. Set .s=r

Jika adalah turunan YA dari Vertex Cover, maka mudah untuk melihat bahwa turunan yang baru saja dibangun dari masalah Anda juga merupakan turunan YA: cukup pilih label sesuai dengan simpul dalam solusi apa pun , dan untuk setiap sisi menetapkan elemen yang sesuai mana yang salah satu dari label atau dipilih (pilih secara sewenang-wenang jika kedua label diambil). Solusi ini menggunakan himpunan bagian , dan valid karena satu-satunya berlaku adalah yang sesuai(G,r)SjvjUvbvcE(b,c)ASbScsaijlabel, yang memiliki efek (non-) mencegah lebih daritepi diberi label yang sama.|E|

Tetap menunjukkan bahwa YA-instance dari masalah Anda menyiratkan bahwa yang asli adalah instance-YA dari Vertex Cover. Hal ini sedikit lebih rumit, karena solusi yang valid ke mungkin dalam menetapkan umum tepi seorang non label -corresponding , yaitu, , yang berarti bahwa kita tidak bisa tentu "membacakan" penutup simpul yang valid dari solusi yang valid .X=(A,a,s)(G,r)YX(i,j)Smm{i,j}UY

Namun, menetapkan label yang tidak sesuai memiliki biaya tinggi yang sangat membatasi struktur solusi: setiap kali tepi diberikan label seperti , dengan , faktanya bahwa memastikan bahwa itu harus menjadi satu - satunya tepi yang ditetapkan label ini. Jadi, dalam setiap solusi mengandung tepi yang tidak berlabel yang sesuai , kita dapat membuat solusi alternatif sebagai berikut:(i,j)Smm{i,j}a(i,j),m=1Y(i,j)SmY

  1. Secara sewenang-wenang pilih label baru untuk sebagai atau .Sz(i,j)SiSj
  2. Tetapkan label baru ini. Jika ini menghasilkan solusi yang tidak valid, itu pasti karena tepat satu sisi lainnya , telah diberi label . Dalam hal ini, atur dan lanjutkan ke langkah 1.(i,j)(i,j)z{i,j}Sz(i,j)=(i,j)

Algoritme di atas harus diakhiri dengan salah satu dari dua cara: label baru ditemukan yang tidak menimbulkan kontradiksi, atau siklus lengkap simpul ditemukan. Dalam kasus sebelumnya, ditemukan solusi baru yang valid dengan set , sedangkan pada kasus yang kedua ditemukan solusi baru yang valid dengan set ; Bagaimanapun, kami telah membangun solusi baru yang valid dengan setidaknya satu keunggulan lagi ditetapkan untuk label yang sesuai . Setelah mengulangi seluruh proses ini paling banyakkali, kami akan menghasilkan solusi yang valid dari mana solusi untuk masalah Vertex Cover asli dapat dibacakan.Szs1s|E|Y

Konstruksi ini jelas merupakan waktu polinomial, sehingga masalah Anda adalah NP-hard.

j_random_hacker
sumber
Terima kasih untuk bantuannya. Apakah Anda tahu bagaimana cara memecahkan (kira-kira) masalah ini? (Seperti, misalnya, bisakah saya menggunakan teknik untuk mengatasi masalah vertex untuk menyelesaikannya?) Saya mencoba beberapa pendekatan serakah tetapi, kadang-kadang, gagal menghasilkan solusi yang layak. (Cara saya memilih membuat pendekatan serakah gagal di mana solusi bisa ada.)Sj
drzbir
Yah, diharapkan bahwa pendekatan serakah kadang-kadang akan gagal menghasilkan solusi yang layak, karena jika selalu demikian, Anda akan memecahkan masalah NP-hard dalam waktu-poli ;-) Ingat bahwa itu tidak selalu salah jika tidak bisa temukan solusinya: mungkin saja tidak ada solusi yang layak.
j_random_hacker
Mengenai teknik solusi, yang saya sukai disebut pencarian balok. Ini pada dasarnya adalah semacam cabang-dan-terikat yang "lupa" solusi parsial yang cukup buruk untuk membatasi penggunaan memorinya. (B&B itu sendiri merupakan pendekatan yang sangat baik, dan kadang-kadang menyelesaikan masalah dengan cepat, dan ini sedikit lebih sederhana daripada pencarian balok sehingga layak dicoba - tetapi karena ini adalah metode yang tepat, tentu saja dapat mengambil ribuan tahun dalam beberapa kasus.)
j_random_hacker
(Semua hal di bawah ini berlaku juga untuk pencarian balok serta B&B.) B&B adalah teknik yang sangat umum. Kuncinya adalah dengan mengeksploitasi spesifik masalah untuk mengatur keputusan yang Anda buat sehingga, sebanyak mungkin, keputusan yang buruk (yaitu, keputusan yang tidak mengarah pada solusi yang layak) dibuat di awal pohon pencarian. (Keputusan-keputusan ini akan dibuat di suatu tempat , dan setiap tingkat yang lebih dalam yang mereka buat akan berlipat ganda berapa kali mereka dibuat.) Untuk masalah Anda, saya sarankan pertama peringkat elemen-elemen dalam dalam mengurangi urutan "kejahatan", di mana. ..A
j_random_hacker
... kejahatan elemen bisa jadi, misalnya, minimum atas semua , memutus ikatan dengan minimum kedua, lalu minimum ketiga, dll. Secara kasar, elemen "terburuk" akan menjadi elemen yang paling parah membatasi set apa pun yang ditambahkan padanya. Pada setiap node pada kedalaman di pohon pencarian, Anda akan memiliki solusi parsial di mana elemen pertama (dan dengan demikian "terburuk") telah ditugaskan untuk ditetapkan; Anda harus memilih set yang mana untuk menetapkan elemen untuk: yaitu, Anda akan memerlukan hingga panggilan rekursif. ("Hingga" karena mudah-mudahan kita punya, ...iaijjddn(d+1)n
j_random_hacker