算法分析与设计实验报告——0-1背包问题的动态规划算法实现

算法分析与设计实验报告——0-1背包问题的动态规划算法实现

目录:

  • 算法分析与设计实验报告——0-1背包问题的动态规划算法实现
    • 一、 实验目的
    • 二、实验要求
    • 三、 实验原理
    • 四、 实验过程(步骤)
    • 五、 运行结果
    • 六、实验分析与讨论
    • 七、实验特色与心得
    • 附件一 实验过程(步骤)
    • 附件二 运行结果

一、 实验目的

掌握动态规划的基本思想和解决问题的基本步骤,认识动态规划和分治法的联系与区别,对比解决同一问题的两种算法设计策略的时间复杂性。

二、实验要求

用c++语言实现用动态规划算法解决0-1背包问题,分析时间复杂性,体会动态规划算法解决问题的基本思路和步骤。

三、 实验原理

0-1 背包问题具有最优子结构性质,可以据此定义递归关系,建立递归方程,并以自底向上的方式计算最优值,根据计算最优值时的得到的信息,构造最优解。
设所给 0-1 背包问题的子问题的最优值 m(i,j) ,即 m(i,j) 是背包重量为 j ,可选物品为 i,i+1,…,n-1 时的最优值。由最优子结构性质,可以计算出 m(i,j) 的递归式如下:
在这里插入图片描述
在这里插入图片描述

四、 实验过程(步骤)

见附件一
实验步骤、特点
重要源代码(流操作的部分要醒目的提示并注释)

五、 运行结果

见附件二

六、实验分析与讨论

刚开始运行并没有得到最优解,经过检查程序发现有一个判断条件出错了,修改后结果依然不变,再次阅读程序没有发现问题,然后开始查阅课本,再重新理解一下这个问题。思考后想到了数组的范围设置错误,导致了结果偏移的问题。修改后结果得到了最优解。

七、实验特色与心得

0-1 背包问题具有最优子结构性质,所以可以用动态规划方法求解。根据这种性质定义递归关系并建立递归方程,以自底向上的方式计算最优值。而且以后编程时要彻底理解问题后再构造算法。

附件一 实验过程(步骤)

#include 
#define maxn 100
using namespace std;
void Knapsack(int *v, int *w, int c, int n, int (*m)[maxn]) {
    //先判断第n个物品能不能装入背包
    int jMax = min(w[n] - 1, c);
    //当0<=j<=wn时,m(n,j)=0
    for (int j = 0; j <= jMax; j++) {
        m[n][j] = 0;
    }
    //当j>=wn时,m(n,j)=vn
    for (int j = w[n]; j <= c; j++) {
        m[n][j] = v[n];
    }
    //再从n-1往前开始判断第n个物品到第i个物品能不能装下
    for (int i = n - 1; i > 1; i--) {
        jMax = min(w[i] - 1, c);
        for (int j = 0; j < jMax; j++) {
            m[i][j] = m[i + 1][j];
        }
        for (int j = w[i]; j <= c; j++) {
            m[i][j] = max(m[i + 1][j], m[i + 1][j - w[i]] + v[i]);
        }

    }
    //判断第n个到第1个物品能不能装下
    m[1][c] = m[2][c];
    if (c >= w[1])
        m[1][c] = max(m[1][c], m[2][c - w[1]] + v[1]);
}

//回溯查找最优序列,能装下的赋值为1,不能装下的赋值为0
void Traceback(int (*m)[maxn], int *w, int c, int n, int *x) {
    for (int i = 1; i < n; i++) {
        if (m[i][c] == m[i + 1][c])
            x[i] = 0;
        else {
            x[i] = 1;
            c -= w[i];
        }
    }
    x[n] = (m[n][c]) ? 1 : 0;
}
int main() {
    //进行数据输入
    int n, c;
    cout << "请输入物品数量 n=";
    cin >> n;
    cout << "请输入背包容量 c=";
    cin >> c;
    int w[n];
    cout << "请依次输入各物品的重量:";
    for (int i = 1; i <= n; i++) {
        cin >> w[i];
    }
    int v[n];
    cout << "请依次输入各物品的价值:";
    for (int i = 1; i <= n; i++) {
        cin >> v[i];
    }
    int m[maxn][maxn];
    int x[n];
    int max_weight = 0;
    int max_value = 0;
    //进行查找与回溯
    Knapsack(v, w, c, n, m);
    Traceback(m, w, c, n, x);
    //输出最优序列和最优重量与最优价值
    cout << "最优装载序列为:\n";
    for (int i = 1; i <= n; i++) {
        printf("%d ", x[i]);
        max_weight += (x[i] * w[i]);
        max_value += (x[i] * v[i]);
    }
    cout << endl;
    printf("最大重量为: %d\n最大价值为: %d\n", max_weight, max_value);
    return 0;
}
/*
5
10
2 2 6 5 4
6 3 5 4 6
*/

附件二 运行结果

算法分析与设计实验报告——0-1背包问题的动态规划算法实现_第1张图片

你可能感兴趣的:(算法实验笔记,算法,动态规划,c++)