""" 实现最优二叉搜索树 p_i为关键字 k_i概率,q_i为空节点概率, e[i, j]为从顶点 k_i到 k_j组成的最优二叉搜索树的均值 w[i, j] = (p_i + p_i+1 + ... + p_j) + (q_i-1 + q_i + ... + q_j) 1、j = i - 1时 e[i, j] = q_i-1 2、j >= i 时 e[i, j] = e[i, r-1] + e[r+1, j] + w[i, j], (其中,w[i, j] = w[i, r-1] + p_r + w[r+1, j] = w[i, j-1] + p_j + q_j) """
"""
实现最优二叉搜索树(OptimalBinarySearchTree(OBST))
可打印出期望代价表e,权重表w,根节点表root
"""
def OBST(p, q, n, e, w, root):
for i in range(1, n+2):
e[i][i-1] = q[i-1] # 当根为k_1, ..., k_n时将e和w的对角线赋值为空结点q[i-1]权重
w[i][i-1] = q[i-1] # w[i][j] = p_i + ... + p_j + q_i-1 + ... + q_j
for l in range(1, n+1):
for i in range(1, n - l + 2): # 只用下标为1到n+1行,下表为0的行不用
j = i + l - 1 # 下标为0到n列
e[i][j] = float("inf") # 初始化e[i][j]为正无穷
w[i][j] = round(w[i][j-1] + p[j] + q[j], 2) # 计算w[i][j],保留2位数,不保留的话会出现异常数据
for r in range(i, j+1): # 根结点取1到n
t = round(e[i][r-1] + e[r+1][j] + w[i][j], 2)
if t < e[i][j]: # 将e[i][j]更新到最小
e[i][j] = t
root[i][j] = r # 将e[i][j]为最小时的根节点保存为root[i][j]
print("期望搜索代价表e:")
for i in range(1, n+2): # 打印行号1到n+1行,第0行没用到不打印
print(e[i][:])
print("权重表w:")
for i in range(1, n+2): # 打印行号1到n+1行,第0行没用到不打印
print(w[i][:])
print("根节点表root:") # 打印行号1到n行,第0行和第0列没用到不打印
for i in range(1, n+1):
print((root[i][1:]))
p = [0, 0.15, 0.10, 0.05, 0.10, 0.20] # 查找成功结点权重,共6个节点,第一个节点概率为0,实际共5个结点
q = [0.05, 0.10, 0.05, 0.05, 0.05, 0.10] # 查找失败结点权重
n = len(p) - 1 # 共5个节点
e, w, root = [], [], [] # 将e, w, root定义为一维数组
for i in range(n+2): # 将e, w, root初始化为全0的7行6列的二维数组,行号为0在函数中用不到,但也要生成,否则会出现溢出错误
e.append([0]*(n+1)) #在一维数组e中添加一维数组[0, 0, 0, 0, 0, 0],变为二维数组
root.append([0]*(n+1))
w.append([0]*(n+1))
OBST(p, q, n, e, w, root)
运行结果:
期望搜索代价表e:
[0.05, 0.45, 0.9, 1.25, 1.75, 2.75]
[0, 0.1, 0.4, 0.7, 1.2, 2.0]
[0, 0, 0.05, 0.25, 0.6, 1.3]
[0, 0, 0, 0.05, 0.3, 0.9]
[0, 0, 0, 0, 0.05, 0.5]
[0, 0, 0, 0, 0, 0.1]
权重表w:
[0.05, 0.3, 0.45, 0.55, 0.7, 1.0]
[0, 0.1, 0.25, 0.35, 0.5, 0.8]
[0, 0, 0.05, 0.15, 0.3, 0.6]
[0, 0, 0, 0.05, 0.2, 0.5]
[0, 0, 0, 0, 0.05, 0.35]
[0, 0, 0, 0, 0, 0.1]
根节点表root:
[1, 1, 2, 2, 2]
[0, 2, 2, 2, 4]
[0, 0, 3, 4, 5]
[0, 0, 0, 4, 5]
[0, 0, 0, 0, 5]
Process finished with exit code 0