动态规划与分治方法类似,都是通过组合子问题来求解原问题。通常用来求解最优化问题,通常按如下4个步骤设计一个动态规划算法:
1.刻画一个最优解的结构特征;
2.递归的定义最优解的值;
3.采用自底向上的方法计算最优解的值;
4.利用计算出的信息构造一个最优解。
二叉搜索树(optimal binary search tree,OBST): 对于key 都有个p 表示搜索到的概率,q表示没有搜索到概率,比如q1 表示搜寻数字位于
k1 和 k2 之间的概率,q0表示小于k1的概率。如果找到了key, 则相应的‘P’ 则记录,否则‘q’ 加入
定义表示OBST的权重矩阵,定义
表示OBST搜索代价矩阵。
举个例子吧:
有N=6,6个点,p1=10,p2 =3,p3=9,p4=2,p5=0,p6=10; q0 =5,q1=6,q2=4,q3=4,q4=3,q5=8,q6=0, 则首先计算W以及C
根据min的结果,记录root节点,并填表,最后完成的root表格。
根据最后的R表格,计算得到OBST
根据上面例子,很容易写如下代码: 代码部分,计算的双重循环,需要仔细琢磨,此处处理的比较巧妙
1. compute_W_C_R
void COMPUTE_W_C_R()
{
int x, min;
int i, j, k, h, m;
//Construct weight matrix W
for(i = 0; i <= NUMBER_OF_KEYS; i++)
{
W[i][i] = q[i];
for(j = i + 1; j <= NUMBER_OF_KEYS; j++)
W[i][j] = W[i][j-1] + p[j] + q[j];
}
//Construct cost matrix C and root matrix R
for(i = 0; i <= NUMBER_OF_KEYS; i++)
C[i][i] = W[i][i];
for(i = 0; i <= NUMBER_OF_KEYS - 1; i++)
{
j = i + 1;
C[i][j] = C[i][i] + C[j][j] + W[i][j];
R[i][j] = j;
}
// calculate min i<k<j (ci,k-1 , c k,j),
for(h = 2; h <= NUMBER_OF_KEYS; h++)
for(i = 0; i <= NUMBER_OF_KEYS - h; i++)
{
j = i + h;
m = R[i][j-1];
min = C[i][m-1] + C[m][j];
for(k = m+1; k <= R[i+1][j]; k++)
{
x = C[i][k-1] + C[k][j];
if(x < min)
{
m = k;
min = x;
}
}
C[i][j] = W[i][j] + min;
R[i][j] = m;
}
}
2.构建OBST: 这段代码比较好理解
//Construct the optimal binary search tree
OBST *CONSTRUCT_OBST(int i, int j)
{
OBST *p;
if(i == j)
p = NULL;
else
{
p = new OBST;
p->KEY = KEYS[R[i][j]];
p->left = CONSTRUCT_OBST(i, R[i][j] - 1); //left subtree
p->right = CONSTRUCT_OBST(R[i][j], j); //right subtree
}
return p;
}
资源文档下载(含代码):
http://download.csdn.net/detail/himilong/9064737