无损压缩的定义
一种压缩技术:利用逆向算法(),能从压缩数据中完美重建原始数据,不丢失任何信息。
ByteQuest · YouTube · 5:52
本视频片段介绍无损数据压缩的概念,并演示一种朴素的定长编码算法。以文本“BANANA BANDANA”为例,计算其原始ASCII大小(112比特),确定表示唯一字符所需的最少比特数(3比特编码5个字符),计算编码后文本的大小(42比特),并计入码表开销(55比特),最终得到压缩后的总大小为97比特。 本150秒片段通过示例字符串“BANANA BANDANA”讲解霍夫曼编码。首先回顾一种定长3位编码,该编码将消息压缩为97位,而原始长度为112位,然后提问是否存在更优的方法。视频统计了各符号的出现频次(A:6, B:2, N:4, D:1,空间:1),创建加权叶节点,并反复合并两个最小节点,构建根节点权重为14的哈夫曼树。将左分支标记为1,右分支标记为0后,沿各符号从根到叶的路径读取其编码,得到 , , , ,以及 -=1111。最终要点是:出现频率更高的符号获得更短的码字,这正是哈夫曼编码的核心压缩思想。 这段52秒的片段为文本“BANANA BANDANA.”提供了霍夫曼编码的紧凑演算示例。它首先阐明关键原则:出现频率更高的字符获得更短的二进制码;随后显示一张表格:A:6→0,B:2→110,N:4→10,D:1→1110,空格:1→1111。示例文本被编码为一个28比特的字符串,视频明确添加54比特用于编码映射表,从而得到总计82比特。接着,它将该结果与先前提到的97比特朴素压缩结果进行比较,并指出霍夫曼编码在更大数据集上更具优势。最后几秒画面切换至 GitHub 上的 Python 实现文件 Huffman_compression.py,其中包含构建树、生成码字、编码、解码以及计算表大小等函数。
在学习检查器中查看要点和时刻,或切换阅读标签查看完整笔记。
依据视频画面与讲解整理,并非逐字语音转写。
视频首先将数据压缩定义为利用算法减小文件大小的过程。并以一个100MB的文件压缩为70MB为例加以说明。
接着定义无损压缩:应用逆向算法可完美还原原始的100MB文件。这为后续讲解霍夫曼编码奠定基础。
为在讲解霍夫曼编码前夯实基础,讲解者引入一种基于文本“BANANA BANDANA”的‘朴素’压缩方法。原始大小计算为14个字符乘以8比特/字符,等于112比特。
该方法识别出5个唯一字符(A、B、N、D、空格)。为用定长二进制码唯一表示这些字符,需检验容量:1比特可表示2个值,2比特可表示4个,3比特可表示8个。
由于,每个字符至少需要3比特。视频为这些唯一字符分配了3比特长的编码(例如,A:000,B:001……)。
用这些3位代码替换原始文本,可将有效载荷大小减少至143=42位。但解码器需要该映射关系。
代码表必须存储5个条目,每个条目包含原始的8位ASCII字符及其对应的新3位代码。这一开销为5(8+3)=55位。
压缩后的总大小变为42(有效载荷)+55(代码表)=97位。虽然小于112位,但定长代码表带来的高开销促使人们采用霍夫曼编码等更先进的方法。
该片段开头重访“BANANA BANDANA”的早期定长编码方案,其中每个符号占用3位。画面上,原显示的42位和55位被替换为97位,旁白指出该结果已小于原始的112位表示。
叙述者继而提问该消息能否被更高效地编码,并指出霍夫曼编码可优于前述方法。由此自然过渡到由符号频率驱动的变长编码,取代等长编码。
霍夫曼编码的第一个具体步骤是统计示例中各符号的出现次数。屏幕上可见的频次表为 A : 6,B : 2,N : 4,D : 1,- : 1,其中 - 表示空格字符。
每个不同的符号成为一个叶节点,其权重为其出现频率。然后将这些节点按权重从小到大排列,得到初始有序集合:-, D, B, N, A,对应权重分别为1、1、2、4、6。
引入核心构造规则:选取当前可用的两个权重最小的节点,将它们合并为一个新父节点,并令该父节点的权重等于二者权重之和。解说同时强调:一旦节点被合并,它们便不再被单独选取;后续步骤中仅其父节点参与。
将该规则应用于本例:权重为1的两个叶节点(- 和 D)首先合并,形成一个权重为2的内部节点。动画将新父节点置于其两个子节点上方,使树的生长过程清晰可见。
在剩余的顶层节点中,下一对权重最小的节点是新生成的权重为2的节点与权重为2的叶节点 B。将它们合并后生成一个权重为4的节点。视觉重点在于反复选取两个最小权重的节点,而非任意一对。
该过程继续进行:权重为4的节点与权重为4的叶节点 N 合并,形成一个权重为8的节点;随后该节点再与权重为6的叶节点 A 合并,最终生成权重为14的根节点。此时所有叶节点均已纳入一棵完整的二叉树中。
树结构完成后,视频调整布局以增强可读性,然后为各条边标注二进制数字。所采用的约定是:左分支标记为1,右分支标记为0;解说员指出,若将此约定反转,也不会改变本质结果。
现在直接从树中读取码字。为求某符号的编码,从根节点出发,沿唯一路径下行至该符号对应的叶节点,并依序记录途中各边的标签。
对于符号 A,路径仅含一条右分支,因此记录下的标签为0。本例使路径读取规则具体化:码字并非独立选定,而是完全由该叶节点在已标注的树中的位置决定。
对于符号 B,从根节点出发的路径依次经过左分支、左分支、右分支,得到110。随后对剩余叶节点应用相同步骤,得出 、、- = 1111。
最终表格汇总了结果,并列出了原始频率:A : 6 0,B : 2 110,N : 4 10,D : 1 1110,- : 1 1111。该展示将树的构造过程与实用的符号到编码映射关联起来。
最后的观察点是核心概念要点:高频符号获得较短的码字,低频符号则获得较长的码字。在本例中,出现频率最高的符号 A 获得一个1位的编码,而出现频率最低的符号 D 和 - 则分别获得4位的编码。
视频片段以示例字符串“BANANA BANDANA”开场,并配有一张表格,列出每个字符、其出现频次及对应的霍夫曼编码。旁白指出霍夫曼编码的基本设计原则:高频符号分配短码字,低频符号分配长码字。
在所展示的表格中,A 出现6次,获得1位编码0;N 出现4次,获得10;B 出现2次,获得110;D 和空格各出现一次,分别获得1110和1111。这使频次与码长之间的关系变得具体可感。
下一步是将原文中每个字符替换为其对应编码,并将所有编码连接成一个连续比特流。屏幕上显示完整的编码结果:110 0 10 0 10 0 1111 110 0 10 1110 0 10 0。
一个大括号将该有效载荷标注为28位。可通过查表验证该位数:将各字符频次乘以其码长再求和,即。
随后视频将焦点转向映射表本身。第二个大括号将该表标注为耗费54位,强调解码器同样需要字符到编码的对应关系。
屏幕上将这两部分数值合并,框出总计82位。其数学要点在于:压缩后的总存储量不仅包含编码后的消息,还包含映射表的开销。
讲述者将这一82位的结果与先前朴素压缩算法所得的97位结果进行对比,表明霍夫曼编码在此例中显著更优。
接着是一条定性说明:在更大规模的数据集上,该方法效果更佳,因为固定的映射表开销被分摊到更多编码字符上,从而使压缩优势更加明显。
最后一段离开例题演示,展示一个 GitHub 页面,其中包含 Python 文件 Huffman_compression.py。可见的函数名有 build_huffman_tree、build_codes、huffman_encoding、huffman_decoding 和 calculate_table_size,将概念性演示与实际实现联系起来。
一种压缩技术:利用逆向算法(),能从压缩数据中完美重建原始数据,不丢失任何信息。
为源文本中每个唯一字符分配相同长度的二进制代码。长度需满足条件:。
在定长压缩中,必须将一张将原始字符映射到其新代码的查找表与压缩数据一同存储,这会带来显著的大小开销。
在介绍哈夫曼编码之前,视频展示了对字符串“BANANA BANDANA”中各符号所采用的等长3位编码。该编码将原始信息从112比特压缩至97比特,但讲解者进一步提问:是否存在更优的编码方式?
哈夫曼编码首先统计每个符号出现的频次。对于示例字符串,各符号频次为:,,,,空格(-)= 1。
每个不同符号成为一个带权叶节点;在开始任何合并操作前,这些叶节点按频次升序排列。
反复选取当前可用节点中权重最小的两个,将它们合并到一个新父节点下,并令该父节点的权重等于其两个子节点权重之和。重复此过程,直至仅剩一个根节点。
示例树通过如下步骤构建:先合并,再合并,接着合并,最后合并。根节点权重14等于消息中的字符总数。
树构建完成后,每条边被赋予一个二进制数字。视频采用左分支 = 1、右分支 = 0的约定,并指出交换该约定不会影响最终结果。
一个符号的哈夫曼编码,是从根节点到该符号所在叶节点的路径上各条边的标签所组成的序列。本片段明确演示了符号 A 和 B 的这一过程。
完成的编码表为:A : 0, B : 110, N : 10, D : 1110, - : 1111。这些编码直接来自带标签的树中从根到叶的路径。
此处所阐释的核心思想是:出现频率更高的符号被放置在更靠近根节点的位置,因而获得更短的码字;而出现频率更低的符号则获得更长的码字。
视频片段直接阐明中心原理:为出现频率更高的字符分配更短的编码,为出现频率更低的字符分配更长的编码。这种依赖频率的编码分配方式被表述为哈夫曼编码高效性的原因。
该例题使用文本“BANANA BANDANA”,并展示一个五行表格:A 频率为6,对应编码0;B 频率为2,对应编码110;N 频率为4,对应编码10;D 频率为1,对应编码1110;空格频率为1,对应编码1111。该表格用具体的二进制码字实例化了上述通用规则。
将每个字符替换为其哈夫曼编码,得到比特串110 0 10 0 10 0 1111 110 0 10 1110 0 10 0。视频将该有效载荷标注为28比特,该数值与表格中频率乘以码长的算术结果一致。
在本例中,映射表本身占用了54比特。视频借此传授一个重要概念:压缩后的文件不仅包含编码后的符号,还包含用于解读这些符号所需的信息。
通过将28比特的有效载荷与54比特的编码表相加,视频得出总计82比特。该总数随后将与朴素压缩方法进行比较。
讲解者指出,82位的霍夫曼编码结果明显小于先前朴素压缩算法得到的97位。这一对比作为本例中实际改进效果的证据呈现。
片段在概念部分结尾处给出一个关于规模的观察:在更大的数据集上,霍夫曼编码变得更加有效,压缩效果的差异也更加显著。其隐含原因是编码表的开销被分摊到了更多已编码的符号上。
最后几秒展示了一个 GitHub 页面,其中可见 Python 文件 Huffman_compression.py,以及函数如 build_huffman_tree、build_codes、huffman_encoding、huffman_decoding 和 calculate_table_size。这将直观解释与可执行代码关联起来,而非引入新的理论。
按知识点查看条件、步骤和证据。补充解释与视频直接内容分别标明。
一个蓝色圆角矩形,标注为“数据”,出现在屏幕的左侧和右侧。
讲述者提到“一段数据”和“原始文件”。
Data
正在被压缩或解压缩的输入或输出数据。
文件或文本数据
一个红色圆圈,标注为“C”,显示在初始数据块与压缩后数据块之间。
讲述者说:“将其传入一个压缩算法。”
C
压缩算法。
将原始数据映射为压缩数据的函数
一个红色圆圈,标注为“”,显示在压缩后数据块与恢复后数据块之间。
讲述者说:“将其传入该算法的逆过程。”
逆过程(解压缩)算法。
将压缩数据映射回原始数据的函数
文本‘100 MB’和‘70 MB’分别显示在对应的数据块下方。
MB
兆字节,一种数字信息大小的单位。
正实数
文本‘112 bits’、‘42 bits’和‘55 bits’显示在各计算结果下方。
bits
二进制位,计算机中信息的基本单位。
非负整数
屏幕顶部显示文本‘BANANA BANDANA’。
讲解员说道:‘我们以一个文本例子开始——banana bandana,全部大写。’
BANANA BANDANA
用作压缩示例的特定字符字符串。
字符组成的字符串
讲解员指出:‘每个字符在ASCII中使用8位表示。’
ASCII
美国信息交换标准代码,一种字符编码标准。
字符集
标题文字“BANANA BANDANA”始终显示在画面顶部,用作频次统计与编码的示例字符串。
BANANA BANDANA
用于统计字符频次并进行编码的示例输入字符串。
一个由字母A、B、N、D及一个空格字符(用“-”表示)组成的14字符字符串。
垂直列表依次显示:A : 6,B : 2,N : 4,D : 1,- : 1。
A : 6, B : 2, N : 4, D : 1, - : 1
该示例字符串的频次表;每个符号均与其出现次数配对。
出现在“BANANA BANDANA”中的字符;其频次均为正整数。
屏幕先后显示“42 bits”、“55 bits”,随后替换为“97 bits”。
讲述者指出,总大小变为97比特,远小于原始的112比特。
42 bits, 55 bits, 97 bits, 112 bits
用于比较该示例消息不同编码方式的比特长度量。
非负整数形式的比特数。
叶节点标注有字符及权重1、1、2、4、6;内部节点则按合并生成,权重分别为2、4、8、14。
讲述者说明:新节点的频次等于刚刚合并的两个节点的频次之和。
node frequency / weight
附加在霍夫曼树节点上的数值标签,等于该节点下方所有叶节点频率之和。
本例中的正整数。
二进制标签1和0在树构建完成后标注在树的边上。
讲解者指出,所有左向边均被赋予1,所有右向边均被赋予0;且对调这两者的赋值方式不会影响最终结果。
edge value 0 or 1
分配给树边的二进制数字;叶节点的编码即为从根节点到该叶节点路径上各边所赋数字组成的序列。
每条边恰好被分配一个二进制数字。
讲述者将无损压缩定义为在不丢失任何信息的前提下恢复原始文件。
标题变为“无损压缩”,同时展示过程。
无损压缩是一种技术:压缩后的文件可通过压缩算法的逆算法进行处理,从而精确还原原始文件,整个过程中不丢失任何数据。
逆算法必须存在且被正确应用。
讲解员解释分配3位编码给5个唯一字符。
一张表格将字符 A、B、N、D 和空格(-)分别映射为3位二进制字符串(000、001、010、100、101)。
一种朴素的压缩方法:文本中每个不同字符都被分配一个长度固定的二进制编码;该固定长度由表示全部不同字符所需的最少比特数决定。
每个字符所占的比特数必须足以对源文本中所有不同字符进行唯一编码。
讲述者解释1位、2位和3位各自能够表示多少个值。
列表显示:1位可表示0、1;2位可表示00、01、10、11;3位可表示从000到111。
由位组成的序列所能表示的不同数值的个数为。例如,1位可表示2个数值,2位可表示4个数值,3位可表示8个数值。
是位数。
讲解员指出,解码时需要存储编码表,这会额外占用若干比特。
计算表明,编码表共需比特。
在定长编码中,原始字符与其新编码之间的映射关系必须被存储。这一‘编码表’会增加压缩后文件的总大小。
解码器必须能够访问该编码表,才能还原出原始文本。
显示了一个固定映射:A : 000,B : 001,N : 010,D : 100,- : 101。
比特总数42比特和55比特被替换为97比特。
讲解员称,这使得总大小变为97比特,已远小于原始的112比特。
该片段首先回顾了一种等长编码,其中每个不同符号都被分配一个3比特的码字。使用该编码,示例消息从112比特压缩至97比特,从而引出进一步优化的必要性。
每个符号使用相同的码长,此处为3比特。
示例字母表为{A, B, N, D, -}。
讲解员提示观众记下示例中每个字母的出现频率。
出现如下列表:A : 6, B : 2, N : 4, D : 1, - : 1。
五个圆形节点出现,并按其数值频率从小到大排列。
霍夫曼编码始于统计源消息中每个符号的出现频次。所统计出的频次成为初始叶节点的权重,且这些叶节点在合并开始前按权重从小到大排序。
必须已知源消息,才能统计各符号频次。
每个不同符号成为一个初始叶节点。
讲解者指出,应选取频率最小的两个节点,并将它们合并为一个新节点,该新节点的频率等于这两个被合并节点的频率之和。
权重为1和1的节点合并为2;接着2和2合并为4;然后4和4合并为8;最后8和6合并为14。
每一步中,从当前所有可用节点中选出权重最小的两个节点,在它们上方创建一个父节点,并将该父节点的权重设为这两个节点权重之和。重复此过程,直至仅剩一个根节点。
当剩余节点多于一个时,持续重复该操作。
已合并的节点本身不再参与后续选择,除非通过其父节点间接参与。
讲述者指出,所有左分支边均赋值为1,所有右分支边均赋值为0;若反过来赋值,最终结果不受影响。
完成的树被重新标记:左分支上标1,右分支上标0。
霍夫曼树构建完成后,每条边都被赋予一个二进制数字。本视频采用的约定是:左 = 1,右 = 0;但采用相反约定所得的编码结构同样等价。
该树必须已是完整的。
所有边必须统一且一致地采用同一约定。
讲解者说明:要得到符号 A 的编码,需从根节点出发,沿树向下遍历至 A;该路径上仅有一个取值0,因此 。对于 B,该路径给出110。
最终表格列出:A : 6 0,B : 2 110,N : 4 10,D : 1 1110,- : 1 1111。
对每个叶节点符号,记录从根节点向下移动至该叶节点过程中所经过的各条边的标签序列;该序列即为该符号的哈夫曼编码。
使用已完整标注的树。
每个叶节点恰好对应一个信源符号。
讲解者指出:高频字母被分配较短的编码,低频字母被分配较长的编码,并称这是哈夫曼编码背后的关键思想。
最终表格在视觉上将较大频数与较短码字配对:A(6)→ 0,N(4)→ 10,B(2)→ 110,D(1)→ 1110,-(1)→ 1111。
此处演示的核心压缩原理是:更常见的符号被置于离根更近的位置,因而用更少的比特编码;而较罕见的符号位于更深的位置,因而需要更多比特。
适用于视频片段中展示的哈夫曼构造过程。
本片段中的陈述属于定性描述;未给出最优性证明。
讲解指出:更常出现的字符被分配较短的编码,而较少出现的字符则被分配较长的编码。
所显示的表格符合该规则:A 的频次为6、编码为0,N 的频次为4、编码为10,B 的频次为2、编码为110,而 D 和空格的频次均为1、编码分别为1110和1111。
本片段介绍了霍夫曼编码的核心设计思想:符号出现频率决定其码字长度。高频符号分配较短的二进制码,低频符号则分配较长的二进制码。示例表格通过将频率与码长1、2、3和4一一配对,明确呈现了这种对应关系。
适用于一组已知各符号频率的固定信源符号集。
该片段以示例文本“BANANA BANDANA”为例演示这一原理。
表格列出了:A:,B:,N:,D:,以及空格:。
视频为示例文本中的每个字符给出了具体的二进制码字映射。该表格随后既用于消息编码,也用于计算该映射信息本身所占用的存储开销。
仅针对示例字符串“BANANA BANDANA”。
假设所展示的频率即为编码所依据的符号统计信息。
讲解员得出结论:由于共有5个不同字符,因此至少需要3位。
若要用定长二进制码唯一地编码个不同字符,则至少需要位,使得。
共有个不同的字符需要编码。
编码是长度为的定长二进制字符串。
对所有正整数和。
讲解员指出,97比特已远小于原始的112比特。
屏幕上显示97比特,同时回溯到先前的112比特基准值。
对于该示例消息,屏幕上展示的定长编码使用97比特,小于原始的112比特。
原始消息大小为112比特。
该示例采用屏幕上展示的每符号3比特编码方案进行编码。
针对视频中展示的具体示例字符串。
讲解员提问我们能否做得更好,并回答:可以,借助霍夫曼编码。
视频指出,霍夫曼编码对此示例能产生比先前所展示编码更优的结果。
定长编码已被展示过。
当前讨论的是同一信源消息。
本片段中的例子未证明任何一般性定理。
讲解者指出,你也可以反过来操作,这不会影响最终结果。
将0分配给左分支、1分配给右分支(而非视频中展示的约定)不会影响最终结果。
底层的树结构保持不变。
仅交换了边上二进制标签。
针对本片段中展示的基于树的编码构造方法。
讲解者指出,频率较高的字母被分配较短的码字,频率较低的字母被分配较长的码字。
最终的码表明确体现了这一顺序。
对于本例中的树,频率较大的符号所获得的码字比频率较小的符号更短。
请使用本片段中已完成的哈夫曼树及最终码表。
在具体示例中观察得出;视频将其呈现为关键思想,而非一般性证明。
旁白指出,为高频字符分配较短编码、为低频字符分配较长编码,正是霍夫曼编码高效的原因。
霍夫曼编码之所以高效,是因为它为高频符号分配较短的码字,为低频符号分配较长的码字。
源符号上存在已知的频率分布。
编码依据示例中所展示的霍夫曼原则进行分配。
针对演示示例中的符号。
旁白指出,文本占28比特,码表占54比特,总计为82比特。
屏幕上显示28比特、54比特,以及一个框出的82比特。
对于字符串“BANANA BANDANA”及所展示的霍夫曼编码表,总存储量为82比特,其中编码文本占28比特,编码表占54比特。
使用所展示的编码表。
总计时需同时包含编码后的消息与映射表。
针对此特定示例字符串及该编码表。
讲解员指出,82比特明显小于使用朴素压缩算法所得的97比特。
本片段中并未重新推导朴素算法本身。
霍夫曼编码结果82比特明显小于此前讨论的朴素压缩算法所得的97比特结果。
此前提到的97比特数值,指的是同一示例文本在朴素方法下的结果。
总大小是在相同基准下进行比较的。
以“BANANA BANDANA”为例。
讲述者指出,在更大的数据集上,该算法效果更佳,压缩效果的差异也更加明显。
这是一个定性论断,片段中未提供证明或数值演示。
当霍夫曼编码应用于更大的数据集时,其压缩优势变得更加突出。
同一通用编码方案被应用于更大的输入。
对比中包含了编码表的开销。
针对比所展示的小例子更大的数据集。
逐步计算各部分大小:原始文本占112位,编码后文本占42位,编码表占55位。
讲解者逐步演示字符计数、每个字符的比特数以及编码表大小的计算过程。
计算文本‘BANANA BANDANA’(含空格共14个字符)的原始大小,使用8位ASCII编码。
ASCII编码的定义及基础乘法运算。
确定对5个不同字符(A、B、N、D、空格)进行编码所需的最少比特数。
二进制表示的容量()。
使用新的3位定长编码计算编码后文本的大小。
定长编码公式。
计算解码所需的码表大小,存储5个条目(每个条目包含8位原始码和3位编码)。
码表开销公式。
计算包含码表在内的压缩文件总大小。
编码后文本大小与码表大小之和。
朴素压缩后的文件总大小为97比特,小于原始的112比特,但码表开销(55比特)显著。
视频从五个带权叶节点出发,逐步构建该树。
讲解者说明了合并规则,并指出需重复执行,直至所有节点合并成一棵完整的哈夫曼树。
初始时,每个不同符号对应一个叶节点,权重为其出现频次,并按权重升序排列。
讲解者指出需记录各字符频次,为每个字符创建节点,再按频次升序排列。
将两个最小权重的叶节点——空格符号与 D——合并,生成一个权重为2的新内部节点。
所陈述的规则是:选取两个频次最小的节点,将其频次之和作为新节点的频次。
在其余可用节点中,将权重为2的新节点与权重为2的节点 B 合并,形成一个权重为4的节点。
讲解者指出,需持续检查剩余节点中频次最小的两个,已合并的元素应被排除。
将权重为4的节点与权重为4的节点 N 合并,生成一个权重为8的节点。
这遵循相同的“反复选取最小两个进行合并”的流程。
将权值为8的节点与权值为6的节点A合并,得到权值为14的根节点。
该过程持续进行,直至所有节点都被合并成一棵完整的哈夫曼树。
完成的哈夫曼树根节点权值为14,其叶节点对应于A、B、N、D以及空格符号。
讲解者说明了路径追踪法,并明确推导出和。
最终表格列出了全部五个码字。
关于N、D及空格符号的中间路径说明未被完整口述;它们的码字仅在最终表格中显示。
为完成树的每一条边标注一个二进制数字。
讲解者将1赋给左向边,将0赋给右向边。
从根节点到A仅经过一条右向边,因此路径标签为0。
讲解者明确追踪了从根节点到A的路径,并读出了唯一的数值0。
从根节点到B的路径依次经过左向边、左向边、右向边,结果为110。
讲解者明确追踪到节点 B 的路径,并读出110。
从根节点到节点 N 的路径先经过一条左分支,再经过一条右分支,得到10。
这遵循相同的根节点到叶节点的路径读取规则;该值显示在最终表格中。
从根节点到节点 D 的路径连续经过三条左分支,然后是一条右分支,得到1110。
这遵循相同的根节点到叶节点的路径读取规则;该值显示在最终表格中。
从根节点到空格符号的路径经过四条左分支,得到1111。
这遵循相同的根节点到叶节点的路径读取规则;该值显示在最终表格中。
最终生成的编码表为:,,,,- = 1111。
编码后的比特串显示在标题下方,并用“28比特”括起。
表格列出了符号频次6、2、4、1、1以及对应码长1、3、2、4、4。
从所显示的表格中读取符号频次和码长。
直接从屏幕上的码表中观察得出。
将每个符号的频率乘以其码长,再对所有符号求和。
根据符号到码字的映射计算总编码长度的标准方法。
计算该和式以得到有效载荷大小。
算术化简。
字符串“BANANA BANDANA”的编码结果占用28比特,与屏幕上的标签一致。
屏幕上将消息标注为28比特,将码表标注为54比特。
讲解员称这使得总比特数达到82比特。
54比特的码表开销内部构成并未在屏幕上推导。
取示例中显示的编码消息大小。
从图示与讲解中观察得出。
采用示例中所示的码表存储方式。
从图示和讲解中观察得出。
将这两部分开销相加,得到总存储量。
视频明确地将这两个量合并为一个总量。
当同时存储编码后的文本和映射表时,整个压缩表示共需 82 比特。
整个片段使用“BANANA BANDANA”来演示压缩步骤。
讲解员明确将此作为文本示例引入。
使用定长编码方案压缩文本“BANANA BANDANA”,并计算包含码表在内的总压缩大小。
文本:“BANANA BANDANA”(共14个字符)。
原始编码:8位ASCII码。
不重复字符:A、B、N、D、空格(共5个字符)。
计算朴素压缩后的总比特数。
计算未压缩时的大小。
14个字符 × 8比特/字符。
计算将字符替换为3比特编码后的文本大小。
5个不同字符需要3比特()。14个字符 × 3比特/字符。
计算解码所需的查找表大小。
5个条目 × (8比特用于原始字符 + 3比特用于新编码)。
将编码后文本的大小与编码表的大小相加。
加法。
97比特
结果97比特小于原始的112比特,证实了压缩发生,但相对于这段短文本而言,开销较大。
整段视频围绕单一示例字符串“BANANA BANDANA”展开。
讲解者以该例引入霍夫曼编码,并逐步演示频率统计、树的构建及编码提取过程。
给定消息“BANANA BANDANA”,构造霍夫曼编码,并确定每个符号对应的码字。
消息:BANANA BANDANA。
不同符号:A、B、N、D 和空格(-)。
所示频次:,,,,- = 1。
所示边约定:左侧 = 1,右侧 = 0。
构造哈夫曼树,并列出每个符号对应的二进制编码。
统计消息中每个符号出现的次数。
讲解者提示先记下各符号的频次。
为每个符号创建一个叶节点,并按频次升序排列。
视频中明确将节点按频次升序排列。
重复合并当前最小的两个节点,直至只剩一个根节点。
这是所陈述的哈夫曼合并规则。
为完成后的树的所有边分配二进制数字。
讲述者明确了这一约定,并指出反向约定也是可行的。
通过从根节点到对应叶节点的路径,读出每个符号的编码。
讲述者先以 A 和 B 为例进行演示,再将相同方法应用于其余符号。
A 对应 0,B 对应 110,N 对应 10,D 对应 1110,减号对应 1111。
最终呈现在屏幕上的表格与已完成树中的路径标签一致,片段同时强调:出现频率越高的符号,其编码越短。
完整演算示例已给出:标题文字、码表、编码比特串、28 比特、54 比特 和 82 比特。
讲解过程逐步演示了原文本的编码,以及消息长度与码表长度之和的计算。
用于存储 54 比特码表的具体比特级格式未予展示。
使用图中显示的霍夫曼编码对文本“BANANA BANDANA”进行编码,并计算包含码表在内的总存储量。
文本:BANANA BANDANA
频次与编码:A:,B:,N:,D:,空格:
编码后消息的大小显示为28比特
编码表的大小显示为54比特
求出编码后的比特串,以及存储压缩结果加编码表所需的总比特数。
用表中的哈夫曼编码替换字符串“BANANA BANDANA”中的每个字符。
直接应用所展示的映射关系。
统计拼接后所有码字的总长度。
由编码串下方的大括号标出,并由旁白确认。
计入编码表所需的存储空间。
旁白中已说明,并由围绕编码表的大括号标出。
将有效载荷与编码表开销相加,得到压缩后的总大小。
视频中明确指出并直观展示。
编码后的比特串:110 0 10 0 10 0 1111 110 0 10 1110 0 10 0;包含编码表在内的总存储量:82比特。
算术式 与显示的有效载荷大小一致,且 与显示的总数一致。
方块先从左向右穿过‘C’,再从右向左穿过‘’。
蓝色“数据”方块
红色“C”圆圈
红色“”圆圈
箭头
数据方块经过 C 后,从 100 MB 缩小为 70 MB。
数据块通过100MB,恢复为原始大小。
方块上始终保留“数据”标签。
标题“数据压缩”变为“无损压缩”。
直观呈现无损压缩算法的可逆性。
字符 A、B、N、D、- 垂直排列于主文本下方。
文本“BANANA BANDANA”
字符的垂直列表
括号与数字“5”
逐个提取并列出各个字符。
在列表旁显示5的计数。
原始文本保留在顶部。
演示定长编码的第一步:找出唯一符号构成的字母表。
依次出现1位、2位和3位的行,及其可能的组合。
文本行:“1位 : ……”,“2位 : ……”,“3位 : ……”
二进制组合列表呈指数增长(分别含2、4、8项)。
格式“n位 : [列表]”保持一致。
说明为何至少需要3位来表示5个不同字符。
为字符列表中的每个不同字符分配3位编码,然后用这些编码替换原文。
字符列表
编码分配(000、001等)
编码后的二进制字符串
字符旁的空位用3位编码填充。
原始文本“BANANA BANDANA”被直观映射为一长串二进制字符串。
该映射对各个不同字符是一一对应的。
展示源文本向压缩比特流的转换过程。
初始的定长映射及总比特数逐渐淡出,仅保留标题,随后出现频率列表。
标题:“BANANA BANDANA”
定长映射:A : 000, B : 001, N : 010, D : 100, - : 101。
总比特数:42 比特,55 比特,97 比特。
3比特的映射及总比特数消失。
屏幕清空,为频率统计做准备。
示例字符串保持不变。
视觉重置标志着从比较先前的编码方式,转向引入霍夫曼编码这一更优方法。
五个圆圈出现并排列成一行,每个圆圈标注符号及其出现频率。
频率列表:A : 6, B : 2, N : 4, D : 1, - : 1。
五个圆形叶节点,分别标注为 -、D、B、N、A,对应权重为 1、1、2、4、6。
数值型频率被转换为独立的节点对象。
这些节点按权重从小到大排列。
每个不同符号恰好对应一个初始叶节点。
动画表明,霍夫曼编码从加权叶节点出发,而这些叶节点仅由符号频率决定。
在每对较小节点上方添加父节点,红色箭头指向新生成的权重和。
叶节点:-、D、B、N、A。
带权重的内部节点:2、4、8、14。
红色箭头表示新生成的父节点。
两个权重最小的节点被反复合并到一个新父节点之下。
可用的顶层节点数量不断减少,直至只剩一个根节点。
每个父节点的权重等于其两个子节点权重之和。
原始的叶节点符号保留在树的底部。
不断生长的树直观地编码了定义霍夫曼构造的贪心合并过程。
在调整树的布局后,二进制数字出现在各条边上。
完成的霍夫曼树。
边上的标签:0和1。
左分支边标记为1。
右分支边标记为0。
在标记过程中,树的拓扑结构保持不变。
此步骤将抽象的合并树转化为具体的二进制码生成器。
根节点及通往A的路径以红色高亮显示,且代码0写在表格中A的旁边。
根节点14。
叶节点A。
边的标记0。
A在码表中的条目。
从根节点到A的路径被强调。
码字0被添加至A所在表格行。
此刻仅读取通往A的路径。
动画演示:一个符号的编码,恰好是其从根节点到叶节点路径上各条边的标签序列。
通往B的路径被高亮显示,且在B旁写出110;随后展示完整的最终表格。
对于N、D和-的中间高亮步骤,不如A和B那样明确,但最终表格清晰明了。
从根节点到B的路径。
最终表格:A : 6 0,B : 2 110,N : 4 10,D : 1 1110,- : 1 1111。
将B的码字110加入。
全部码字集合随之显现。
树结构逐渐淡出,仅留下最终汇总表格。
每个码字对应一条唯一的根节点到叶节点路径。
最终呈现将整个构造过程整合为一张查找表,并使频次与码长之间的规律清晰可见。
静态画面显示标题“BANANA BANDANA”以及一个五行表格,内容为字符、频次与编码。
标题文字“BANANA BANDANA”
各行分别为:A:6 0,B:2 110,N:4 10,D:1 1110,空格:1 1111
尚无动画;该表格以固定参考形式呈现。
在此时间段内,字符-频次-编码的映射关系保持不变。
本片段先确立符号统计结果及由此生成的变长编码,再演示编码过程。
二进制组依次出现在标题下方,构成示例文本的编码字符串。
编码后的分组:110、0、10、0、10、0、1111、110、0、10、1110、0、10、0
标题下方的空白区域从左至右依次填入各字符对应的码字。
右侧的码表始终保持可见且不变。
这可视化了每个源字符被其霍夫曼编码字替换,并连接成一个比特流的过程。
讲解员强调需要存储编码表,额外增加55位到42位有效载荷中。
假设减少每个字符的比特数总能显著减小文件大小,而未考虑解码所需的元数据。
对于短文本或大字母表,存储编码表的固定开销可能超过使用更短字符编码所带来的节省,导致朴素的定长压缩效率低下。
讲述者表示,你也可以反过来操作,这不会影响最终结果。
有人可能认为,为了使霍夫曼编码正常工作,左侧必须始终为1,右侧必须始终为0。
视频指出,交换边的约定不会影响最终结果;关键在于所选树内部的一致性。
讲述者强调,高频字母获得较短的编码,低频字母获得较长的编码。
固定长度的思维模式会让人觉得每个符号都应当使用相同数量的比特。
本片段将先前的固定长度编码方法与霍夫曼编码进行对比,后者中编码长度随频率而变化。
讲解者明确地将54位的编码表加到28位的消息上,得到82位。
画面区分了用于编码文本的28位和用于编码表的54位,再将二者合并。
人们可能误以为压缩后的大小就只是编码后消息的长度。
视频强调映射表也必须被存储,因此本例中真正的总大小为28+54=82位。
该表格展示了不同长度的码字:0、10、110、1110、1111。
讲解通过对比指出:高频字符使用较短的编码,低频字符使用较长的编码。
这一误解并未被口头点明;而是从与定长编码直觉的对比中推断得出。
定长编码的心理模型会为每个符号分配相同的比特宽度。
本例采用变长编码,其长度与字符出现频率相关,这正是本片段所强调的核心效率机制。
讲述者利用二进制容量规则来确定定长编码的3位长度。
理解位所能表示的数值个数,是选择定长编码中编码长度的必要前提。
讲述者解释,解码定长编码后的文本需要编码表。
编码表开销这一概念直接适用于定长编码方案的实现。
在展示先前方法得到的97比特后,讲述者提问我们能否做得更好,并以霍夫曼编码作答。
固定长度编码被作为基准呈现,霍夫曼编码旨在对此加以改进。
讲述者首先指出需记录频率并创建节点,接着强调关键步骤是合并这些节点。
频率统计提供了合并操作开始前所需的初始加权叶节点。
树构建完成后,讲解者接着为各条边分配二进制值。
必须先存在一棵完整的树,边上的标签才能定义码字。
完成边的标注后,讲解者指出该树现在可用于计算每个字母对应的编码。
边上的标签即为从根节点到叶节点路径上所读取的原始符号,由此生成码字。
最终的表格直观展示了高频符号对应短编码、低频符号对应长编码。
讲解者称这一模式为霍夫曼编码背后的关键思想。
提取出的编码表体现了霍夫曼编码的一般原则:符号出现频率决定其编码长度。
讲解明确指出了基于频率的编码分配规则。
该表格用具体的编码实例化了这一规则。
将通用的基于频率的原理应用于生成“BANANA BANDANA”的特定编码表。
通过按所展示的表格替换每个字符,形成编码后的比特串。
直接使用示例表格计算28比特的编码有效载荷。
视频先展示28比特和54比特,再将它们合并为82比特。
总尺寸结论依赖于先确定有效载荷尺寸,再加入编码表开销。
54比特的编码表标签与28比特的有效载荷标签合并,得到总尺寸。
总尺寸公式还依赖于单独测得的编码表开销。
在计算出包含编码表开销的82比特后,讲解者指出:数据集越大,其优势越明显。
片段中的缩放论证是定性的。
观察到编码表开销是一项独立的加性成本,这支持了“输入规模越大,其相对影响越小”的论断。
叙述中给出的定义。
二进制容量的可视化列表。
计算位。
屏幕上显示97比特替换了42比特和55比特。
讲解者将97比特与原始的112比特进行比较。
讲解者指出,应首先记录各符号的频率,然后按频率递增顺序创建并排列节点。
讲述者陈述了规则:选取两个最小的频率,将它们相加形成一个新节点。
讲述者将1分配给左分支,将0分配给右分支,并指出反过来也同样可行。
讲述者通过从根节点追踪路径,明确推导出 。
讲述者总结道:高频字母获得较短的编码,低频字母获得较长的编码。
解说说明了为何出现频率更高的字符会分配更短的编码。
编码表可见,其中列出了各字符的出现频率及其对应的二进制编码。
编码后的字符串长度标注为28比特。
已覆盖 · 数据压缩与无损压缩简介
已覆盖 · 使用字符串“BANANA BANDANA”详解朴素的定长压缩方法。
已覆盖 · 回顾此前的定长编码,并对比97比特与112比特。
已覆盖 · 引入霍夫曼编码,并构建初始的按频率排序的叶节点。
已覆盖 · 逐步合并两个最小的节点,直至生成完整的霍夫曼树。
已覆盖 · 调整树的布局,并为各分支分配二进制标签。
已覆盖 · 沿根到叶路径读取码字,并呈现最终的编码表。
已覆盖 · 最后指出:频率越高的符号对应越短的编码。
已覆盖 · 音频部分阐述了基于频率的码长原则,而静态表格则展示了对应的映射示例。
已覆盖 · 编码后的比特串在屏幕上逐步构建,并标注为28比特。
已覆盖 · 表格开销标注为54比特,并与有效载荷合并得到82比特。
已覆盖 · 旁白将82比特与朴素方法所得的97比特进行比较,并评论了更大数据集的情况。
已覆盖 · 画面切换至一个 GitHub 页面,展示 Python 实现文件及函数;这是上下文相关的实现画面,而非新的数学推导。
已审核的主题路径