我该如何向我的朋友解释“01背包”问题?

来源:互联网 发布:非洲网络建设情况 编辑:程序博客网 时间:2024/04/29 11:57

    最近有位朋友有向我问道关于“01背包”算法问题的理解。由于她本人在基础年纪没有学过《计算机算法设计与分析》这门课程,正如每一位初始的人学习一种新的知识一样,学习过程中总是遇到各种疑问。学习过程中,有疑问时一种好事,但是过于完美的一遍读懂,似乎确实有困难。认知一门知识,无非两种选择,一是可以反复阅读,直至每一次认识一点点,好处在于,短时间对认识有一定的掌握,但是到完全理解还是需要不断在读几遍;另一就是慢慢读,一遍就有一个很好的理解层次,这需要时间稍长。

    在这文章中,我希望自己用他人的知识背景,解释我对自己学习过的知识进行理解。下面将是我对01背包问题的理解:

    预备知识:对C语言了解、有一定的数据结构概念、Max{}函数的知识、有些基本生活阅历常识。

    算法名称解释:“背包”这个词可以这么想,在日常生活中,比如说我们出去旅游时的背包吧!当你决定背着它去旅行的时候,这背包的体积(背包的大小)或是最大能装物品的重量,此时当然是固定的啦。这里的“0和1”呢,其实就是一种状态,是什么呢,拿你的旅行包为例。比如说你在出发前,你可能最先想到你要带几件衣服啦,但是也不是所有衣服都带是不是,可能带一套就够了,这时,你选则一件你认为最好看的放进背包里,那么在计算机中,这个放进去的过程用“1”来表示喽,没有被选中的衣服,肯定也没有放进去,这是用“0”来表示了。好了,以上就是对这个算法名称的通俗解释啦。

    算法情景分析案例: 比如前一阵子我去了一次贵州“西乡苗寨”两日游为例吧,去旅游,可能衣服、牙刷之类没的说,一定带,背包肯定也可以放下去,但是对于吃的零食呢,肯定是能装下多少就使劲往里塞对不对。但是,但是不同零食个头体积都不一样呀,当然我是全想带,全带的话,你的背包能装的下么?估计不行,所以我只能考虑一下,有些零食只能算了。那么问题就来了:我怎样做,才能把那些我最喜欢的零食放进背包里呢,然后开心地去旅行了?

   算法情景分析假设:我背包的大小即容量,我们假设V,这里V是固定的;零食中的苹果、矿泉水、饮料、瓜子、面包、、、等的体积我假设用C[i]来表示;对应每种零食我的喜爱程度(需要程度)肯定不是一样重要的,按照这些零食对我的需要价值我假设用P[i]表示。放入零食的时候,每种零食只能整包放入,不可以拆开哦。F[i][V]表示第1、2、3...i个零食放到容量为V的背包中后,此时恰好也是我背包里的前i个零食价值总和的最大值。则该函数的表示如下:

F[i][V] = Max{ F[ i-1 ][ V ] , F[ i-1 ][ V-C[i] ] + P[i] }

   这里要说的是,此处是采用动态规划来完成的,即在考虑放不放第[i]个零食时,我们只说放还是不放,这样的话,假如我们实际上没有放入第[i]个零食,则此时最大值是F[i-1][V],如果放入第[i]个零食,则此时变成了前[i-1]个零食在体积V-C[i]下的最大值F[i-1][V-C[i]]。

   如果采用回溯法解决的法,我们涉及到二叉树的来构造解空间,解空间其实就是我们规定X[i]的取值为0和1.还记得我们内存吗,每一位使用二进制,要么0,要么1,假如有N位的话,则可以表示2的N次方个树,在数据结构可以采用完全二叉树来表示的。所以你有N个零食要放入背包的话,总共有2的N次方方案放入。这里肯定有最优的值。

   回溯则体现在一个二叉树,从根节点开始,只要往左可以做的话,就不回往右,万一到了一个左边的节点行不通了,则退回到最近的父节点,然后往右走。回溯的含义就在于此。

   以上的说的是我对01背包问题的思路分析,具体代码此处没有提供。



0 0