【动态规划】最优二叉搜索树C++实现
程序在VC++6.0下编译通过
1 #include <iostream>
2 #include <fstream>
3 #include <string>
4 #include <limits>
5
6 using namespace std;
7
8 const string INFILE = "in.txt"; // 存放“输入数据”的文件
9 const string OUTFILE = "out.txt"; // 存放“输出数据”的文件
10 const int N = 7; //结点数
11 const double MAX = numeric_limits<double>::max(); //double的最大值
12 const double MAXMAX = numeric_limits<long>::max(); //double的最大值
13
14 double p[N+2]; // p[i]为结点i被访问的概率
15 double q[N+2]; // q[i]为“虚结点”i被访问的概率
16 //double e[(N+2)*(N+2)]; // e,用来存放子树(i,j)的期望代价
17 double e[N+2][N+2];
18 //double w[(N+2)*(N+2)]; // w,用来存放子树(i,j)的所有结点(包括虚结点)的p、q之和
19 double w[N+2][N+2];
20 //int root[(N+2)*(N+2)]; // root,用来跟踪root的
21 int root[N+2][N+2];
22
23
24 //void optimalBst(double *p, double *q, int n)
25 void optimalBst(void)
26 {
27 int i,j,l,r; // i,j用来标记“子树(i,j)”;l用来标记“步长”;r用来标记子树的根节点(动态规划的“选择”)
28
29 //这是个很boundary的case:当j=i-1的时候,“子树(i,j)”实际上是“虚结点i-1”*/
30 for(i=1; i<=N+1 ; ++i)
31 {
32 e[i][i-1] = q[i-1];
33 w[i][i-1] = q[i-1];
34 }
35
36 // 用“动态规划”方法,自底向上构造“最优二叉搜索树”的解
37 for(l=1 ; l<=N ; ++l) // 步长l从小到大
38 {
39 for(i=1 ; i<=N-l+1 ; ++i) //步长为l的情况下,i的范围是1到N-l+1
40 {
41 j = i+l-1; // 此时步长为l,j的值为i+l-1
42 e[i][j] = MAX;
43 w[i][j] = w[i][j-1] + p[j] + q[j]; // 对于“子树(i,j)”来说,不管树形是什么样的,w[i,j]的值都是固定的
44
45 // 在i--j中,选择一个r作为“最佳根节点”
46 double temp = MAX;
47 for(r=i ; r<=j; ++r)
48 {
49 temp = e[i][r-1] + e[r+1][j] + w[i][j];
50 if(temp < e[i][j])
51 {
52 e[i][j] = temp;
53 root[i][j] = r;
54 }
55 }
56 }
57 }
58
59
60 }
61
62 int main()
63 {
64 int i,j;
65 ifstream fIn(INFILE.c_str()); //文件“读入流”
66 ofstream fOut(OUTFILE.c_str()); //文件“输出流”
67
68 //从文件读入输入数据
69 i=1;
70 while(!fIn.eof())
71 {
72 if(i<=N)
73 {
74 fIn>>p[i];
75 }
76 else
77 {
78 fIn>>q[i-N-1];
79 }
80 ++i;
81 }
82
83 // 用“动态规划”计算“最优二叉搜索树”
84 //optimalBst(p,q,N);
85 optimalBst();
86
87 // 打印结果
88 for(i=0 ; i<=N+1 ; ++i)
89 {
90 for(j=0 ; j<=N+1 ; ++j)
91 {
92 fOut<<"e["<<i<<","<<j<<"] = "<<e[i][j]<<endl;
93 }
94 }
95 fOut<<endl<<endl;
96 for(i=0 ; i<=N+1 ; ++i)
97 {
98 for(j=0 ; j<=N+1 ; ++j)
99 {
100 fOut<<"w["<<i<<","<<j<<"] = "<<w[i][j]<<endl;
101 }
102 }
103 fOut<<endl<<endl;
104 for(i=0 ; i<=N+1 ; ++i)
105 {
106 for(j=0 ; j<=N+1 ; ++j)
107 {
108 fOut<<"root["<<i<<","<<j<<"] = "<<root[i][j]<<endl;
109 }
110 }
111
112 cout<<"大丈夫、萌大奶,去"<<OUTFILE<<"里查看结果吧少年!"<<endl;
113 cout<<MAXMAX<<endl;
114
115 return 0;
116 }
浙公网安备 33010602011771号