(转载加改写)背包问题及网易CPU双核调度问题

来源:互联网 发布:郭德纲网络节目 编辑:程序博客网 时间:2024/06/04 19:07

01背包问题,是用来介绍动态规划算法最经典的例子,网上关于01背包问题的讲解也很多,我写这篇文章力争做到用最简单的方式,最少的公式把01背包问题讲解透彻。

01背包的状态转换方程 f[i,j] = Max{ f[i-1,j-Wi]+Pi( j >= Wi ),  f[i-1,j] }

f[i,j]表示在前i件物品中选择若干件放在承重为 j 的背包中,可以取得的最大价值。
Pi表示第i件物品的价值。
决策:为了背包中物品总价值最大化,第 i件物品应该放入背包中吗 ?

题目描述:

有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?

nameweightvalue12345678910a26066991212151515b23033669991011c65000666661011d54000666661010e460006666666

只要你能通过找规律手工填写出上面这张表就算理解了01背包的动态规划算法。

首先要明确这张表是至底向上,从左到右生成的。

为了叙述方便,用e2单元格表示e行2列的单元格,这个单元格的意义是用来表示只有物品e时,有个承重为2的背包,那么这个背包的最大价值是0,因为e物品的重量是4,背包装不了。

对于d2单元格,表示只有物品e,d时,承重为2的背包,所能装入的最大价值,仍然是0,因为物品e,d都不是这个背包能装的。

同理,c2=0,b2=3,a2=6。

对于承重为8的背包,a8=15,是怎么得出的呢?

根据01背包的状态转换方程,需要考察两个值,

一个是f[i-1,j],对于这个例子来说就是b8的值9,另一个是f[i-1,j-Wi]+Pi;

在这里,

 f[i-1,j]表示我有一个承重为8的背包,当只有物品b,c,d,e四件可选时,这个背包能装入的最大价值

f[i-1,j-Wi]表示我有一个承重为6的背包(等于当前背包承重减去物品a的重量),当只有物品b,c,d,e四件可选时,这个背包能装入的最大价值

f[i-1,j-Wi]就是指单元格b6,值为9,Pi指的是a物品的价值,即6

由于f[i-1,j-Wi]+Pi = 9 + 6 = 15 大于f[i-1,j] = 9,所以物品a应该放入承重为8的背包

网易CPU调度问题

问题描述:

/*[编程题] 双核处理一种双核CPU的两个核能够同时的处理任务,现在有n个已知数据量的任务需要交给CPU处理,假设已知CPU的每个核1秒可以处理1kb,每个核同时只能处理一项任务。n个任务可以按照任意顺序放入CPU进行处理,现在需要设计一个方案让CPU处理完这批任务所需的时间最少,求这个最小的时间。输入描述:输入包括两行:第一行为整数n(1 ≤ n ≤ 50)第二行为n个整数length[i](1024 ≤ length[i] ≤ 4194304),表示每个任务的长度为length[i]kb,每个数均为1024的倍数。输出描述:输出一个整数,表示最少需要处理的时间输入例子:53072 3072 7168 3072 1024输出例子:9216*/

问题分析:这道题目要用动态规划求解,可以转换得到背包问题上,如何转换呢?我们可以这样思考:由于有两个CPU,那么最理想的调度时间为sum/2,sum总时长,但是由于子进程不可切分,那么就需要放置一个背包,背包的重量为sum/2,能装入的值为3072 ,3072 ,7168 ,3072 ,1024,求装入哪些值可以使得背包重量最大?
那么我们就可以使用原始的背包问题来求解这个问题了。
简单的python代码示例:

value=[0,1,3,3,3,7]weight=[0,1,3,3,3,7]total=8f=np.zeros((6,9),int)for i in range(1,6):    for j in range(1,9):        if(j<weight[i]):            f[i][j] = f[i-1][j]        else:            f[i][j]=max(f[i-1][j],(f[i-1][j-weight[i]]+value[i]))print f

结果为:

[[0 0 0 0 0 0 0 0 0] [0 1 1 1 1 1 1 1 1] [0 1 1 3 4 4 4 4 4] [0 1 1 3 4 4 6 7 7] [0 1 1 3 4 4 6 7 7] [0 1 1 3 4 4 6 7 8]]

可见最少用时为8,也就是8*1024=9216

总结

我也是刚刚学习到动态规划,有几点粗浅的理解:

  1. 动态规划刚刚开始确实不直观,不易理解,花些功夫看,多想想,总能理解;
  2. 将问题化为求解子问题,前一个子问题最值问题求解了,如果你找到子问题与当前问题的关系,那么当前问题就解决了,是一个迭代的过程。就比如这里的状态转移公式,求当前的状态必须依靠之前的状态。
  3. 将搜索进行记忆化,也就是说,之前的状态全部存储起来,在计算后面的状态时依靠前面的状态,此时前面的状态已经存储起来,可以直接使用。
0 0
原创粉丝点击