动态规划-线性模型

动态规划-线性模型动态规划可以用一句话概括:动态规划是在解决多阶决策的过程中动态地选择最优决策的方法最终目的:找出最优解问题特征:1.问题范围可以缩小到多个问题单元,对应多种决策2.这多个决策动态选择组合可以充分解决整个问题解决问题三要素:1最优子决策2边界值3状态抉择公式线性模型例子:小朋友过桥步骤:1.找出边界:最后剩下两个小朋友、最后剩下1个小朋友2.找出边界对应最优子决策:…

大家好,欢迎来到IT知识分享网。

一、动态规划简介

  1. 动态规划可以用一句话概括:

动态规划是在解决多阶决策的过程中动态地选择最优决策的方法

  1. 最终目的:找出最优解
  2. 问题特征:
    (1). 问题范围可以缩小到多个问题单元,对应多种决策
    (2). 这多个决策动态选择组合可以充分解决整个问题
  3. 解决问题三要素:
    (1). 最优子决策
    (2). 边界值
    (3). 状态抉择公式

二、线性模型

例子:小朋友过桥
四个调皮的小朋友晚上要过桥去对岸玩耍。桥一次最多只能通过两个小朋友,他们只有一个手电筒,过桥需要有人拿着手电筒,问他们怎么过最快。其中这四个小朋友的过桥速度分别为1,2,5,10 (分钟)
在这里插入图片描述

有的人会想到贪心算法(只要一个策略作为最优策略):速度最快的小朋友来回传手电筒,那么有什么欠考虑的地方呢?我们一起来看一下过程图:
贪心算法过程图
【贪心算法过程图】
在这里插入图片描述
【动态规划过程图】
图1算出19,图2算出17,相信你已经发现,一起走的两个人,如果速度相当,反而会节约时间。如果你害怕还有欠考虑的情况,那就直接用动态规划思路吧,一起来看看。

三、动态规划步骤(自底向上):

先将小朋友按照速度快慢进行排列得到队列:
t[i]={t(1),t(2),t(3)…t(i)}
1.找出边界
最后剩下两个小朋友、最后剩下1个小朋友
2.找出边界对应最优子决策
最后剩下1个小朋友:
remainOne(i)=sum(i)=sum(i-1)+t(1)+t(i)
最后剩下两个小朋友:
remainTwo(i)=sum(i)=sum(i-2)+t(1)+t(i)+t(2)+t(2)
3.状态抉择
sum(i)=min(remainOne(i),remainTwo(i))

四、送上完整java实现代码

public class AlgorithmTest { 
   
    public static int[] childTimes=new int[]{ 
   1,2,5,10};//{2,4,5,7};

    public static int indexFirst=0;
    public static int indexSecond=1;
    public static void main(String[] args) { 
   
        AlgorithmTest test=new AlgorithmTest();
        System.out.println(test.getSumTime(4-1));
        System.out.println(test.getSumTimeFor());
    }

    //递归方式
    public int getSumTime(int i) { 
   
        if (i <=indexSecond) { 
   
            if(childTimes.length==1){ 
   
                return childTimes[indexFirst];
            }
            return childTimes[indexSecond];
        }
        //如果只剩下一个,那么总耗时=i-1个人之前的总耗时+一个来回(送电筒的+最后一个的)
        int lastone = getSumTime(i - 1) + childTimes[indexFirst] + childTimes[i];
        int lasttwo = getSumTime(i - 2) + childTimes[indexFirst] + childTimes[i] + childTimes[indexSecond] + childTimes[indexSecond];
        return Math.min(lastone, lasttwo);
    }

    //备忘录方式
    public int getSumTimeFor(){ 
   
        int[] memoMin=new int[childTimes.length];
        int memoRemainOne=0;
        int memoRemainTwo=0;
        int n=childTimes.length-1;
        if (n ==indexFirst||n==indexSecond) { 
   
            if(childTimes.length==1){ 
   
                memoMin[0]= childTimes[indexFirst];
            }
            memoMin[0]= childTimes[indexSecond];
            return memoMin[0];
        }
        
        memoMin[0]=memoMin[1]= childTimes[indexSecond];
        for (int i=2;i<=n;i++){ 
   
            memoRemainOne=memoMin[i-1] + childTimes[indexFirst] + childTimes[i];
            memoRemainTwo=(memoMin[i-2])+ childTimes[indexFirst] + childTimes[i] + childTimes[indexSecond] + childTimes[indexSecond];
            memoMin[i]=Math.min(memoRemainOne, memoRemainTwo);
        }
        return memoMin[n];
    }
}

最后输出:

17
17

集合为{2,4,5,7}则输出:

20
20

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/11542.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信