动态规划-0-1背包问题

版权声明:转载请注明出处。 https://blog.csdn.net/baidu_38304645/article/details/83792573

给定n个物品和一个背包。物品i的重量为wi,价值为vi,背包容量为c。问如何选择装入背包中的物品,使得装入背包的物品的价值最大?在装入背包时,每种物品i只有两种选择,装入或者不装入,既不能装入多次,也不能只装入一部分。

因此,此问题称为0-1背包问题.0-1背包问题是一个特殊的整数规划问题。

输入:物品的数目n,背包的容量c。各个物品的重量wi,各个物品的价值vi。

输出:装入背包的最大价值。各个物品是否装入背包,装入输出1,不装入输出0.

运行结果:

0-1背包问题的形式描述:

问题的形式描述是:给定c0wi0,vi01≤i≤n,求n0-1向量(x1, x2, , xn),使得

背包问题的最优子结构性质:

(y1, y2, , yn)是所给0-1背包问题的一个最优解,则(y2, , yn)是下面对应问题的最优解:

n否则,设(z2, , zn)是最优解,则(y1, z2, , zn)是原问题的最优解,而(y1, y2, , yn)不是最优解。矛盾.、

设所给0-1背包问题的子问题

其最优解为m(i, j),即背包容量为j,可选择物品为i, i+1, , n0-1背包问题的最优解,则

0-1背包问题的递归算法:

用二维数组m[i][j], 0≤j≤c, 存储m(i, j)的值。

求解0-1背包问题就是在二维数组m中填入相应的值。

m[1][c]中的值就是该背包问题的解。

在二维数组m中最先填入的应该是哪些呢?

二维数组m最先填入只能选择物品n的最优解m(n, j)

0≤jwnm[n][j]=0

 若   j≥wnm[n][j]=vn

n然后从物品n1物品1逐个填入它们的最优解m(i, j)

n0≤jwim[i][j]= m[i+1][j]; 

nj≥wi,   m[i][j]=max{m[i+1][j], m[i+1][jwi]+vi}

template <class Type>
void Knapsack(Type *v, int *w, int c, int n, Type m[][maxn])
{
    int i, j, jMax;

    jMax = min(w[n]-1, c);
    for(j = 0; j <= jMax; j++)
        m[n][j] = 0;
    for(j = w[n]; j <= c; j++)
        m[n][j] = v[n];
    for(i = n-1; i > 1; i--)
    {
        jMax = min(w[i]-1, c);
        for(j = 0; j <= jMax; j++)
            m[i][j] = m[i+1][j];
        for(j = w[i]; j <= c; j++)
            m[i][j] = max(m[i+1][j], m[i+1][j-w[i]] + v[i]);
    }

    m[1][c] = m[2][c];
    if(c >= w[1])
        m[1][c] = max(m[2][c], m[2][c-w[1]] + v[1]);
}

算法Traceback计算相应的最优解

若m[1][c]=m[2][c],则x1=0,否则x1=1.

当x1=0时,由m[2][c]继续构造最优解。当x1=1时,由m[2][c-w1]继续构造最优解。依次类推,可构造出相应的最优解(x1,x2,.....xn)

template <class Type>
void Traceback(Type m[][maxn], int *w, int c, int n, int *x)
{
    int i;

    for(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;
}

0-1背包问题算法的复杂性:

从算法中可以看出,对每个物品i要填入m[i][1], m[i][2], , m[i][c]n个物品共要填写nc个,因此整个算法的时间复杂性是O(nc)

此算法在背包容量c很大时所需的计算时间量很大。如c=2n,则算法的复杂性为O(n2n)。

算法的不足:要求物品的重量wi是整数,而不能为实数。

猜你喜欢

转载自blog.csdn.net/baidu_38304645/article/details/83792573