Saya mengalami masalah di mana tujuannya adalah menggunakan pemrograman dinamis (bukan pendekatan lain). Ada jarak yang harus direntang, dan satu set kabel dengan panjang yang berbeda. Berapa jumlah minimum kabel yang dibutuhkan untuk menjangkau jarak dengan tepat?
Bagi saya ini tampak seperti masalah ransel , tetapi karena mungkin ada kelipatan dari panjang tertentu, itu adalah masalah ransel terikat, bukan masalah ransel 0/1. (Perlakukan nilai setiap item menjadi bobotnya.) Mengambil pendekatan naif (dan tidak peduli tentang perluasan ruang pencarian), metode yang saya gunakan untuk mengubah masalah ransel terikat menjadi masalah ransel 0/1, cukup sederhana pisahkan kelipatan menjadi lajang dan terapkan algoritma pemrograman dinamis yang terkenal. Sayangnya, ini mengarah pada hasil yang kurang optimal.
Misalnya, kabel yang diberikan:
1 x 10 kaki,
1 x 7 kaki,
1 x 6 kaki,
5 x 3 kaki,
6 x
2 kaki , 7 x 1 kaki
Jika rentang target 13ft, algoritma DP memilih 7 + 6 untuk rentang jarak. Algoritma serakah akan memilih 10 + 3, tetapi ini adalah seri untuk jumlah minimum kabel. Masalah muncul, ketika mencoba span 15ft. Algoritma DP akhirnya memilih 6 + 3 + 3 + 3 untuk mendapatkan 4 kabel, sedangkan algoritma serakah dengan benar memilih 10 + 3 + 2 hanya untuk 3 kabel.
Ngomong-ngomong, melakukan beberapa pemindaian ringan dari konversi yang dibatasi ke 0/1, sepertinya pendekatan yang terkenal untuk mengubah banyak item menjadi {p, 2p, 4p ...}. Pertanyaan saya adalah bagaimana cara kerja konversi ini jika p + 2p + 4p tidak menambah jumlah beberapa item. Sebagai contoh: Saya memiliki 5 kabel 3ft. Saya tidak bisa menambahkan {3, 2x3, 4x3} karena 3 + 2x3 + 4x3> 5x3. Haruskah saya menambahkan {3, 4x3}?
[Saat ini saya mencoba untuk membaca kertas "Oregon Trail Knapsack Problem", tetapi saat ini sepertinya pendekatan yang digunakan tidak ada pemrograman yang dinamis.]
sumber
Jawaban:
Mungkin ada beberapa kesalahan dalam kode Anda. Saya menulis program DP seperti yang disebutkan oleh Naryshkin. Untuk rentang target 13, ia melaporkan 6 + 7, dan untuk 15, ia melaporkan 2 + 6 + 7.
Jika Anda menyesuaikan urutan panjang input, ini dapat memberikan solusi optimal lainnya. Misalnya,
lens = 5*[3] + 6*[2] + 7*[1] + [10, 7, 6]
akan memberi 15 = 10 + 2 + 3.sumber
Cara yang saya lihat digunakan untuk mengubah masalah knapsack terikat menjadi 0/1 adalah dengan hanya memiliki beberapa item yang identik. Katakan jika Anda memiliki item berikut (diberikan sebagai berat, utilitas):
Anda akan mengubahnya menjadi masalah 0/1 menggunakan item dengan
Dan gunakan algoritma 0/1 untuk menyelesaikannya. Anda mungkin akan memiliki beberapa solusi dengan kebenaran yang sama sehingga Anda memilih yang sewenang-wenang.
Sekarang tentang masalah kawat Anda: Saya akan memiliki panjang kabel menjadi bobot dan nilai masing-masing kabel sama persis (sebut saja 1, meskipun ada nilai positif akan bekerja). Sekarang, gunakan algoritma penyelesaian Knapsack favorit Anda tetapi di mana Anda biasanya memilih solusi (parsial) yang memaksimalkan nilai, pilih salah satu yang meminimalkan itu. Selain itu, abaikan semua solusi yang tidak memiliki bobot total yang sama dengan kapasitas. Saya mungkin dapat (mencoba) menulis algoritma yang lebih konkret dengan kode aktual jika ada yang menginginkannya.
sumber