Algorithm 反向哈夫曼编码

Algorithm 反向哈夫曼编码,algorithm,math,Algorithm,Math,假设我有一个带有预定义二进制前缀代码的单词集合。给定一个非常大的随机二进制数据块,我可以使用前缀代码将该数据块解析为单词 我想至少大致确定(对于长度非常大的随机块)每个单词的点击数的期望值(在解码文本中被提及的次数) 乍一看,这个问题似乎微不足道——从随机比特池中扫描每个字的概率完全取决于其长度(因为每个比特可以是0或1)。但我怀疑这是对上述问题的错误回答,因为单词有不同的长度,因此这个概率与预期的点击数(除以数据块的长度)不一样 UPD:我被要求(在下面的评论中)用数学的方法来陈述这个问题,现

假设我有一个带有预定义二进制前缀代码的单词集合。给定一个非常大的随机二进制数据块,我可以使用前缀代码将该数据块解析为单词

我想至少大致确定(对于长度非常大的随机块)每个单词的点击数的期望值(在解码文本中被提及的次数)

乍一看,这个问题似乎微不足道——从随机比特池中扫描每个字的概率完全取决于其长度(因为每个比特可以是0或1)。但我怀疑这是对上述问题的错误回答,因为单词有不同的长度,因此这个概率与预期的点击数(除以数据块的长度)不一样

UPD:我被要求(在下面的评论中)用数学的方法来陈述这个问题,现在就这样

w成为一个只有0和1的单词列表(我们的字母表只有两个字母)。此外,w中没有任何单词是任何其他单词的前缀。因此,w形成合法的二进制前缀代码。我想知道(至少大约)点击的平均值,对于w中的每个单词,在所有可能的固定大小的二进制数据块上取平均值nn可以理解为非常大,比我们的任何字长都大得多。然而,单词的长度不同,这一点不容忽视


如果有人能提到解决这个问题的方法,我将不胜感激。

让我们制作一台能够识别单词的简单机器:一台具有每个单词接受状态的DFA。要构造此DFA,请从一个二叉树开始,每个左子边标记为0,每个右子边标记为1。每个叶要么是单词接受器(如果树下该叶的路径是单词的拼写),要么是垃圾(不是任何有效单词前缀的字母字符串)。我们将“重新启动”边从树叶连接回树根*

让我们找出匹配每个单词的频率,如果我们有一个无限长的字符串。为此,将DFA图视为马尔可夫状态转移图,以概率1和所有其他状态0将起始状态初始化为根,并找到稳态分布(通过找到转移图对应矩阵的主特征向量)

我们的弦不是无限长的。但由于n很大,我认为“边缘效应”没有那么重要。我们可以通过将匹配率按单词计算并乘以n来近似匹配频率。如果我们想更精确一些,我们不需要取特征向量,只需要将转移矩阵取到nth次方,然后将其与开始分布相乘,得到n个字母后的结果分布

*这不是很精确,因为这个马尔可夫系统会在根上花费一些非零的时间,当识别一个单词或跳过垃圾后,它应该立即转到0-child或1-child。因此,我们实际上并没有将“重新启动”边连接到根:从一个单词接受节点,我们连接两个重新启动边(一个连接到根的0-child,一个连接到根的1-child);我们用0-child的边替换剩下的子节点的垃圾节点;我们用1-child的边替换作为正确子级的垃圾节点。事实上,如果我们将初始状态设置为概率为0.5的0和概率为0.5的1,我们甚至不需要根

编辑:要使用@WhatsUp的示例,我们从如下所示的DFA开始:

我们将其重新布线一点,以便在接受一个字后重新启动,并除去根节点:

相应的马尔可夫转移矩阵为:

0.5    0  0.5  0.5
0.5    0  0.5  0.5
  0  0.5    0    0
  0  0.5    0    0
其第一特征向量为:

0.333
0.333
0.167
0.167

也就是说,它在0节点上花费了1/3的时间,在1节点上花费了1/3的时间,在10节点上花费了1/6的时间,在11节点上花费了1/6的时间。这与@WhatsUp在该示例中的结果是一致的。

我的简要回答是:可以为每个给定的单词列表计算预期的点击次数(或者更确切地说是预期的点击比例)

我将不描述完整的算法,但只做下面的示例来详细说明:让我们修复以下由三个单词组成的非常简单的列表:
0
10
11

对于每个
n
,都有
2^n
不同长度的数据块
n
(我的意思是
n
位),每个数据块都以相同的概率出现
2^(-n)

第一个观察结果是,并非所有的数据块都能被准确解码-例如,数据
0101
,当您解码时,最终将保留一个
1

让我们写
U(n)
来计算可以精确解码的长度
n
数据块的数量,并写
V(n)
来计算其他数据块(即最后有额外
1
的数据块)。以下循环关系是明确的:

  • U(n)+V(n)=2^n

  • V(n)=U(n-1)

  • 初始值
    U(0)
    =1和
    V(0)=0

    简单计算后得出:

    U(n)=(2^(n+1)+(-1)^n)/3

    现在让
    A(n)
    (resp.
    B(n)
    C(n)
    )为所有
    U(n)
    精确数据块的单词
    0
    (resp.
    10
    11
    )的点击次数之和,并让
    A(n)
    (resp.
    B(n)
    C(n)
    )为所有
    V(n)的点击次数之和
    不精确的数据块(最后一个
    1
    在本例中不计算在内)

    那么我们有以下关系:

  • a(n)=a(n-1)
    b(n)=b(n-1)
    c(n)=c(n-1)
  • A(n)=A(n