背包

背包

一、算法设计

目标函数

\[\sum_{j=1}^{n}v_jx_j \]

约束条件

\[\sum_{j=1}^{n}w_jx_j\leq W \quad\quad\quad\quad\sum_{j=1}^{n}c_jx_j\leq V \]

​ 约束条件有两个,一个是总重量小于等于W,另一个是总体积小于等于V

递推关系

\[F_k(y,z)=max\{F_k(y-w_k,z-c_k)+v_k,F_{k-1}(y,z)\} \\ \\ \]

​ F_k(y,z)表示前k种物品在重量限制y和体积限制z的共同作用下的最大价值。此时有两种情况,一种是不装第k种商品,它的总价值就和前(k-1)种物品在背包(y,z)情况下的总价值,即为F_k-1(y,z);另一种是装第k种商品,它的价值就为装此商品前的背包价值F(y-w,z-c)加上此物品的价值。

边界条件

\[F_0(y,z)=0\\ F_i(y,z)=0 \qquad y=0\quad or\quad z=0\\ F_1(y,z)=min\{\lfloor y/w_1 \rfloor,\lfloor z/c_1 \rfloor\}*v_1 \]

​ 背包没有商品时,价值为0。当重量或体积约束为0时,价值也为0。第一种物品的数量要同时考虑到重量和体积的约束,所以要选最小值。其中还要注意y,z需要大于0,否则在边界位置没有意义。

标记函数

\[i_k(y,z)=\begin{cases} i_{k-1}(y,z) && F_{k-1}(y,z)>F_k(y-2_k,z-c_k)+v_k\\ k && F_{k-1}\leq F_k(y-w_k,z-c_k)+v_k \end{cases} \]

二、算法实现

随机生成数据

import numpy as np
num=20
min=1
max=20min
a=np.random.randint(min,max,(num,3))
np.savetxt("data.txt",a,fmt="%d",delimiter=' ')

​ 物品的的种类为num,随机生成num行3列的数组,第一列为价值,第二列为重量,第三列为体积。存入'data.txt'文件里

取数据,并初始化

	a=np.array([[0,0,0]],dtype=np.int)
    b=np.loadtxt("data.txt",delimiter=' ',dtype=np.int)
    a=np.append(a,b,axis=0)
    F=np.zeros((a[:,0].size,W+1,V+1),dtype=np.int)
    for i in range(0,W+1):
        for j in range(0,V+1):
            F[1,i,j]=min(i//a[1,1],j//a[1,2])*a[1,0]
    i=np.zeros((a[:,0].size,W+1,V+1),dtype=np.int)

​ 由于有边界条件,所以数据要从第一行开始存。F的大小为物品种类总体积总重量*,同时因为边界调节,每个坐标轴都要+1。标记数组i都要初始化为0(其实只有边界需要初始化,但是反正创建数组时都要初始化,就初始化一下吧)

优化数组

 for k in range(1,a[:,0].size):
        for y in range(1,W+1):
            if y<a[k,1]:
                F[k,y,:]=F[k-1,y,:]
                continue
            for z in range(1,V+1):
                if z<=a[k,2]:
                    F[k,y,z]=F[k-1,y,z]
                    continue
                F[k,y,z]=max(F[k,y-a[k,1],z-a[k,2]]+a[k,0],F[k-1,y,z])

​ y和z在0的时候没有意义,所以从一开始。注意y和z需要大于0,所以不满足的情况要跳过。

标记数组

    for k in range(1,a[:,0].size):
        for y in range(1, W+1):
            if y < a[k, 1]:
                i[k,y,:]=i[k-1,y,:]
                continue
            for z in range(1, V+1):
                if z <= a[k, 2]:
                    i[k,y,z]=i[k-1,y,z]
                    continue
                if F[k-1,y,z]>F[k,y-a[k,1],z-a[k,2]]+a[k,0]:
                    i[k,y,z]=i[k-1,y,z]
                else:
                    i[k,y,z]=k

​ 和优化数组的要点一样,y和z要从1开始。不满足y和z大于0的情况要跳过。

追踪过程

 	x=np.zeros(a[:,0].size,dtype=np.int)
    y=W
    z=V
    k=a[:,0].size-1
    while(i[k,y,z]!=0):
        j=i[k,y,z]
        x[j]=1
        y-=a[j,1]
        z-=a[j,2]
        while(i[j,y,z]==j):
            y -= a[j, 1]
            z -= a[j, 2]
            x[j]+=1

三、算法分析

数据及结果

  v,w,c
[[7 6 7]
 [4 5 1]
 [7 7 2]
 [5 7 1]
 [7 5 5]]

重量限制 10 体积限制 15
第 5 件物品 2 件
总价值为 14

优化函数

[[[ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]]

 [[ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  7  7  7  7  7  7  7  7  7]
  [ 0  0  0  0  0  0  0  7  7  7  7  7  7  7  7  7]
  [ 0  0  0  0  0  0  0  7  7  7  7  7  7  7  7  7]
  [ 0  0  0  0  0  0  0  7  7  7  7  7  7  7  7  7]
  [ 0  0  0  0  0  0  0  7  7  7  7  7  7  7  7  7]]

 [[ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  4  4  4  4  4  4  4  4  4  4  4  4  4  4  4]
  [ 0  4  4  4  4  4  4  7  7  7  7  7  7  7  7  7]
  [ 0  4  4  4  4  4  4  7  7  7  7  7  7  7  7  7]
  [ 0  4  4  4  4  4  4  7  7  7  7  7  7  7  7  7]
  [ 0  4  4  4  4  4  4  7  7  7  7  7  7  7  7  7]
  [ 0  4  8  8  8  8  8  8  8  8  8  8  8  8  8  8]]

 [[ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  4  4  4  4  4  4  4  4  4  4  4  4  4  4  4]
  [ 0  4  4  4  4  4  4  7  7  7  7  7  7  7  7  7]
  [ 0  4  7  7  7  7  7  7  7  7  7  7  7  7  7  7]
  [ 0  4  7  7  7  7  7  7  7  7  7  7  7  7  7  7]
  [ 0  4  7  7  7  7  7  7  7  7  7  7  7  7  7  7]
  [ 0  4  8  8  8  8  8  8  8  8  8  8  8  8  8  8]]

 [[ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  4  4  4  4  4  4  4  4  4  4  4  4  4  4  4]
  [ 0  4  4  4  4  4  4  7  7  7  7  7  7  7  7  7]
  [ 0  5  7  7  7  7  7  7  7  7  7  7  7  7  7  7]
  [ 0  5  7  7  7  7  7  7  7  7  7  7  7  7  7  7]
  [ 0  5  7  7  7  7  7  7  7  7  7  7  7  7  7  7]
  [ 0  5  8  8  8  8  8  8  8  8  8  8  8  8  8  8]]

 [[ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
  [ 0  4  4  4  4  7  7  7  7  7  7  7  7  7  7  7]
  [ 0  4  4  4  4  7  7  7  7  7  7  7  7  7  7  7]
  [ 0  5  7  7  7  7  7  7  7  7  7  7  7  7  7  7]
  [ 0  5  7  7  7  7  7  7  7  7  7  7  7  7  7  7]
  [ 0  5  7  7  7  7  7  7  7  7  7  7  7  7  7  7]
  [ 0  5  8  8  8  8 11 11 11 11 14 14 14 14 14 14]]]

标记函数

[[[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]]

 [[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1]
  [0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1]
  [0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1]
  [0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1]
  [0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1]]

 [[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]
  [0 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1]
  [0 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1]
  [0 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1]
  [0 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1]
  [0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]]

 [[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]
  [0 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1]
  [0 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3]
  [0 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3]
  [0 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3]
  [0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]]

 [[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]
  [0 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1]
  [0 4 3 3 3 3 3 3 3 3 3 3 3 3 3 3]
  [0 4 3 3 3 3 3 3 3 3 3 3 3 3 3 3]
  [0 4 3 3 3 3 3 3 3 3 3 3 3 3 3 3]
  [0 4 2 2 2 2 2 2 2 2 2 2 2 2 2 2]]

 [[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  [0 2 2 2 2 5 5 5 5 5 5 5 5 5 5 5]
  [0 2 2 2 2 5 5 5 5 5 5 5 5 5 5 5]
  [0 4 3 3 3 5 5 5 5 5 5 5 5 5 5 5]
  [0 4 3 3 3 5 5 5 5 5 5 5 5 5 5 5]
  [0 4 3 3 3 5 5 5 5 5 5 5 5 5 5 5]
  [0 4 2 2 2 2 5 5 5 5 5 5 5 5 5 5]]]

四、时间复杂度分析

运行时间

W=100	#约束条件
V=150
mi=1   #价格体积重量数据的范围
ma=10

因为此题的可变条件较多,所以我就选择了一个最不受干扰的数据———物品种类来做分析。由此可见,运行时间基本和物品种类成线性关系。

时间复杂度

​ O(nWV),表面上开始这样的。但是同书上所说其实和W、V在电脑中占的存储空间有关,所以未伪多项式时间。但如同我上面的图片所示。在附加数据不变的情况下,基本与物品种类n成正比

posted @ 2020-12-09 19:18  小夏的魔仙堡  阅读(78)  评论(0编辑  收藏  举报