C语言实现--背包问题 算法(Knapsack Problem)
問題引入
????????假設有一個背包的負重最多可達8公斤,而希望在背包中裝入負重范圍內可得的相應總價物
品,假設物品是水果,水果的編號、單價與重量如下所示:
| 1 | 李子 | 4 | 4500 |
| 2 | 蘋果 | 5 | 5700 |
| 3 | 橘子 | 2 | 2250 |
| 4 | 草莓 | 1 | 1100 |
| 5 | 甜瓜 | 6 | 6700 |
????????請實現“如何最佳的選擇物品”實現背包負重允許下裝更多的物品?
問題分析
????????背包問題是關于最佳化的問題,要解最佳化問題可以使用「動態規劃」(Dynamic?programming),從空集合開始,每增加一個元素就先求出該階段的最佳解,直到所有的元素加?入至集合中,最后得到的就是最佳解。
????????以背包問題為例,我們使用兩個陣列value與item,value表示目前的最佳解所得之總價,item表?示最后一個放至背包的水果,假設有負重量?1~8的背包8個,并對每個背包求其最佳解。
逐步將水果放入背包中,并求該階段的最佳解:?
| 放入李子 | 背包 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 負重 | |||||||||
| value | 0 | 0 | 0 | 450 | 450 | 450 | 450 | 900 | |
| item | - | - | - | 0 | 0 | 0 | 0 | 0 | |
| 放入蘋果 | 背包 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 負重 | |||||||||
| value | 0 | 0 | 0 | 450 | 570 | 570 | 570 | 900 | |
| item | - | - | - | 0 | 1 | 1 | 1 | 0 | |
| 放入橘子 | 背包 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 負重 | |||||||||
| value | 0 | 225 | 225 | 450 | 570 | 675 | 795 | 900 | |
| item | - | 2 | 2 | 0 | 1 | 2 | 2 | 0 |
| 放入草莓 | 背包 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 負重 | |||||||||
| value | 110 | 225 | 335 | 450 | 570 | 680 | 795 | 905 | |
| item | 3 | 2 | 3 | 0 | 1 | 3 | 2 | 3 | |
| 放入甜瓜 | 背包 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 負重 | |||||||||
| value | 110 | 225 | 335 | 450 | 570 | 680 | 795 | 905 | |
| item | 3 | 2 | 3 | 0 | 1 | 3 | 2 | 3 |
????????由最后一個表格,可以得知在背包負重8公斤時,最多可以裝入9050元的水果,而最后一個裝入?的?水果是3號,也就是草莓,裝入了草莓,背包只能再放入7公斤(8-1)的水果,所以必須看?背包負重7公斤時的最佳解,最后一個放入的是2號,也就?是橘子,現在背包剩下負重量5公斤(7-2),所?以看負重5公斤的最佳解,最后放入的是1號,也就是蘋果,此時背包負重量剩下0公 斤(5-5),?無?法?再放入水果,所以求出最佳解為放入草莓、橘子與蘋果,而總價為9050元。
代碼實現
????????說明:采用C語言,編譯環境為DevC++。
#include <stdio.h> #include <stdlib.h> #define LIMIT 8//重量限制 #define N 5 //物品種類 #define MIN 1 //最小重量struct body {char name[20]; int size;int price; }; typedef struct body object;int main() {int item[LIMIT+1] = {0}; int value[LIMIT+1] = {0}; int newvalue, i, s, p;object a[] = {{"李子", 4, 4500},{"蘋果", 5, 5700},{"橘子", 2, 2250},{"草莓", 1, 1100},{"甜瓜", 6, 6700}};for(i = 0; i < N; i++){for(s = a[i].size; s <= LIMIT; s++){ p = s - a[i].size;newvalue = value[p] + a[i].price;if(newvalue > value[s]){ // 找到階段最佳解value[s] = newvalue; item[s] = i;}}}printf("物品\t價格\n");for(i = LIMIT; i >= MIN; i = i - a[item[i]].size){ printf("%s\t%d\n",a[item[i]].name, a[item[i]].price);}printf("合計\t%d\n", value[LIMIT]);return 0; }運行結果
寫在最后:
? ? ? ? 讀兩遍下來,如果仍然有不清楚的地方,可在評論區留言。
? ? ? ? 如果你有其他感到困惑的問題,歡迎留言。
總結
以上是生活随笔為你收集整理的C语言实现--背包问题 算法(Knapsack Problem)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端学习(83):按显示进行分类
- 下一篇: gateway权限统一认证