算法设计实验五
实验五 利用回溯法解决0-1背包问题
实验目的
掌握回溯法的算法框架(子集树框架);
利用回溯法解决0-1背包问题.
实验内容
1. 回溯法的算法框架(子集树框架)
void backtrack(int t) {
if (t == N) {
output();
} else {
x[t] = 0;
if (legal(t)) backtrack(t + 1);
x[t] = 1;
if (legal(t)) backtrack(t + 1);
}
}
2. 子集算法
问题描述:设一个集合有 N 个元素,试打印出这个集合的所有子集。
参考实现:
#include <stdio.h>
#include <stdlib.h>
#define N 5
int a[] = {1, 2, 3, 4, 5};
int x[N];
void output() {
int i;
printf(" { ");
for (i = 0; i < N; i++)
if (x[i]) printf("%d, ", a[i]);
printf("}\n");
}
void backtrack(int t) {
if (t == N) {
output();
} else {
x[t] = 0;
backtrack(t + 1);
x[t] = 1;
backtrack(t + 1);
}
}
int main() {
backtrack(0);
}
2. 0-1背包问题
问题描述:给定 N 个物品,物品 i 的重量是weights[i], 其价值为prices[i],背包容量为 CAPACITY ,问如何选择装入背包中的物品,使得装入背包中的物品其总价值最大?
参考实现:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 3
#define CAPACITY 30
int weights[N] = {16, 15, 15}; // 重量
int prices[N] = {45, 25, 25}; // 价值
int x[N]; // 选择结果
void output() {
int i, sum = 0;
for (i = 0; i < N; i++)
if (x[i]) {
sum += prices[i];
printf(" %d ", i);
}
printf(" \t-> %d\n", sum);
}
// 如果合法返回1, w为当前背包所放物品的重量和。
int legal(int t, int w) {
return w <= CAPACITY;
}
int backtrack(int t, int w) {
if (t == N) {
output();
} else {
x[t] = 0;
if (legal(t, w)) backtrack(t + 1, w);
x[t] = 1; w += weights[t];
if (legal(t, w)) backtrack(t + 1, w);
}
}
void main() {
trackback(0, 0);
}
思考
上述背包问题的实现程序只是把所有的选择方法打印出来,并没有找到最大值? 试修改程序以打印出最大价值。
浙公网安备 33010602011771号