算法设计实验五

实验五 利用回溯法解决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);
}

思考

上述背包问题的实现程序只是把所有的选择方法打印出来,并没有找到最大值? 试修改程序以打印出最大价值。

posted on 2012-02-11 15:15  wuqq  阅读(156)  评论(0)    收藏  举报