最优化方法:七、动态规划

主要参考书目:

  • 最优化方法及其应用/郭科,陈聆,魏友华.-北京:高等教育出版社,2007.7(2013.7重印)

基本原理

这一部分的描述比较数学化,这里完全照搬书本。
最优化方法:七、动态规划_第1张图片
最优化方法:七、动态规划_第2张图片
最优化方法:七、动态规划_第3张图片
4

实例一、楼梯问题

  • 问题描述
    一个人爬楼梯,每次只能爬一个或两个台阶,假设有n个台阶,那么这个人有多少种不同的爬楼梯方法。
  • 思路分析
    该问题并不涉及优化,而是方法计数。
    逆序考虑该问题,要上到第n层,一定是从第n-1层爬一级或者从n-2层爬两级。
    则可得到上n层台阶的方法 f(n)=f(n1)+f(n2),n>2 f ( n ) = f ( n − 1 ) + f ( n − 2 ) , n > 2
    f(1)=1,f(2)=2. f ( 1 ) = 1 , f ( 2 ) = 2.
  • 代码实现
    Python

    def ladder(n):
        if n==1:
            return [1]
        elif n==2:
            return [1,2]
    
        rel= [0]*(n+1)
        rel[0]=0
        rel[1]=1
        rel[2]=2
        for i in range(3,n+1):
            rel[i]=rel[i-1]+rel[i-2]
        return rel[1:]
    
    print(ladder(5))
    input()

实例二、背包问题

  • 问题描述
    某人拥有一个容量为V的背包,有一天他找到了一个宝藏,该宝藏有n个,其价值为v[n],所需容量为w[n],求该人如何选择带走的东西能使利益最大化?
  • 思路分析
    不妨把问题具体化:

    V=120;n=5;w=[40,50,70,40,20];v=[10,25,40,20,10]. V = 120 ; n = 5 ; w = [ 40 , 50 , 70 , 40 , 20 ] ; v = [ 10 , 25 , 40 , 20 , 10 ] .

    该问题其实是一个0-1规划:
    max(10x1+25x2+40x3+20x4+10x5)s.t.   40x1+50x2+70x3+40x4+20x5120xi=0 or 1; m a x ( 10 x 1 + 25 x 2 + 40 x 3 + 20 x 4 + 10 x 5 ) s . t .       40 x 1 + 50 x 2 + 70 x 3 + 40 x 4 + 20 x 5 ≤ 120 x i = 0   o r   1 ;

    此处仍用动态规划的方法解决该问题,考虑动态规划问题中的要素:
    阶段:考虑第k个物品是否放入,即是第k个阶段。
    状态:当前背包所剩容量,当前决定到哪一个物品即是当前的状态 sk s k
    决策:当前这个物品要还是不要 uk u k
    策略:当前物品及当前物品以后的物品要还是不要 pk,n p k , n
    状态转移方程:当前的决策会使当前状态变为下一阶段的状态:

    if u_k==1
        s_(k+1)=s_k+[-1,-w[k]]
    elseif u_k==0`
        s_(k+1)=s_k+[-1,0]

    阶段指标函数:即第k次决策所带来的收益 dk d k ,放入就是v[k],不放入就是0。
    过程指标函数:即第k次决策及其以后使用某策略获得的收益 Vk,n V k , n
    最优指标函数 fk=max(Vk,n) f k = m a x ( V k , n )
    不难看出,对于该问题:

    f(n,V)=max(f(n1,Vw(n))+v(n),f(n1,V)); f ( n , V ) = m a x ( f ( n − 1 , V − w ( n ) ) + v ( n ) , f ( n − 1 , V ) ) ;

    特别地,
    f(1,V)={0, V<w[1]v[1], Vw[1] f ( 1 , V ) = { 0 ,   V < w [ 1 ] v [ 1 ] ,   V ≥ w [ 1 ]

  • 代码实现
    Python

    import numpy as np
    
    def bag(i,V):
        w=[0,40,50,70,40,20]
        v=[0,10,25,40,20,10]
        choose=[0,0,0,0,0,0]
        if i == 1:
            if V >= 40:
                choose[1]=1
                return [v[i],choose]
            if V < 40:
                choose[1]=0
                return [0,choose]
        choose[i]=1
        if V >= v[i]:
            ret0=bag(i-1,V-w[i])[0]+v[i]
            ret1=np.array(bag(i-1,V-w[i])[1])+np.array(choose)
            ret1=ret1.tolist()
            if ret0 < bag(i-1,V)[0]:
                ret0=bag(i-1,V)[0]
                ret1=bag(i-1,V)[1]
            return [ret0,ret1]
        return bag(i-1,V)
    
    print (bag(5,120))
    input ()

实例三、最短路问题

  • 问题描述
    在有n个节点的网络中求i,j两点间的最短路径。
  • 思路分析
    首先不考虑含回路的路线,含回路的路线必定不是最短路。
    (1)函数迭代法
    最优化方法:七、动态规划_第4张图片
    编程实现(matlab)

    function f = TheShortestWay(c,n)
    len_n=size(c,1);
    c_std=std(c,n,len_n);
    for i=2:len_n-1
        f_old=c_std(len_n,:);
        f_tmp=repmat(f_old',1,len_n);
        f_new=min(f_tmp+c_std);
        if f_new==f_old
            break;
        end
        c_std(len_n,:)=f_new;
    end
    f=rstd(f_new,n,len_n);
    
    %%std.m
    function c_std = std(c,n,len_n)
    %将目标点换为最后一个点
    c_std=c;
    c_std(:,len_n)=c(:,n);
    c_std(:,n)=c(:,len_n);
    tmp=c_std;
    c_std(len_n,:)=tmp(n,:);
    c_std(n,:)=tmp(len_n,:);
    end
    
    %%rstd.m
    function f=rstd(f_new,n,len_n)
    f=f_new;
    f(len_n)=f_new(n);
    f(n)=f_new(len_n);
    end

    (2)策略迭代法
    最优化方法:七、动态规划_第5张图片
    最优化方法:七、动态规划_第6张图片
    如果初始策略是直接前往目的点则策略迭代与函数迭代相同。

你可能感兴趣的:(优化问题)