动态规划简要笔记

    动态规划解决的问题多数有重叠子问题这个特点

    动态规划与分治法最大的区别在于:适合于用动态规划法求解的问题,经分解后得到的子问题往往不是互相独立的(即下一个子阶段的求解是建立在上一个子阶段的解得基础上,进行进一步的求解)

    以下例子总结自公开课 计算机科学及编程导论

第一个简单例子(Python 3.x)
def fib(n):
    global numCalls
    numCalls+=1
    print ("fib called with ",n)
    if n<=1:
        return 1;
    else:
            return fib1(n-1)+fib1(n-2)

随着运算的进行,会出现很多冗余的计算,一些我们已经知道结果的计算(重叠子问题)

         ——解决方法:默记法,在第一次计算时就记录一个值,在后续计算中通过查表使用这个值

改进后的代码:

def fastfib(n,memo):
    global numCalls
    numCalls+=1
    print ("fib called with ",n)
    if not n in memo:
        memo[n] = fastfib(n-1,memo) + fastfib(n-2,memo)
    return memo[n]

def fib(n):

    memo={0:1,1:1}  ## initialize, memo is a dictionary

    return fastfib(n,memo)

当n较大时,执行可发现numCalls大大降低


第二个例子:0-1背包问题

最优子结构(optimal substructure),通过子问题的局部最优方案得到全局优化解决方案

基于决策树的实现:

def maxVal(i,v,w,aw):

     print (i,aw)

    global callNums

    callNums+=1

    if i==0:

        if w[i]<= aw:

            return v[i]

        else:

            return 0

    without_i=maxVal(i-1,v,w,aw)

    if w[i]>aw:

        return without_i

    else:

        with_i=v[i]+maxVal(i-1,v,w,aw-w[i])

    return max(without_i,with_i)

改进后的代码:

def fastmaxVal(i,v,w,aw,m):

    global callNums

    callNums+=1

    print (i,aw)

    try:

        return m[(i,aw)]

    except KeyError:

        if i==0:

            ifw[i]<=aw:

                m[(i,aw)]=v[i]

                return v[i]

            else:

                m[(i,aw)]=0

                return 0

        without_i=fastmaxVal(i-1,v,w,aw,m)

        if w[i]> aw:

            m[(i,aw)]=without_i

            return without_i

        else:

           with_i=v[i]+fastmaxVal(i-1,v,w,aw-w[i],m)

        res=max(without_i,with_i)

        m[(i,aw)]=res      #dictionary memo

        return res


总结:动态规划->大大减少调用次数,本质:空间换时间








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值