ภาพรวม
โปรแกรม C++ นี้แก้ปัญหา 0-1 Knapsack Problem โดยใช้ Dynamic Programming กำหนดให้มีชิ้นส่วน n ชิ้น แต่ละชิ้นมีน้ำหนัก (weight) และค่า (value) ต้องเลือกชิ้นส่วนใดบ้างเพื่อให้ค่ารวมมากที่สุด โดยน้ำหนักรวมไม่เกินความจุกระเป๋า (W) แต่ละชิ้นเลือกได้สูงสุด 1 ชิ้น (0-1)
อัลกอริธึม Dynamic Programming
- สร้างตาราง DP ขนาด
(n+1) x (W+1)โดยdp[i][w]= ค่าสูงสุดที่ได้จาก i ชิ้นแรก ด้วยความจุ w - Base case:
dp[0][w] = 0,dp[i][0] = 0 - Transition:
- ถ้า
weight[i-1] <= w:dp[i][w] = max(value[i-1] + dp[i-1][w-weight[i-1]], dp[i-1][w]) - ถ้า
weight[i-1] > w:dp[i][w] = dp[i-1][w]
- ถ้า
- คำตอบอยู่ที่
dp[n][W]
โค้ดตัวอย่าง
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int knapSack(int W, const vector& wt, const vector& val, int n) {
vector> dp(n + 1, vector(W + 1, 0));
for (int i = 1; i <= n; i++) {
for (int w = 1; w <= W; w++) {
if (wt[i-1] <= w) {
dp[i][w] = max(val[i-1] + dp[i-1][w - wt[i-1]], dp[i-1][w]);
} else {
dp[i][w] = dp[i-1][w];
}
}
}
return dp[n][W];
}
int main() {
int n, W;
cout << "Enter the number of items in a Knapsack: ";
cin >> n;
vector val(n), wt(n);
for (int i = 0; i < n; i++) {
cout << "Enter value and weight for item " << i << ": ";
cin >> val[i] >> wt[i];
}
cout << "Enter the capacity of knapsack: ";
cin >> W;
cout << "\nMaximum value: " << knapSack(W, wt, val, n);
return 0;
}
ผลลัพธ์ตัวอย่าง
Enter the number of items in a Knapsack: 4
Enter value and weight for item 0: 10 50
Enter value and weight for item 1: 20 60
Enter value and weight for item 2: 30 70
Enter value and weight for item 3: 40 90
Enter the capacity of knapsack: 100
Maximum value: 40
การเพิ่มเติม: แสดงรายการที่เลือก
// หลังคำนวณ dp เสร็จ ให้ trace back:
int w = W;
for (int i = n; i > 0 && w > 0; i--) {
if (dp[i][w] != dp[i-1][w]) {
cout << "Item " << i-1 << " (value=" << val[i-1] << ", weight=" << wt[i-1] << ") selected\n";
w -= wt[i-1];
}
}
ความซับซ้อน
- เวลา: O(nW) - Pseudo-polynomial (ขึ้นอยู่กับค่า W ไม่ใช่แค่ n)
- พื้นที่: O(nW) - สามารถลดเหลือ O(W) ได้โดยใช้ 1D array
- ข้อจำกัด: W ใหญ่เกินไปจะกินหน่วยความจำมาก