banner
NEWS LETTER

回朔法

Scroll down

利用回朔法求解 0-1 背包问题

我们有 n 种物品,物品 j 的重量为 wj,价格为 pj。我们假定所有物品的重量和价格都是非负的。背包所能承受的最大重量为 c。如果限定每种物品只能选择 0 个或 1 个。有六件物品,体积和价值见下表,背包容量为 25。

i 1 2 3 4 5 6
w(体积) 11 7 9 12 3 10
v(价值) 10 5 7 9 2 12

求解思想:

  1. 定义问题解空间;
  2. 确定易于搜索的解空间结构,该问题的解空间结构为子集树;

回朔法

  1. 采用深度优先方式搜索解空间,同时要及时剪枝,避免无效搜索。该问
    题的限界函数为:
    公式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
public class _01KnapsackProblem {
public int[] weight;
public int[] value;
public int[] take;

int curWeight = 0;
int curValue = 0;

int bestValue = 0;
int[] bestChoice;
int count;

int maxWeight = 0;

public void init(int[] weight, int[] value, int maxWeight) {
if (weight == null || weight.length == 0
|| value == null || value.length == 0
|| weight.length != value.length || maxWeight <= 0) {
System.out.println("输入数据有错!");
return;
}
this.value = value;
this.weight = weight;
this.maxWeight = maxWeight;
count = value.length;
take = new int[count];
bestChoice = new int[count];
}

public int[] maxValue(int x) {
//走到了叶子节点
if (x > count - 1) {
//更新最优解
if (curValue > bestValue) {
bestValue = curValue;
for (int i = 0; i < take.length; i++) {
bestChoice[i] = take[i];
}
}
} else {
//遍历当前节点(物品)的子节点:0 不放入背包 1:放入背包
for (int i = 0; i < 2; i++) {
take[x] = i;
if (i == 0) {
//不放入背包,接着往下走
maxValue(x + 1);
} else {
//约束条件,如果小于背包容量
if (curWeight + weight[x] <= maxWeight) {
//更新当前重量和价值
curWeight += weight[x];
curValue += value[x];
//继续向下深入
maxValue(x + 1);
//回溯法重要步骤,个人感觉也是精华所在。
// 当从上一行代码maxValue出来后,需要回溯容量和值
curWeight -= weight[x];
curValue -= value[x];
}
}
}
}
return bestChoice;
}
public static void main(String[] args) {
_01KnapsackProblem bt=new _01KnapsackProblem();
bt.init(new int[]{11,7,9,12,3,10},new int[]{10,5,7,9,2,12},25);
int[] result = bt.maxValue(0);
System.out.print("输出:\n"+"选择的物品是:");
for (int i = 0; i <=bt.bestChoice.length-1 ; i++) {
if (bt.bestChoice[i] == 1) {
System.out.print(i+1+",");
}
}
System.out.println("\n此时价值最大,即"+bt.bestValue);
}
}

运行结果:

运行结果:

参考链接1:https://blog.csdn.net/jarvischu/article/details/16067319

参考链接2:https://blog.csdn.net/u012545728/article/details/81746467?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522158616323419726869000059%2522%252C%2522scm%2522%253A%252220140713.130056874..%2522%257D&request_id=158616323419726869000059&biz_id=0&utm_source=distribute.pc_search_result.none-task-blog-all_SOOPENSEARCH-3

其他文章
cover
多段图问题
  • 25/09/27
  • 15:00
  • 687
  • 3
cover
Bootstrap
  • 25/09/27
  • 15:00
  • 4.3k
  • 21
目录导航 置顶
  1. 1. 利用回朔法求解 0-1 背包问题
    1. 1.0.1. 我们有 n 种物品,物品 j 的重量为 wj,价格为 pj。我们假定所有物品的重量和价格都是非负的。背包所能承受的最大重量为 c。如果限定每种物品只能选择 0 个或 1 个。有六件物品,体积和价值见下表,背包容量为 25。
    2. 1.0.2. 求解思想:
    3. 1.0.3. 运行结果:
    4. 1.0.4. 参考链接1:https://blog.csdn.net/jarvischu/article/details/16067319
    5. 1.0.5. 参考链接2:https://blog.csdn.net/u012545728/article/details/81746467?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522158616323419726869000059%2522%252C%2522scm%2522%253A%252220140713.130056874..%2522%257D&request_id=158616323419726869000059&biz_id=0&utm_source=distribute.pc_search_result.none-task-blog-all_SOOPENSEARCH-3