当前位置:   article > 正文

高效的动态规划算法应用案例_动态规划算法生活应用实例

动态规划算法生活应用实例

1.前言:动态规划与分治算法类似,递归求解子问题,再组合子问题来求解。但动态规划在子问题有重叠的情况下有优势。动态规划算法用于求解最优化问题,所求解的问题需要满足最优子结构性质:问题最优解由相关子问题的最优解组合而成。

2.动态规划的两种实现方式:

    2.1 带备忘的自顶向下法

           所谓的带备忘,即保存每一个子问题的解,在下次用时直接取出而不需要重新计算,从而提高效率。

    2.2 自底向上法

          即任何子问题的求解,只依赖于规模更小的子子问题的求解。由于是从小到大的规模顺序求解,即在计算子问题时,它的所有依赖的更小的子问题已经求解且保存,不需重新计算,从而提高效率。

3.钢条切割最优化求解(算法导论上的)

问题描述:给定钢条长度n和一个价格表p,求切割方案,使得销售收益r最大。


价格表

长度i12345678910
价格p15891017172024

30


建立数学模型:r(n)=max(p(i)+r(n-i));    其中i=1,2,...n

说明:我们将钢条从左边切割下长度为i的一段,只对右边剩下的n-i长度来继续进行切割。即原问题最优解只包含一个子问题解(右端剩余部分),而不是两个。

java代码如下:

  1. package com.talkweb.test01;
  2. import java.util.Arrays;
  3. /**
  4. * 动态规划运用案例
  5. * 钢条切割
  6. * @author Administrator
  7. *
  8. */
  9. public class DynamicProgram {
  10. public static void main(String[] args){
  11. int[] p={-1,1,5,8,9,10,17,17,20,24,30};//下标对应钢条长度,值对应收益,下标从1开始
  12. DynamicProgram dp=new DynamicProgram();
  13. //1.初始化r
  14. int[] r=new int[p.length];
  15. for(int i=0;i<r.length;i++){
  16. r[i]=-1;
  17. }
  18. //2.调用方法求解
  19. int n=7;//需要切割的钢条长度
  20. int m=dp.iterationValue(p,n, r);//带备忘自顶向下
  21. System.out.println("带备忘自顶向下 m="+m);
  22. dp.printBottom_up(p,n); //自底向上
  23. }
  24. /**
  25. * 自顶向下递归求解:递归计算当前长度为n的钢条的最优值
  26. * @param p钢条对应收益数组
  27. * @param n当前钢条长度
  28. * @param r记录最优值
  29. */
  30. public int iterationValue(int[] p,int n,int[] r){
  31. if(r[n]>=0){//若已记录当前长度n的最优值,则直接返回
  32. return r[n];
  33. }
  34. //若当前长度n为0则最优值为0
  35. if(n==0){
  36. return 0;
  37. }
  38. int s=-1;//记录当前n做一次切割各种方案的最优值
  39. for(int i=1;i<=n;i++){//遍历当前长度,即当前长度的各种切割方案
  40. s=max(s,p[i]+iterationValue(p,n-i,r));
  41. }
  42. //保存当前长度n的最优值
  43. r[n]=s;
  44. return s;
  45. }
  46. public int max(int s,int t){
  47. return s>t?s:t;
  48. }
  49. /**
  50. * 自底向上非递归求解
  51. * @param p
  52. * @return
  53. */
  54. public int[] bottom_up(int[] p,int n){
  55. int[] r=new int[n+1]; //保存最优值
  56. int[] s=new int[n+1]; //保存最优切割方案
  57. for(int j=1;j<=n;j++){
  58. int q=-1; //记录钢条长度为j时的最优值
  59. for(int i=1;i<=j;i++){ //对长度为j的钢条做一次切割
  60. if(q<p[i]+r[j-i]){
  61. q=p[i]+r[j-i]; //保存较大值
  62. s[j]=i; //保存当前长度为j的最佳切割长度i
  63. }
  64. }
  65. r[j]=q; //保存钢条规模长度为j的最佳收益值
  66. }
  67. System.out.println("自底向上 最优收益:"+r[n]);
  68. return s; //返回钢条长度为n时的最佳收益值
  69. }
  70. public void printBottom_up(int[]p,int n){
  71. int[]s=bottom_up(p,n);
  72. System.out.println("切割方案:");
  73. while(n>0){
  74. System.out.print(s[n]+" ");
  75. n=n-s[n];
  76. }
  77. System.out.println();
  78. }
  79. }

4.商品折扣最优购买方案的优惠总额(只是简单的自顶向下实现,没有用到动态规划)

  1. package com.talkweb.arithmetic;
  2. import java.util.ArrayList;
  3. import java.util.Arrays;
  4. import java.util.List;
  5. /**
  6. * 商品折扣最优购买方案
  7. * @author Administrator
  8. *
  9. */
  10. public class GoodsDiscount {
  11. public static void main(String[] args){
  12. //1.折扣集合
  13. List<ZheKou> zks=new ArrayList<ZheKou>();
  14. zks.add(new ZheKou(0,"0",0,0));
  15. zks.add(new ZheKou(1,"折扣1",30,6));
  16. zks.add(new ZheKou(3,"折扣2",60,15));
  17. zks.add(new ZheKou(2,"折扣3",99,20));
  18. GoodsDiscount gd=new GoodsDiscount();
  19. double money=100;
  20. int[] s=new int[zks.size()];
  21. System.out.println("优惠总额:"+gd.fun(zks,money,0));
  22. }
  23. /**
  24. * 递归计算最多优惠额
  25. * @param zks商品折扣
  26. * @param money余额
  27. * @return最多优惠额
  28. */
  29. public double fun(List<ZheKou> zks,double money,double youhui){
  30. //1.若余额不足以购买任何折扣,则返回优惠额
  31. boolean flag=false;
  32. for(int i=1;i<zks.size();i++){
  33. if(zks.get(i).getPrice()<money){
  34. flag=true;
  35. }
  36. }
  37. if(!flag){
  38. return youhui;
  39. }
  40. //2.迭代可以购买每一种折扣,计算并记录当前购买最大优惠额
  41. double max=0;
  42. for(int i=1;i<zks.size();i++){
  43. if(money>zks.get(i).getPrice()){
  44. //计算购买1件第i种折扣优惠额
  45. max=maxValue(max,fun(zks,money-zks.get(i).getPrice()+zks.get(i).getYhPrice(),youhui+zks.get(i).getYhPrice()));
  46. }
  47. }
  48. //保存优惠额
  49. youhui=max;
  50. return youhui;
  51. }
  52. public double maxValue(double m,double y){
  53. return m>y?m:y;
  54. }
  55. }










声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/798941
推荐阅读
相关标签
  

闽ICP备14008679号