【数据结构-树】哈夫曼树

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
img

  • 推荐:kuan 的首页,持续学习,不断总结,共同进步,活到老学到老
  • 导航
    • 檀越剑指大厂系列:全面总结 java 核心技术点,如集合,jvm,并发编程 redis,kafka,Spring,微服务,Netty 等
    • 常用开发工具系列:罗列常用的开发工具,如 IDEA,Mac,Alfred,electerm,Git,typora,apifox 等
    • 数据库系列:详细总结了常用数据库 mysql 技术点,以及工作中遇到的 mysql 问题等
    • 懒人运维系列:总结好用的命令,解放双手不香吗?能用一个命令完成绝不用两个操作
    • 数据结构与算法系列:总结数据结构和算法,不同类型针对性训练,提升编程思维,剑指大厂

非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨

博客目录

    • 一.哈夫曼算法
      • 1.什么是编码?
      • 2.编码传输规则
      • 3.Huffman 编码
    • 二.哈夫曼树
      • 1.什么 Huffman 树?
      • 2.哈夫曼树特点
      • 3.节点总数证明
      • 4.Huffman 树特点
    • 三.常见方法
      • 1.内部 Node 节点
      • 2.构造方法
      • 3.编码
      • 4.解码
      • 5.完整代码
    • 四.练习题
      • 1.连接棒材的最低费用-力扣 1167 题

一.哈夫曼算法

1.什么是编码?

简单说就是建立【字符】到【数字】的对应关系,如下面大家熟知的 ASC II 编码表,例如,可以查表得知字符【a】对应的数字是十六进制数【0x61】

\000102030405060708090a0b0c0d0e0f
0000000102030405060708090a0b0c0d0e0f
0010101112131415161718191a1b1c1d1e1f
002020!"#$%&()*+,-./
00300123456789:;<=>?
0040@ABCDEFGHIJKLMNO
0050PQRSTUVWXYZ[\]^_
0060`abcdefghijklmno
0070pqrstuvwxyz{|}~7f

注:一些直接以十六进制数字标识的是那些不可打印字符

2.编码传输规则

传输时的编码

  • java 中每个 char 对应的数字会占用固定长度 2 个字节
  • 如果在传输中仍采用上述规则,传递 abbccccccc 这 10 个字符
    • 实际的字节为 0061006200620063006300630063006300630063(16 进制表示)
    • 总共 20 个字节,不经济

现在希望找到一种最节省字节的传输方式,怎么办?

假设传输的字符中只包含 a,b,c 这 3 个字符,有同学重新设计一张二进制编码表,见下图

  • 0 表示 a
  • 1 表示 b
  • 10 表示 c

现在还是传递 abbccccccc 这 10 个字符

  • 实际的字节为 01110101010101010 (二进制表示)
  • 总共需要 17 bits,也就是 2 个字节多一点,行不行?

不行,因为解码会出现问题,因为 10 会被错误的解码成 ba,而不是 c

  • 解码后结果为 abbbababababababa,是错误的

怎么解决?必须保证编码后的二进制数字,要能区分它们的前缀(prefix-free)

用满二叉树结构编码,可以确保前缀不重复

image-20230616094945068

  • 向左走 0,向右走 1
  • 走到叶子字符,累计起来的 0 和 1 就是该字符的二进制编码

再来试一遍

  • a 的编码 0
  • b 的编码 10
  • c 的编码 11

现在还是传递 abbccccccc 这 10 个字符

  • 实际的字节为 0101011111111111111(二进制表示)
  • 总共需要 19 bits,也是 2 个字节多一点,并且解码没有问题了,行不行?

这回解码没问题了,但并非最少字节,因为 c 的出现频率高(7 次)a 的出现频率低(1 次),因此出现频率高的字符编码成短数字更经济

3.Huffman 编码

考察下面的树

image-20230616095129461

  • 00 表示 a
  • 01 表示 b
  • 1 表示 c

现在还是传递 abbccccccc 这 10 个字符

  • 实际的字节为 000101 1111111 (二进制表示)
  • 总共需要 13 bits,这棵树就称之为 Huffman 树
  • 根据 Huffman 树对字符和数字进行编解码,就是 Huffman 编解码

二.哈夫曼树

1.什么 Huffman 树?

哈夫曼树,英文名 huffman tree,它是一种的叶子节点带有权重的特殊二叉树,也叫最优二叉树。

哈夫曼(Huffman)编码是上个世纪五十年代由哈夫曼教授研制开发的,它借助了数据结构当中的树型结构,在哈夫曼算法的支持下构造出一棵最优二叉树,我们把这类树命名为哈夫曼树。

哈夫曼树是带权路径长度最短的树,权值较大的节点离根较近。

2.哈夫曼树特点

哈夫曼树的特点:

  • 没有度为1的节点(每个非叶子节点都是由两个最小值的节点构成)

  • n 个叶子节点的哈夫曼树总共有2n-1个节点;

  • 哈夫曼树的任意非叶节点的左右子树交换后仍是哈夫曼树

  • 对同一组权值{w1,w2,…},存在不同构的两个哈夫曼树,但是它们的总权值相等。

  • 形成了这样的一颗哈夫曼树,这也是二叉树的前序

3.节点总数证明

证明哈夫曼树中有 n 个叶子节点的树总共有 2n-1 个节点可以使用数学归纳法。以下是证明的步骤:

步骤 1:基础情况
当 n=1 时,只有一个叶子节点,因此整棵哈夫曼树只有一个节点。这是一个基础情况。

步骤 2:归纳假设
假设对于某个正整数 k,当哈夫曼树有 k 个叶子节点时,它总共有 2k-1 个节点。

步骤 3:归纳证明
现在,考虑有 k+1 个叶子节点的情况。我们可以将这个问题分成两个部分:

部分 1: 从 k 个叶子节点构建一个哈夫曼树,根据归纳假设,这个树有 2k-1 个节点。

部分 2: 现在,我们添加一个额外的叶子节点,构建一个新的哈夫曼树。在这个新树中,我们需要添加一个新的内部节点,作为新叶子节点和部分 1 中的树的根节点的父节点。这个新树总共有 2k 个叶子节点和 1 个额外的内部节点,所以共有 2k+1 个节点。

现在,将部分 1 和部分 2 合并在一起,我们得到了有 k+1 个叶子节点的哈夫曼树,总共有(2k-1) + (2k+1) = 2k-1 + 2k+1 = 2(k-1+2) = 2k+1-1 个节点。

这证明了对于 k+1 个叶子节点的情况,有 2k+1-1 个节点,即当 n=k+1 时,也成立。

由于基础情况成立,并且我们已经证明了当 n=k+1 时成立,所以根据数学归纳法,对于所有正整数 n,有 n 个叶子节点的哈夫曼树总共有 2n-1 个节点。

4.Huffman 树特点

哈夫曼树(Huffman Tree)是一种用于数据压缩的树形数据结构,它具有以下几个特点:

  1. 最优编码:哈夫曼树被设计用来实现最优的数据压缩编码,这意味着它可以生成具有最小平均编码长度的编码方案,以便在数据传输或存储时能够节省空间。

  2. 基于频率:哈夫曼树的构建是基于数据中各个字符(或符号)的出现频率来进行的。频率高的字符被赋予较短的编码,而频率低的字符被赋予较长的编码。

  3. 唯一性:对于给定的数据集,存在唯一的哈夫曼树。这意味着如果两个人使用相同的数据集和相同的构建规则来创建哈夫曼树,它们将得到相同的树结构和编码。

  4. 前缀编码:哈夫曼编码是一种前缀编码,意味着没有一个字符的编码是另一个字符编码的前缀。这个特性确保在解码时不会产生歧义。

  5. 树形结构:哈夫曼树是一种二叉树,它由内部节点和叶子节点组成。叶子节点对应于数据集中的字符,而内部节点是用于构建编码的辅助节点。

  6. 压缩率:哈夫曼编码通常能够实现较高的压缩率,尤其是对于具有不同频率分布的数据集。频率高的字符使用较短的编码,从而实现更好的压缩效果。

  7. 动态性:哈夫曼编码可以动态地根据数据集的特性进行调整,以适应不同的数据。这使得它在各种应用中都具有灵活性。

总之,哈夫曼树是一种用于数据压缩的有效工具,其特点包括最优编码、基于频率、唯一性、前缀编码、树形结构、高压缩率和动态性。通过合理构建哈夫曼树,可以实现高效的数据压缩和解压缩操作。

三.常见方法

1.内部 Node 节点

/*** Node代表字符节点*/
static class Node {/*** 字符*/Character ch;/*** 频次*/int freq;/*** 左子节点*/Node left;/*** 右子节点*/Node right;/*** 编码*/String code;public Node(Character ch) {this.ch = ch;}public Node(int freq, Node left, Node right) {this.freq = freq;this.left = left;this.right = right;}int freq() {return freq;}boolean isLeaf() {return left == null;}@Overridepublic String toString() {return "Node{" + "ch=" + ch + ", freq=" + freq + '}';}
}

2.构造方法

public HuffmanTree(String str) {this.str = str;// 功能1:统计字符的频率char[] chars = str.toCharArray();for (char c : chars) {Node node = map.computeIfAbsent(c, Node::new);node.freq++;}// 功能2: 构造树PriorityQueue<Node> queue = new PriorityQueue<>(Comparator.comparingInt(Node::freq));queue.addAll(map.values());while (queue.size() >= 2) {Node x = queue.poll();Node y = queue.poll();int freq = x.freq + y.freq;queue.offer(new Node(freq, x, y));}root = queue.poll();// 功能3:计算每个字符的编码,int sum = dfs(root, new StringBuilder());for (Node node : map.values()) {System.out.println(node + " " + node.code);}// 功能4:字符串编码后占用 bitsSystem.out.println("总共会占用 bits:" + sum);
}private int dfs(Node node, StringBuilder code) {int sum = 0;if (node.isLeaf()) {node.code = code.toString();sum = node.freq * code.length();} else {sum += dfs(node.left, code.append("0"));sum += dfs(node.right, code.append("1"));}if (code.length() > 0) {code.deleteCharAt(code.length() - 1);}return sum;}

3.编码

public String encode() {//abbcccccccchar[] chars = str.toCharArray();StringBuilder sb = new StringBuilder();for (char c : chars) {sb.append(map.get(c).code);}return sb.toString();
}

4.解码

public String decode(String str) {/*从根节点,寻找数字对应的字符数字是 0 向左走数字是 1 向右走如果没走到头,每走一步数字的索引 i++走到头就可以找到解码字符,再将 node 重置为根节点a 00b 10c 1i0   0   0   1   0   1   1   1   1   1   1   1   1*/char[] chars = str.toCharArray();int i = 0;StringBuilder sb = new StringBuilder();Node node = root;//             i = 13  node=root// 0001011111111while (i < chars.length) {if (!node.isLeaf()) { // 非叶子if (chars[i] == '0') { // 向左走node = node.left;} else if (chars[i] == '1') { // 向右走node = node.right;}i++;}if (node.isLeaf()) {sb.append(node.ch);node = root;}}return sb.toString();
}

5.完整代码

/*** Huffman 树的构建过程* 1. 将统计了出现频率的字符,放入优先级队列* 2. 每次出队两个频次最低的元素,给它俩找个爹* 3. 把爹重新放入队列,重复 2~3* 4. 当队列只剩一个元素时,Huffman 树构建完成** @author : qinyingjie* @date : 2023/9/26*/
public class HuffmanTree {/*** Node代表字符节点*/static class Node {/*** 字符*/Character ch;/*** 频次*/int freq;/*** 左子节点*/Node left;/*** 右子节点*/Node right;/*** 编码*/String code;public Node(Character ch) {this.ch = ch;}public Node(int freq, Node left, Node right) {this.freq = freq;this.left = left;this.right = right;}int freq() {return freq;}boolean isLeaf() {return left == null;}@Overridepublic String toString() {return "Node{" + "ch=" + ch + ", freq=" + freq + '}';}}String str;/*** 统计字符数量,key是字符,value是节点*/Map<Character, Node> map = new HashMap<>();/*** 根节点*/Node root;public HuffmanTree(String str) {this.str = str;// 功能1:统计字符的频率char[] chars = str.toCharArray();for (char c : chars) {Node node = map.computeIfAbsent(c, Node::new);node.freq++;}// 功能2: 构造树PriorityQueue<Node> queue = new PriorityQueue<>(Comparator.comparingInt(Node::freq));queue.addAll(map.values());while (queue.size() >= 2) {Node x = queue.poll();Node y = queue.poll();int freq = x.freq + y.freq;queue.offer(new Node(freq, x, y));}root = queue.poll();// 功能3:计算每个字符的编码,int sum = dfs(root, new StringBuilder());for (Node node : map.values()) {System.out.println(node + " " + node.code);}// 功能4:字符串编码后占用 bitsSystem.out.println("总共会占用 bits:" + sum);}private int dfs(Node node, StringBuilder code) {int sum = 0;if (node.isLeaf()) {node.code = code.toString();sum = node.freq * code.length();} else {sum += dfs(node.left, code.append("0"));sum += dfs(node.right, code.append("1"));}if (code.length() > 0) {code.deleteCharAt(code.length() - 1);}return sum;}// 编码public String encode() {//abbcccccccchar[] chars = str.toCharArray();StringBuilder sb = new StringBuilder();for (char c : chars) {sb.append(map.get(c).code);}return sb.toString();}// 解码public String decode(String str) {/*从根节点,寻找数字对应的字符数字是 0 向左走数字是 1 向右走如果没走到头,每走一步数字的索引 i++走到头就可以找到解码字符,再将 node 重置为根节点a 00b 10c 1i0   0   0   1   0   1   1   1   1   1   1   1   1*/char[] chars = str.toCharArray();int i = 0;StringBuilder sb = new StringBuilder();Node node = root;//             i = 13  node=root// 0001011111111while (i < chars.length) {if (!node.isLeaf()) { // 非叶子if (chars[i] == '0') { // 向左走node = node.left;} else if (chars[i] == '1') { // 向右走node = node.right;}i++;}if (node.isLeaf()) {sb.append(node.ch);node = root;}}return sb.toString();}public static void main(String[] args) {HuffmanTree tree = new HuffmanTree("abbccccccc");String encoded = tree.encode();System.out.println(encoded);System.out.println(tree.decode(encoded));}
}

四.练习题

1.连接棒材的最低费用-力扣 1167 题

题目编号题目标题算法思路
1167(Plus 题目)连接棒材的最低费用Huffman 树、贪心

为了装修新房,你需要加工一些长度为正整数的棒材 sticks。

如果要将长度分别为 X 和 Y 的两根棒材连接在一起,你需要支付 X + Y 的费用。

由于施工需要,你必须将所有棒材连接成一根。

返回你把所有棒材 sticks 连成一根所需要的最低费用。注意你可以任意选择棒材连接的顺序。

示例 1:
输入:sticks = [2,4,3]
输出:14
解释:先将 2 和 3 连接成 5,花费 5;再将 5 和 4 连接成 9;总花费为 14。
示例 2:
输入:sticks = [1,8,3,5]
输出:30
提示:
1 <= sticks.length <= 10^4
1 <= sticks[i] <= 10^4

题解

/*** <h3>连接棒材的最低费用</h3>* <p>为了装修新房,你需要加工一些长度为正整数的棒材。如果要将长度分别为 X 和 Y 的两根棒材连接在一起,你需要支付 X + Y 的费用。 返回讲所有棒材连成一根所需要的最低费用。</p>*/
public class Leetcode1167 {/*举例 棒材为 [1,8,3,5]如果以如下顺序连接(非最优)- 1+8=9- 9+3=12- 12+5=17总费用为 9+12+17=38如果以如下顺序连接(最优)- 1+3=4- 4+5=9- 8+9=17总费用为 4+9+17=30*/int connectSticks(int[] sticks) {PriorityQueue<Integer> queue = new PriorityQueue<>();for (int stick : sticks) {queue.offer(stick);}int sum = 0;while (queue.size() >= 2) {Integer x = queue.poll();Integer y = queue.poll();int c = x + y;sum += c;queue.offer(c);}return sum;}public static void main(String[] args) {Leetcode1167 leetcode = new Leetcode1167();System.out.println(leetcode.connectSticks(new int[]{1, 8, 3, 5})); // 30System.out.println(leetcode.connectSticks(new int[]{2, 4, 3})); // 14}
}

觉得有用的话点个赞 👍🏻 呗。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

img

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/142092.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【算法思想-排序】根据另一个数组次序排序 - 力扣 1122 题

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…

超越代写!5步教你轻松利用ChatGPT创作文本

任何尝试用 ChatGPT 写过“写一篇关于【主题】的文章”的人都知道一个真相&#xff1a; ChatGPT 根本写不好&#xff0c;这不是秘密。如果你怀疑我&#xff0c;试试用它或者任何 AI 写作工具去写一篇博客文章&#xff0c;结果它都会写出非常糟糕的、没人会想看的内容。 但是我…

springboot基于SpringBoot的冬奥会科普平台springboot21

大家好✌&#xff01;我是CZ淡陌。一名专注以理论为基础实战为主的技术博主&#xff0c;将再这里为大家分享优质的实战项目&#xff0c;本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#xff0c;希望你能有所收获&#xff0c;少走一些弯路…

基于微信小程序的动漫论坛平台设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言系统主要功能&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…

RocketMQ生产环境常见问题分析与总结

关于零拷贝与顺序写 一、RocketMQ如何保证消息不丢失 1、哪些环节会有丢消息的可能&#xff1f; 我们考虑一个通用的MQ场景&#xff1a; 其中&#xff0c;1&#xff0c;2&#xff0c;4三个场景都是跨网络的&#xff0c;而跨网络就肯定会有丢消息的可能。 然后关于3这个环节…

地球的某一片红薯地中秋圆《乡村振兴战略下传统村落文化旅游设计》——旅行季许少辉八月新书辉少许想象和世界一样宽广

地球的某一片红薯地中秋圆《乡村振兴战略下传统村落文化旅游设计》——旅行季许少辉八月新书辉少许想象和世界一样宽广 地球的某一片红薯地中秋圆《乡村振兴战略下传统村落文化旅游设计》——旅行季许少辉八月新书辉少许想象和世界一样宽广]

JetBrains常用插件

Codota AI Autocomplete Java and JavaScript&#xff1a;自动补全插件 Background Image plus&#xff1a;背景图片设置 rainbow brackets&#xff1a;彩虹括号&#xff0c;便于识别 CodeGlance2&#xff1a; 类似于 Sublime 中的代码缩略图&#xff08;代码小地图&#xff…

什么是Redux?它的核心概念有哪些?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 什么是Redux&#xff1f;⭐ 它的核心概念有哪些&#xff1f;⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发…

如何通过bat批处理实现快速生成文件目录,一键生成文件名和文件夹名目录

碰对了情人&#xff0c;相思一辈子。 具体方法步骤&#xff1a; 一、创建一个执行bat文件&#xff08;使用记事本即可&#xff09;&#xff1b; 1、新建一个txt文本空白记事本文件 2、复制以下内容进记事本内 dir/a/s/b>LIST.TXT &#xff08;其中LIST.TXT文件名是提取后将…

【Go】rsrc不是内部或外部命令、无法将“rsrc”项识别为 cmdlet、函数、脚本文件或可运行程序的名称 解决方法

前言 想尝试用go创建一个桌面应用程序&#xff0c;然后查了下决定用 walk。 我们要先下载walk&#xff0c;这里 官方链接 按照官方文档&#xff0c;我们先用go get命令下载。 go get github.com/lxn/walk然后分别创建好了 main.go、main.manifest 文件&#xff0c;代码如下…

CV经典任务(一) 语义分割、实例分割 | 全卷积

文章目录 1 语义分割1.1 思路1 滑动窗口1.2 思路2 全卷积网络 2 代码实现3 实例分割 之前讲了分类 实际中除了分类还有几大视觉任务 语义分割&#xff0c;实例分割&#xff0c;目标检测 以上任务基本也都基于前面讲的卷积网络去做的 1 语义分割 语义分割&#xff08;Semant…

深度学习:模型训练过程中Trying to backward through the graph a second time解决方案

1 问题描述 在训练lstm网络过程中出现如下错误&#xff1a; Traceback (most recent call last):File "D:\code\lstm_emotion_analyse\text_analyse.py", line 82, in <module>loss.backward()File "C:\Users\lishu\anaconda3\envs\pt2\lib\site-packag…

常用的文本对比工具或网站

以下是一些常用的文本对比工具的下载地址或网站访问地址&#xff1a; DiffNow: https://www.diffnow.com/ WinMerge: https://winmerge.org/ Beyond Compare: https://www.scootersoftware.com/ Meld: https://meldmerge.org/ diff:文本对比/字符串差异比较 - 在线工具 请…

vite.config.ts

vite会自动生成vite.config.ts文件 https://juejin.cn/post/7039879176534360077https://juejin.cn/post/7039879176534360077 挑了几个常用的记下笔记&#xff0c;配置别名&#xff0c;proxy跨域&#xff0c;本地服务设置 import { defineConfig } from vite import vue fr…

Java环形链表(图文详解)

目录 一、判断链表中是否有环 &#xff08;1&#xff09;题目描述 &#xff08;2&#xff09;题解 二、环形链表的入环节点 &#xff08;1&#xff09;题目描述 &#xff08;2&#xff09;题解 一、判断链表中是否有环 &#xff08;1&#xff09;题目描述 给你一个链表的…

构建智能客服知识库,优化客户体验不是难题!

在当今快节奏的商业环境中&#xff0c;客户都希望得到及时个性化的支持&#xff0c;拥有一个智能客服知识库对于现代企业至关重要。智能客服知识库是一个集中存储、组织和访问与客户服务互动相关的信息的综合性知识库。它为企业提供了全面的知识来源&#xff0c;使他们能够为客…

想要精通算法和SQL的成长之路 - 最长递增子序列 II(线段树的运用)

想要精通算法和SQL的成长之路 - 最长递增子序列 II&#xff08;线段树的运用&#xff09; 前言一. 最长递增子序列 II1.1 向下递推1.2 向上递推1.3 更新操作1.4 查询操作1.5 完整代码&#xff1a; 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 最长递增子序列 II 原题链接…

单链表详细解析|画图理解

前言&#xff1a; 在前面我们学习了顺序表&#xff0c;相当于数据结构的凉菜&#xff0c;今天我们正式开始数据结构的硬菜了&#xff0c;那就是链表&#xff0c;链表有多种结构&#xff0c;但我们实际中最常用的还是无头单向非循环链表和带头双向循环链表&#xff0c;我们今天先…

idea没有maven工具栏解决方法

背景&#xff1a;接手的一些旧项目&#xff0c;有pom文件&#xff0c;但是用idea打开的时候&#xff0c;没有认为是maven文件&#xff0c;所以没有maven工具栏&#xff0c;不能进行重新加载pom文件中的依赖。 解决方法&#xff1a;选中pom.xml文件&#xff0c;右键 选择添加为…

Denoising diffusion implicit models 阅读笔记

Denoising diffusion probabilistic models (DDPMs)从马尔科夫链中采样生成样本&#xff0c;需要迭代多次&#xff0c;速度较慢。Denoising diffusion implicit models (DDIMs)的提出是为了加速采样过程&#xff0c;减少迭代的次数&#xff0c;并且要求DDIM可以复用DDPM训练的网…