当前位置:   article > 正文

动态规划_构造最优比对

构造最优比对

一、动态规划(dynamic programming)

要点一:动态规划通常用于解决最优化问题。

要点二:最优解和最优解的值是不同的概念,最优解可以有多个,最优解的值只能有一个。

要点三:算法设计包含四个步骤:

(1)描述最优解的结构;

(2)递归定义最优解的值;

(3)按自底向上的方式计算最优解的值;

(4)由计算出的结果构造一个最优解。

要点四:应用动态规划的前提有两个:(1)最优子结构(2)重叠子序列

要点五:《算法导论(第二版)》P192

二、LCS的C++实现

最长公共子序列(Longest-Comment-Subsequence, LCS)

(一)借助数组b来构造最优解的值:

  1. #include <iostream>
  2. #include <stdlib.h>
  3. using namespace std;
  4. //说明:X,Y表示要匹配的两个序列;m,n分别表示X,Y中要进行比较的字符个数。
  5. //由于在序列X,Y和数组c和b中,下标为0的位置都不用,所以:X,Y,c,b可以如下表示:
  6. //X:0,1,...,m; Y:0,1,...,n; c,b:(0,1,...,m )*(0,1,...,n)。即,c和b都是m+1行n+1列
  7. //函数LCS_LENGTH:用于计算LCS的长度(应用数组b做记录)
  8. void LCS_LENGTH(char* X,int m,char* Y,int n,int c[][7],int b[][7])
  9. {
  10. int i,j;
  11. for(i=1;i<=m;i++)
  12. {
  13. c[i][0]=0;
  14. b[i][0]=0;
  15. }
  16. for(j=0;j<=n;j++)
  17. {
  18. c[0][j]=0;
  19. b[0][j]=0;
  20. }
  21. for(i=1;i<=m;i++)
  22. for(j=1;j<=n;j++)
  23. {
  24. if(*(X+i)==*(Y+j))
  25. {
  26. //c[i,j]=c[i-1,j-1]+1
  27. c[i][j]=c[i-1][j-1]+1;
  28. //↖:1;↑:2;←:3;
  29. //b[i,j]='↖'
  30. b[i][j]=1;
  31. }
  32. else if(c[i-1][j]>=c[i][j-1])
  33. {
  34. c[i][j]=c[i-1][j];
  35. //b[i,j]='↑'
  36. b[i][j]=2;
  37. }
  38. else
  39. {
  40. c[i][j]=c[i][j-1];
  41. //b[i,j]='←'
  42. b[i][j]=3;
  43. }
  44. }//for(j...)
  45. }//LCS_LENGTH
  46. //函数PRINT_LCS:用于构造LCS并打印出来(应用数组b)
  47. //n:b数组的列数;i=length(X);j=length(Y)
  48. void PRINT_LCS(int b[][7],int n,char* X,int i,int j)
  49. {
  50. if(i==0||j==0)
  51. return;
  52. if(b[i][j]==1)
  53. {
  54. PRINT_LCS(b,n,X,i-1,j-1);
  55. cout<<*(X+i)<<" ";
  56. }
  57. else if(b[i][j]==2)
  58. PRINT_LCS(b,n,X,i-1,j);
  59. else
  60. PRINT_LCS(b,n,X,i,j-1);
  61. }
  62. //main函数(应用b)
  63. void main()
  64. {
  65. //因为表示序列的字符数组X,Y中的第一位都不用,所以用字符‘0’填充
  66. char X[]="0ABCBDAB";
  67. char Y[]="0BDCABA";
  68. cout<<"LCS-Programming is running!"<<endl;
  69. cout<<"Squence X:A B C B D A B"<<endl;
  70. cout<<"Squence Y:B D C A B A"<<endl;
  71. //设置序列X,Y的长度
  72. int m=7;
  73. int n=6;
  74. int i=m,j=n;
  75. int c[8][7],b[8][7];
  76. cout<<"The LCS length is being computed!"<<endl;
  77. LCS_LENGTH(X,m,Y,n,c,b);
  78. cout<<"The LCS:";
  79. PRINT_LCS(b,n,X,i,j);
  80. system("pause");
  81. }

结果:

二、不借助数组b构造LCS的方法(习题15.4-2):

  1. #include <iostream>
  2. #include <stdlib.h>
  3. using namespace std;
  4. void LCS_LENGTH(char* X,int m,char* Y,int n,int c[][7])
  5. {
  6. int i,j;
  7. for(i=1;i<=m;i++)
  8. c[i][0]=0;
  9. for(j=0;j<=n;j++)
  10. c[0][j]=0;
  11. for(i=1;i<=m;i++)
  12. for(j=1;j<=n;j++)
  13. {
  14. if(*(X+i)==*(Y+j))
  15. c[i][j]=c[i-1][j-1]+1;
  16. else if(c[i-1][j]>=c[i][j-1])
  17. c[i][j]=c[i-1][j];
  18. else
  19. c[i][j]=c[i][j-1];
  20. }//for(j...)
  21. }//LCS-LENGTH
  22. void PRINT_LCS(int c[][7],int n,char* X,int i,int j)
  23. {
  24. if(i==0||j==0)
  25. return;
  26. if(c[i-1][j-1]==c[i][j]-1||c[i-1][j]==c[i][j]-1||c[i][j-1]==c[i][j]-1)
  27. {
  28. PRINT_LCS(c,n,X,i-1,j-1);
  29. cout<<*(X+i)<<" ";
  30. }
  31. else if(c[i][j]==c[i-1][j])
  32. PRINT_LCS(c,n,X,i-1,j);
  33. else
  34. PRINT_LCS(c,n,X,i,j-1);
  35. }
  36. void main()
  37. {
  38. cout<<"LCS-Programming is running!"<<endl;
  39. cout<<"Squence X:A B C B D A B"<<endl;
  40. cout<<"Squence Y:B D C A B A"<<endl;
  41. char X[]="0ABCBDAB";
  42. char Y[]="0BDCABA";
  43. int m=7;
  44. int n=6;
  45. int c[8][7]={0};
  46. int i=m,j=n;
  47. cout<<"The LCS length is being computed!"<<endl;
  48. LCS_LENGTH(X,m,Y,n,c);
  49. cout<<"The LCS:";
  50. PRINT_LCS(c,n,X,i,j);
  51. system("pause");
  52. }

结果:


声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号