<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Lishengxie</title><link>https://lishengxie.top/</link><description>Recent content on Lishengxie</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Sat, 17 Oct 2026 16:16:08 +0800</lastBuildDate><atom:link href="https://lishengxie.top/index.xml" rel="self" type="application/rss+xml"/><item><title>TinyLFU</title><link>https://lishengxie.top/post/tinylfu/</link><pubDate>Sat, 17 Oct 2026 16:16:08 +0800</pubDate><guid>https://lishengxie.top/post/tinylfu/</guid><description>&lt;h2 id="什么是缓存淘汰策略"&gt;什么是缓存淘汰策略&lt;/h2&gt;&#10;&lt;p&gt;我们知道，现代计算机采用多级存储结构。为了加速程序执行，通常会将数据从低速存储提前加载到访问速度更快的高速存储（缓存）中。&lt;/p&gt;&#10;&lt;p&gt;但是，由于实际数据量可能远超缓存容量，当有新数据需要进入缓存时，就需要按照一定的规则选择并替换旧数据，这就是所谓的缓存淘汰策略。&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;&lt;a href="https://zh.wikipedia.org/wiki/%E5%BF%AB%E5%8F%96%E6%96%87%E4%BB%B6%E7%BD%AE%E6%8F%9B%E6%A9%9F%E5%88%B6"&gt;维基百科&lt;/a&gt;：&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;缓存文件置换机制&lt;/strong&gt;（英语：Cache replacement policies）是计算机管理缓存存储器的一种机制。&lt;/p&gt;&#10;&lt;p&gt;由于缓存空间有限，无法容纳所有数据，因此当新数据需要进入缓存时，必须根据一定的规则选择合适的数据进行替换，这种规则就称为缓存置换机制。&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;常见的缓存淘汰策略包括：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;FIFO（First In First Out）：先进先出，优先淘汰最早进入缓存的数据，类似队列的思想；&lt;/li&gt;&#10;&lt;li&gt;LRU（Least Recently Used）：最近最少使用，优先淘汰距离上次访问时间最久的数据；&lt;/li&gt;&#10;&lt;li&gt;LFU（Least Frequently Used）：最不经常使用，优先淘汰访问频率最低的数据。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;缓存淘汰策略的一项重要评价指标是缓存命中率。我们希望在有限的缓存容量下，尽可能提高缓存命中率，从而减少对低速存储的访问，加速程序执行。&lt;/p&gt;&#10;&lt;h2 id="lru-和-lfu-的问题"&gt;LRU 和 LFU 的问题&lt;/h2&gt;&#10;&lt;p&gt;LRU 通常基于哈希表和双向链表实现，每次访问后将对应数据移动到链表头部，并从链表尾部淘汰数据。LRU 实现简单，在多数场景下也能取得不错的效果。&lt;/p&gt;&#10;&lt;p&gt;但是，LRU 存在缓存污染的问题。例如，当程序进行一次全量数据扫描时，大量只访问一次的数据可能将原有的热点数据挤出缓存，导致后续访问热点数据时，需要重新从下级存储加载。&lt;/p&gt;&#10;&lt;p&gt;LFU 通常可以基于哈希表和小顶堆实现。相比 LRU，LFU 更关注数据的访问频率，能够有效避免一次性扫描造成的缓存污染。&lt;/p&gt;&#10;&lt;p&gt;但是，LFU 需要额外维护缓存项的访问频率信息，带来一定的存储和更新开销。此外，由于历史访问频率不断累积，曾经的热点数据即使不再被访问，也可能长期占据缓存空间，难以及时淘汰。&lt;/p&gt;&#10;&lt;h2 id="tinylfu"&gt;TinyLFU&lt;/h2&gt;&#10;&lt;p&gt;TinyLFU [1] 是一种用于优化传统 LFU 问题的缓存准入策略（Cache Admission Policy）。与直接决定淘汰哪个数据不同，TinyLFU 在新数据进入缓存时，会比较候选数据（Candidate）和待淘汰数据（Victim）的访问频率，选择频率更高的数据保留在缓存中。&lt;/p&gt;&#10;&lt;center&gt;&lt;img src="https://lishengxie.top/uploads/2026/10/image-20261017180123071.png" alt="TinyLFU 缓存准入流程" style="zoom:50%;" /&gt;&lt;/center&gt;&#10;&lt;p&gt;首先，为了解决访问频率统计的存储开销问题，TinyLFU 使用了 Count-Min Sketch（CM-Sketch）。&lt;/p&gt;&#10;&lt;p&gt;CM-Sketch 是一种与布隆过滤器类似的概率数据结构，不同之处在于，其数组中的每个位置存储的是计数值。对于一个 Key，通过多个 Hash 函数映射到数组中的不同位置，并将对应计数器加一；查询时，取这些计数器中的最小值作为访问频率的估计值。&lt;/p&gt;&#10;&lt;p&gt;需要注意的是，由于存在 Hash 冲突，CM-Sketch 不支持直接删除某个 Key 的统计信息。&lt;/p&gt;</description></item><item><title>交叉熵Loss</title><link>https://lishengxie.top/post/softmax-cross-entropy/</link><pubDate>Mon, 07 Sep 2026 22:45:35 +0800</pubDate><guid>https://lishengxie.top/post/softmax-cross-entropy/</guid><description>&lt;blockquote&gt;&#10;&lt;p&gt;网课学习：https://haoailab.com/cse234-w25/&lt;/p&gt;&#10;&lt;p&gt;Week2 autodiff 章节问题推导&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;div class="katex-display"&gt;L=-\sum t_{i}\log(y_{i}),y_{i}=\text{softmax}\left(x\right)_{i}=\frac{e^{x_{i}}}{\sum e^{x_{d}}}&lt;/div&gt;&lt;h2 id="softmax-cross-entropy-loss--前向与梯度计算"&gt;Softmax Cross-Entropy Loss — 前向与梯度计算&lt;/h2&gt;&#10;&lt;h2 id="1-问题设定"&gt;1. 问题设定&lt;/h2&gt;&#10;&lt;p&gt;给定一个分类任务，共有 &lt;span class="katex-inline"&gt;C&lt;/span&gt; 个类别。对于一个样本，模型输出 logits 向量 &lt;span class="katex-inline"&gt;\mathbf{x} \in \mathbb{R}^{C}&lt;/span&gt;，真实标签为 &lt;span class="katex-inline"&gt;t \in \{0, 1, \dots, C-1\}&lt;/span&gt;（也可用 one-hot 向量 &lt;span class="katex-inline"&gt;\mathbf{t} \in \{0,1\}^{C}&lt;/span&gt; 表示）。&lt;/p&gt;&#10;&lt;h2 id="2-前向传播-forward-pass"&gt;2. 前向传播 (Forward Pass)&lt;/h2&gt;&#10;&lt;h3 id="21-softmax-激活"&gt;2.1 Softmax 激活&lt;/h3&gt;&#10;&lt;div class="katex-display"&gt;y_i = \text{softmax}(\mathbf{x})_i = \frac{e^{x_i}}{\sum_{d=1}^{C} e^{x_d}}, \quad i = 1, 2, \dots, C&lt;/div&gt;&lt;p&gt;其中 &lt;span class="katex-inline"&gt;y_i&lt;/span&gt; 表示模型对第 &lt;span class="katex-inline"&gt;i&lt;/span&gt; 类的预测概率，满足 &lt;span class="katex-inline"&gt;\sum_i y_i = 1&lt;/span&gt; 且 &lt;span class="katex-inline"&gt;y_i &gt; 0&lt;/span&gt;。&lt;/p&gt;&#10;&lt;h3 id="22-交叉熵损失-cross-entropy-loss"&gt;2.2 交叉熵损失 (Cross-Entropy Loss)&lt;/h3&gt;&#10;&lt;p&gt;对于单个样本（真实标签为类别 &lt;span class="katex-inline"&gt;t&lt;/span&gt;）：&lt;/p&gt;&#10;&lt;div class="katex-display"&gt;L = - \sum_{i=1}^{C} t_i \log(y_i) = -\log(y_t)&lt;/div&gt;&lt;p&gt;由于 &lt;span class="katex-inline"&gt;t_i&lt;/span&gt; 是 one-hot 向量（只有 &lt;span class="katex-inline"&gt;t_t = 1&lt;/span&gt;，其余为 &lt;span class="katex-inline"&gt;0&lt;/span&gt;），因此损失简化为仅对真实类别 &lt;span class="katex-inline"&gt;t&lt;/span&gt; 的负对数似然：&lt;/p&gt;</description></item><item><title>分布式ID生成方案全解析：从数据库到雪花算法</title><link>https://lishengxie.top/post/distributed-id-generator-algo/</link><pubDate>Thu, 25 Jun 2026 22:53:20 +0800</pubDate><guid>https://lishengxie.top/post/distributed-id-generator-algo/</guid><description>&lt;p&gt;在分布式系统中，全局唯一ID是一个常见的需求。无论是分库分表后的主键冲突，还是订单号、用户ID等需要唯一标识的场景，都离不开一个可靠的分布式ID生成器。本文将带你了解分布式ID的基本要求，并梳理多种实现方案，从简单的数据库自增到高性能的雪花算法，最后介绍各大厂的开源组件。&lt;/p&gt;&#10;&lt;h2 id="一什么是分布式id"&gt;一、什么是分布式ID？&lt;/h2&gt;&#10;&lt;p&gt;分布式ID是指在分布式环境下生成的全局唯一标识符。典型应用场景包括：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;分库分表&lt;/strong&gt;：数据量增长导致单库单表出现性能瓶颈时，分库分表后无法继续依赖数据库自增ID（会产生主键冲突），此时需要分布式ID保证全局唯一。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;业务标识&lt;/strong&gt;：订单号、用户ID、消息ID等需要全局唯一的场景。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="二分布式id的基本要求"&gt;二、分布式ID的基本要求&lt;/h2&gt;&#10;&lt;p&gt;一个合格的分布式ID生成器通常需要满足以下几点：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;全局唯一&lt;/strong&gt;：这是最基本的要求，ID必须在整个分布式系统中不重复。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;独立部署、高性能、高可用&lt;/strong&gt;：ID生成服务应独立部署，具备高并发下的低延迟响应能力（接近100%可用性），不能成为业务系统的瓶颈。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;安全&lt;/strong&gt;：ID中不应包含敏感信息，避免信息泄露。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;趋势递增&lt;/strong&gt;：尽可能保证ID趋势递增，这有利于数据库的索引插入和排序性能。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="三实现方案"&gt;三、实现方案&lt;/h2&gt;&#10;&lt;img src="https://lishengxie.top/uploads/2026/05/distribute-id.png" alt="分布式ID方案" style="zoom:50%;" /&gt;&#10;&lt;h3 id="1-数据库方案"&gt;1. 数据库方案&lt;/h3&gt;&#10;&lt;h4 id="11-基于数据库自增id"&gt;1.1 基于数据库自增ID&lt;/h4&gt;&#10;&lt;p&gt;使用MySQL的自增主键来充当分布式ID。创建一张专门用于生成ID的表，每次插入一条记录后获取返回的主键ID。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;DATABASE&lt;/span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;SEQ_ID&lt;span style="color:#f92672"&gt;`&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLE&lt;/span&gt; SEQID.SEQUENCE_ID (&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; id bigint(&lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;) unsigned &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt; auto_increment, &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; value char(&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;KEY&lt;/span&gt; (id)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;) ENGINE&lt;span style="color:#f92672"&gt;=&lt;/span&gt;MyISAM;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;INSERT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;INTO&lt;/span&gt; SEQUENCE_ID(value) &lt;span style="color:#66d9ef"&gt;VALUES&lt;/span&gt; (&lt;span style="color:#e6db74"&gt;&amp;#39;values&amp;#39;&lt;/span&gt;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：简单、天然有序。&#10;&lt;strong&gt;缺点&lt;/strong&gt;：单点故障风险、并发性能差、数据库写入压力大，且ID可反推出订单数量等敏感信息。&lt;/p&gt;&#10;&lt;h4 id="12-基于数据库集群模式"&gt;1.2 基于数据库集群模式&lt;/h4&gt;&#10;&lt;p&gt;为解决单点故障，可以采用多主模式，部署多个MySQL实例独立生成自增ID。通过设置不同的起始值和步长避免重复（以两个节点为例）：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- MySQL实例1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;set&lt;/span&gt; &lt;span style="color:#f92672"&gt;@@&lt;/span&gt;auto_increment_offset &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;; &lt;span style="color:#75715e"&gt;-- 起始值&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;set&lt;/span&gt; &lt;span style="color:#f92672"&gt;@@&lt;/span&gt;auto_increment_increment &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;; &lt;span style="color:#75715e"&gt;-- 步长&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- MySQL实例2&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;set&lt;/span&gt; &lt;span style="color:#f92672"&gt;@@&lt;/span&gt;auto_increment_offset &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;; &lt;span style="color:#75715e"&gt;-- 起始值&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;set&lt;/span&gt; &lt;span style="color:#f92672"&gt;@@&lt;/span&gt;auto_increment_increment &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;; &lt;span style="color:#75715e"&gt;-- 步长&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：缓解单点并发压力。&#10;&lt;strong&gt;缺点&lt;/strong&gt;：不利于动态扩容，新增节点时需处理起始值冲突，甚至可能停机调整。&lt;/p&gt;&#10;&lt;h4 id="13-基于数据库号段模式"&gt;1.3 基于数据库号段模式&lt;/h4&gt;&#10;&lt;p&gt;号段模式的核心思想是批量获取自增ID：每次从数据库取出一个ID范围（如(1,1000]），然后在内存中递增分配，用完后再去数据库获取新的号段。&lt;/p&gt;</description></item><item><title>Let's Encrypt 免费申请 SSL 证书，并实现自动续期</title><link>https://lishengxie.top/post/lets-encrypt-ssl/</link><pubDate>Sun, 14 Sep 2025 21:58:04 +0800</pubDate><guid>https://lishengxie.top/post/lets-encrypt-ssl/</guid><description>&lt;h2 id="背景"&gt;背景&lt;/h2&gt;&#10;&lt;p&gt;对于公网可以访问的网站，使用 HTTPS 协议是保证安全访问的基础要求，而 SSL 证书又是 HTTPS 协议不可或缺的一环。SSL 证书需要 CA 机构颁发，当前使用了阿里云的个人测试证书（免费证书），申请后上传到服务器并更新 nginx 配置。&lt;/p&gt;&#10;&lt;p&gt;当前存在的问题是，阿里云的免费 SSL 证书每三个月过期一次，需要手动重新申请并部署到服务器上，流程比较复杂。在网上看到可以使用 Let&amp;rsquo;s Encrypt 免费申请 SSL 证书，并实现自动续期，于是做了尝试，这里记录下相关流程。&lt;/p&gt;&#10;&lt;h2 id="环境准备"&gt;环境准备&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;一台可以访问公网的服务器，我使用的是 Linux/Ubuntu。&lt;/li&gt;&#10;&lt;li&gt;root 权限或者 sudo 权限。&lt;/li&gt;&#10;&lt;li&gt;存在 DNS 解析的域名。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="lets-encrypt-证书颁发"&gt;Let&amp;rsquo;s Encrypt 证书颁发&lt;/h2&gt;&#10;&lt;p&gt;Let’s Encrypt 是一个免费的、自动化的、开放的证书颁发机构（CA），提供免费 SSL 证书。它的目标是让所有网站都能轻松实现 HTTPS 加密，保障用户数据的安全。通过 Let’s Encrypt 可以为网站的主域名、子域名，甚至泛域名配置安全证书，而且过程完全自动化，不需要手动申请和管理证书，官方推荐使用 &lt;a href="https://certbot.eff.org/"&gt;Certbot&lt;/a&gt;。&lt;/p&gt;&#10;&lt;h3 id="certbot-安装"&gt;Certbot 安装&lt;/h3&gt;&#10;&lt;p&gt;Linux 平台上可以使用 snap 或 pip 安装 Certbot，这里使用 Python + pip 的方式，参考&lt;a href="https://certbot.eff.org/instructions?ws=nginx&amp;amp;os=pip"&gt;安装流程&lt;/a&gt;。&lt;/p&gt;&#10;&lt;p&gt;1、首先安装 Python 环境。&lt;/p&gt;</description></item><item><title>Redis ziplist、quicklist 和 listpack</title><link>https://lishengxie.top/post/redis-listpack-ziplist/</link><pubDate>Mon, 03 Mar 2025 22:44:38 +0800</pubDate><guid>https://lishengxie.top/post/redis-listpack-ziplist/</guid><description>&lt;h2 id="ziplist"&gt;ziplist&lt;/h2&gt;&#10;&lt;h3 id="为什么需要-ziplist"&gt;为什么需要 ziplist？&lt;/h3&gt;&#10;&lt;p&gt;由于 Redis 是一个内存型数据库，因此在使用相应的数据结构时需要1）节省内存空间，2）提高操作效率。传统的包含指向相邻节点指针的双向链表中在内存使用和操作效率上存在一些问题：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;存储指针需要额外的内存空间，且该空间在指定硬件平台上是固定的。当存储的数据长度较小时，指针占用空间甚至会超过数据占用空间。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;传统双向链表中相邻节点在内存中并不连续，这虽然利用了碎片化的内存空间，但是由于增加了一次额外的指针索引，遍历效率低。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;ziplist 是 Redis 中设计的一种内存紧凑型的数据结构，可以用来代替传统的双向链表结构。ziplist 使用一块连续的内存空间，通过在每个节点中存储当前及前一个节点的长度来实现双向遍历，节省内存空间，操作效率高。&lt;/p&gt;&#10;&lt;h3 id="ziplist-是什么"&gt;ziplist 是什么？&lt;/h3&gt;&#10;&lt;p&gt;下面给出了压缩列表的结构示意图，包括 10byte 的表头元数据，若干个列表节点以及最后的 1byte 的结束标识符。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt; zlbytes &lt;span style="color:#f92672"&gt;|&lt;/span&gt; zltail &lt;span style="color:#f92672"&gt;|&lt;/span&gt; zllen &lt;span style="color:#f92672"&gt;|&lt;/span&gt; entry1 &lt;span style="color:#f92672"&gt;|&lt;/span&gt; entry2 &lt;span style="color:#f92672"&gt;|&lt;/span&gt; ... &lt;span style="color:#f92672"&gt;|&lt;/span&gt; entryN &lt;span style="color:#f92672"&gt;|&lt;/span&gt; zlend &lt;span style="color:#f92672"&gt;|&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 各部分说明&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;zlbytes: &lt;span style="color:#960050;background-color:#1e0010"&gt;整个压缩列表占用的字节数，&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;uint32_t&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;byte)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;zltail: &lt;span style="color:#960050;background-color:#1e0010"&gt;压缩列表表尾节点距离压缩列表的起始地址有多少字节，&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;uint32_t&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;byte)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;zllen: &lt;span style="color:#960050;background-color:#1e0010"&gt;压缩列表包含的节点数，&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;uint16_t&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;byte)&lt;span style="color:#960050;background-color:#1e0010"&gt;，当该属性值为&lt;/span&gt; UINT16_MAX &lt;span style="color:#960050;background-color:#1e0010"&gt;时，真实节点数量需要遍历整个压缩列表才能得到&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;entry: &lt;span style="color:#960050;background-color:#1e0010"&gt;压缩列表节点&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;zlend: &lt;span style="color:#960050;background-color:#1e0010"&gt;用于标记压缩列表末端的特殊值&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;0xFF&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;byte&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;每个压缩列表的节点中存储的内容可以看作一个字节数组或者整数值，每个节点包含以下三部分内容：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt; previous_entry_length &lt;span style="color:#f92672"&gt;|&lt;/span&gt; encoding &lt;span style="color:#f92672"&gt;|&lt;/span&gt; content &lt;span style="color:#f92672"&gt;|&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 各部分说明&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;previous_entry_length: &lt;span style="color:#960050;background-color:#1e0010"&gt;记录前一个节点的长度，长度为&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;byte &lt;span style="color:#960050;background-color:#1e0010"&gt;或&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;byte&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;前一个节点长度小于&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;254&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;字节时，&lt;/span&gt;previous_entry_length &lt;span style="color:#960050;background-color:#1e0010"&gt;长度为&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;字节，记录前一个节点的长度&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;前一个节点长度大于等于&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;254&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;字节时，&lt;/span&gt;previous_entry_length &lt;span style="color:#960050;background-color:#1e0010"&gt;长度为&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;字节，其中第一个字节设置为&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0xFE&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;，后面的四个字节用于记录前一个节点长度&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;encoding: &lt;span style="color:#960050;background-color:#1e0010"&gt;记录节点的&lt;/span&gt; content &lt;span style="color:#960050;background-color:#1e0010"&gt;中所保存数据的类型和长度&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;一字节&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;00&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;开头&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;、两字节&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;01&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;开头&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;或五字节&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;开头&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;的表示字节数组编码，去除最高两位之后的其他位是字节数组长度&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;一字节长&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;11&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;开头&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;的表示整数编码，去除最高两位后的其他位可以用于标识整数的类型和位宽&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;content: &lt;span style="color:#960050;background-color:#1e0010"&gt;节点值，可以是一个字节数组或者整数值，由&lt;/span&gt; encoding &lt;span style="color:#960050;background-color:#1e0010"&gt;属性决定&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="ziplist-有什么问题"&gt;ziplist 有什么问题？&lt;/h3&gt;&#10;&lt;p&gt;前面提到 ziplist 通过使用连续的内存块和精心设计的编码格式来保存列表数据，并实现双向检索的功能。但是，使用 ziplist 仍然存在一些缺点：&lt;/p&gt;</description></item><item><title>Nginx禁止使用IP直接访问服务器上相应端口</title><link>https://lishengxie.top/post/nginx-prohibit-ip-request/</link><pubDate>Sat, 11 May 2024 21:48:52 +0800</pubDate><guid>https://lishengxie.top/post/nginx-prohibit-ip-request/</guid><description>&lt;h2 id="起因"&gt;起因&lt;/h2&gt;&#10;&lt;p&gt;我的服务器中部署了一个typecho博客和两个使用docker容器的服务，其中docker容器使用端口映射，将容器中的端口映射到宿主机上的端口实现访问。&lt;/p&gt;&#10;&lt;p&gt;一次偶然机会发现服务器上的服务可以通过IP+端口的方式直接访问，如果有未备案的域名解析到我们服务器的IP，可能会导致云服务器厂商关停我们的服务造成一些问题。因此，我们需要禁止通过IP+端口直接访问服务。&lt;/p&gt;&#10;&lt;h2 id="nginx-配置"&gt;Nginx 配置&lt;/h2&gt;&#10;&lt;p&gt;这里的三个服务通过nginx进行转发，对不同&lt;code&gt;server_name&lt;/code&gt;的请求会直接转发到对应的服务进程。因此，这里有限考虑使用nginx配置来禁止IP+端口的访问。服务器上主要开放了两个端口，80和443，分别用于HTTP和HTTPS请求，在实际进行相应配置时二者也有所不同。&lt;/p&gt;&#10;&lt;h3 id="80-端口"&gt;80 端口&lt;/h3&gt;&#10;&lt;p&gt;对于80端口，我们在&lt;code&gt;nginx.conf&lt;/code&gt;中添加如下配置。具体原理在于，当根据listen无法得到最佳匹配时，nginx会使用请求中的Host值匹配server_name，匹配顺序可以参考这篇&lt;a href="https://zhuanlan.zhihu.com/p/109509478"&gt;博客&lt;/a&gt;。IP+端口进行请求时匹配到下面的server配置，直接返回403错误信息。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;server&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;listen&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;80&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;default_server;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;server_name&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;_;&lt;/span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;return&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;403;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="443端口"&gt;443端口&lt;/h3&gt;&#10;&lt;p&gt;由于使用了HTTPS协议，因此还需要禁止通过IP+443端口的访问方式。具体参考了下面的博客：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://www.huixiangdou.cn/archives/nginx-jin-zhi-80-443-duan-kou"&gt;https://www.huixiangdou.cn/archives/nginx-jin-zhi-80-443-duan-kou&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;具体来说，Nginx 上对于 SSL 服务器在不配置证书的时候会出现协议错误，哪怕端口上配置了其他网站也会报错。因此，我们需要随便生成一个证书进行配置，生成 SSL 证书可以使用这个网站&lt;a href="https://myssl.com/create_test_cert.html"&gt;https://myssl.com/create_test_cert.html&lt;/a&gt;。在&lt;code&gt;nginx.conf&lt;/code&gt;中添加如下配置：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;server&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;listen&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;80&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;default;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;listen&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;443&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;default_server;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;#SSL-START&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;SSL相关配置，请勿删除或修改下一行带注释的404规则&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;#error_page&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;404/404.html;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;ssl_certificate&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;/path/to/cert.pem;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;ssl_certificate_key&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;/path/to/private.key;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;ssl_protocols&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;TLSv1&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;TLSv1.1&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;TLSv1.2;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;ssl_ciphers&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;ssl_prefer_server_ciphers&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;on;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;ssl_session_cache&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;shared:SSL:10m;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;ssl_session_timeout&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;10m;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;error_page&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;497&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;https:&lt;/span&gt;&lt;span style="color:#75715e"&gt;//$host$request_uri;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;#SSL-END&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;server_name&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;_;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;return&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;403;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;配置完成后重载 Nginx 配置。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ nginx -t&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ nginx -s reload&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="docker容器问题"&gt;Docker容器问题&lt;/h2&gt;&#10;&lt;p&gt;Docker容器通过端口映射实现服务的对外可用性，这里是通过&lt;code&gt;-p host_port:container_port&lt;/code&gt;实现容器上的端口到宿主机上端口的映射。具体来说，以容器的80端口映射到宿主机的8080端口为例，docker容器运行时使用了&lt;code&gt;-p 8080:80&lt;/code&gt;，Nginx中监听了80端口，并在对应域名访问时将请求转发到服务器的8080端口。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-nginx" data-lang="nginx"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;location&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;proxy_pass&lt;/span&gt; &lt;span style="color:#e6db74"&gt;http://host_ip:8080&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;但是，在根据上面的配置禁止了直接使用IP+80/443端口访问的方式后，发现&lt;code&gt;host_ip:8080&lt;/code&gt;仍然能够访问到docker容器中的服务。查询相关资料修改了iptables路由表和sfw防火墙规则后，仍然无法解决问题。防火墙上没有打开端口，但仍然可以访问。最后通过查找资料发现是docker自身的原因，下面是docker官方的介绍：&lt;/p&gt;</description></item><item><title>LeetCode刷题 - KMP算法</title><link>https://lishengxie.top/post/leetcode-kmp/</link><pubDate>Sun, 04 Feb 2024 18:48:10 +0800</pubDate><guid>https://lishengxie.top/post/leetcode-kmp/</guid><description>&lt;p&gt;KMP算法是一种高效的字符串匹配算法，但是之前每次学过之后都会忘记，这次做一下总结加深印象，主要参考了以下链接。&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://programmercarl.com/0028.%E5%AE%9E%E7%8E%B0strStr.html"&gt;https://programmercarl.com/0028.%E5%AE%9E%E7%8E%B0strStr.html&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="问题"&gt;问题&lt;/h2&gt;&#10;&lt;p&gt;给定一个字符串&lt;span class="katex-inline"&gt;s&lt;/span&gt;(长度为N)和一个模式串&lt;span class="katex-inline"&gt;t&lt;/span&gt;(长度为M)，如果&lt;span class="katex-inline"&gt;s&lt;/span&gt;中存在&lt;span class="katex-inline"&gt;t&lt;/span&gt;，那么返回模式串第一次出现的起始索引；如果不存在返回-1。对应&lt;a href="https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/description/"&gt;Leetcode 28. 找出字符串中第一个匹配项的下标&lt;/a&gt;&lt;/p&gt;&#10;&lt;h2 id="kmp算法"&gt;KMP算法&lt;/h2&gt;&#10;&lt;p&gt;KMP算法是由D.E.Knuth，J.H.Morris和V.R.Pratt同时发现的一种快速的字符串匹配算法，时间复杂度为&lt;span class="katex-inline"&gt;O(M+N)&lt;/span&gt;。KMP算法的核心思想是&lt;strong&gt;在字符串匹配失败时利用之前已经匹配的信息来做快速回退，避免从头再做匹配&lt;/strong&gt;。KMP算法的核心函数是一个用于求解&lt;code&gt;next&lt;/code&gt;数组的函数，&lt;code&gt;next&lt;/code&gt;数组包含了模式串局部匹配的信息。&lt;/p&gt;&#10;&lt;p&gt;这里代码随想录中给出了关于&lt;code&gt;next&lt;/code&gt;数组的详细解释。&lt;code&gt;next&lt;/code&gt;数组对应自定义的前缀表，其中前缀表是一个和模式串长度相同的数组，前缀表第i个位置的值为[0,i]子字符串的最长相同前后缀的长度；&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;前缀是指不包含最后一个字符的所有以第一个字符开头的连续子串。后缀是指不包含第一个字符的所有以最后一个字符结尾的连续子串；&lt;/li&gt;&#10;&lt;li&gt;举例来说，“aab”的前缀有“a”和“aa”、后缀有“b”和“ab”，“aabaa”的最长相同前后缀长度为2，“aa”的最长相同前后缀长度为1。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;以下图为例，假设文本串和模式串分别为&lt;code&gt;aabaabaafa&lt;/code&gt;和&lt;code&gt;aabaaf&lt;/code&gt;，前缀表如图中所示。那么在&lt;code&gt;b&lt;/code&gt;和&lt;code&gt;f&lt;/code&gt;不匹配时，此时寻找前缀表中前一位存储的值，查找得到值为2，该值的含义是“aabaa”的最长相同前后缀长度为2，即“aa”。此时我们可以不用从头开始重新匹配，文本串中的匹配指针可以不移动，将模式串中的匹配指针回退到索引2处重新开始匹配即可。&#10;&lt;img src="https://lishengxie.top/uploads/2024/02/prefix-table.png" alt="prefix table" style="zoom:30%;"/&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;这里为什么可以不回退文本串的匹配指针？&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;因为这里通过回退j指针，找到了从文本串中该位置向前的最长相同前后缀，获得了类似下图的效果。&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;img src="https://lishengxie.top/uploads/2024/02/prefix-table1.png" alt="prefix table" style="zoom:30%;"/&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;实际使用中常通过将前缀表统一减1得到next数组，那么如何计算next数组？&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;next数组的计算类似于移动模式串，在模式串和模式串之间做匹配，在移动的过程中计算next数组的值，next数组的计算代码如下所示：&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getNext&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt; next, &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; string&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt; s){&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; j &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; next[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; j;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; s.size(); i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) { &lt;span style="color:#75715e"&gt;// 注意i从1开始&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (j &lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; s[i] &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; s[j &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;]) { &lt;span style="color:#75715e"&gt;// 前后缀不相同了&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; j &lt;span style="color:#f92672"&gt;=&lt;/span&gt; next[j]; &lt;span style="color:#75715e"&gt;// 向前回退&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (s[i] &lt;span style="color:#f92672"&gt;==&lt;/span&gt; s[j &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;]) { &lt;span style="color:#75715e"&gt;// 找到相同的前后缀&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; j&lt;span style="color:#f92672"&gt;++&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; next[i] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; j; &lt;span style="color:#75715e"&gt;// 将j（前缀的长度）赋给next[i]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&#10;&lt;li&gt;基于next数组进行文本串和模式串的匹配代码如下：&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;match&lt;/span&gt;(string s, string t) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; j &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; next[t.size()];&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; getNext(next, t);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; s.size(); i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (j &lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; s[i] &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; t[j&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;]) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; j &lt;span style="color:#f92672"&gt;=&lt;/span&gt; next[j];&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (s[i] &lt;span style="color:#f92672"&gt;==&lt;/span&gt; s[j&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;]) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; j&lt;span style="color:#f92672"&gt;++&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (j &lt;span style="color:#f92672"&gt;==&lt;/span&gt; (t.size() &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; i &lt;span style="color:#f92672"&gt;-&lt;/span&gt; t.size() &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Transfer Server</title><link>https://lishengxie.top/post/transfer-server/</link><pubDate>Sat, 23 Dec 2023 23:17:56 +0800</pubDate><guid>https://lishengxie.top/post/transfer-server/</guid><description>&lt;h2 id="站点迁移"&gt;站点迁移&lt;/h2&gt;&#10;&lt;p&gt;之前使用的是云服务器是腾讯与的2核4G服务器，但是由于最开始购买时只买了一年，续费时价格太贵，因此转到阿里云，可以有四年每年99元的2核2G服务器可以白嫖~&lt;/p&gt;&#10;&lt;p&gt;迁移过程大概分为两步：站点数据迁移和站点备案迁移&lt;/p&gt;&#10;&lt;h3 id="数据迁移"&gt;数据迁移&lt;/h3&gt;&#10;&lt;h4 id="博客迁移wordpress-typecho"&gt;博客迁移wordpress-&amp;gt;typecho&lt;/h4&gt;&#10;&lt;p&gt;原来的博客使用wordpress框架，但是wordpress框架功能齐全、有些臃肿，因此这里换成了更精简的typecho框架。&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;typecho安装&#10;参考了知乎博客&lt;a href="https://zhuanlan.zhihu.com/p/34211709"&gt;https://zhuanlan.zhihu.com/p/34211709&lt;/a&gt;；&lt;/li&gt;&#10;&lt;li&gt;导出wordpress数据库并在新服务器中导入&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;mysql导入导出命令参考: &lt;a href="https://www.runoob.com/w3cnote/linux-mysql-import-export-data.html"&gt;https://www.runoob.com/w3cnote/linux-mysql-import-export-data.html&lt;/a&gt;；&lt;/li&gt;&#10;&lt;li&gt;先将原服务器上的wordpress数据库导出为*.sql文件，再导入到新服务器中；&lt;/li&gt;&#10;&lt;li&gt;这一步是为了方便下一步转换到typecho，因为这样可以直接访问本地数据库。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;ol start="3"&gt;&#10;&lt;li&gt;数据迁移到typecho&#10;基于typecho插件：&lt;a href="https://docs.typecho.org/plugins/wordpress-to-typecho"&gt;https://docs.typecho.org/plugins/wordpress-to-typecho&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;还原wordpress中的图片附件到typecho中&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;将WordPress的wp-content/uploads目录下的附件全部移动到Typecho的usr/uploads目录下，保持目录结构不变。&lt;/li&gt;&#10;&lt;li&gt;在mysql typecho对应数据库中执行以下代码以完成图片路径的替换：&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt; update typecho_contents set text=replace(text,&amp;#39;wp-content/uploads&amp;#39;,&amp;#39;usr/uploads&amp;#39;)&#10; update typecho_contents set text=replace(text,&amp;#39;wordpree站点url&amp;#39;,&amp;#39;typecho站点url&amp;#39;)&#10;&lt;/code&gt;&lt;/pre&gt;&lt;ol start="5"&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;typecho使用数学公式&#10;使用插件：&lt;a href="https://github.com/yuzhongzhibi/typecho_mathjax_plugin"&gt;https://github.com/yuzhongzhibi/typecho_mathjax_plugin&lt;/a&gt;&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;typecho主题页面更改&#10;参考链接：&lt;a href="https://www.skyqian.com/archives/typecho-pages.html"&gt;https://www.skyqian.com/archives/typecho-pages.html&lt;/a&gt;&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h4 id="docker容器迁移"&gt;docker容器迁移&lt;/h4&gt;&#10;&lt;p&gt;做法是现在新服务器上安装docker，然后迁移旧服务器上的docker挂载文件夹到新服务器相同位置，最后在新服务器启动容器。参考链接：&lt;a href="https://zhuanlan.zhihu.com/p/643367054"&gt;https://zhuanlan.zhihu.com/p/643367054&lt;/a&gt;&#10;这里我主要使用了两个容器用于存储电子书和笔记&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Talebook：&lt;a href="https://github.com/talebook/talebook"&gt;https://github.com/talebook/talebook&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;leanote: &lt;a href="https://www.bilibili.com/read/cv23693842/"&gt;https://www.bilibili.com/read/cv23693842/&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h3 id="站点备案迁移"&gt;站点备案迁移&lt;/h3&gt;&#10;&lt;p&gt;为了方便使用，计划将域名和服务器都转移到阿里云。因为服务器需要在所在服务商处备案，因此还需要再阿里云备案，主要参考了这篇博客：&lt;a href="https://www.zuozuovera.com/posts/1644/"&gt;https://www.zuozuovera.com/posts/1644/&lt;/a&gt;。&lt;/p&gt;</description></item><item><title>算法学习-差分数组</title><link>https://lishengxie.top/post/differential-array/</link><pubDate>Sat, 23 Dec 2023 23:05:16 +0800</pubDate><guid>https://lishengxie.top/post/differential-array/</guid><description>&lt;h2 id="差分数组"&gt;差分数组&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;参考教程：&lt;a href="https://wansuanfa.com/index.php/589"&gt;https://wansuanfa.com/index.php/589&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;leetcode题目：&lt;a href="https://leetcode.cn/problems/corporate-flight-bookings/"&gt;1109. 航班预订统计&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="问题描述"&gt;问题描述&lt;/h2&gt;&#10;&lt;p&gt;给定一个数组，需要频繁地对某个区间内的元素做加减操作，并获取最后的操作结果。常规做法是每次都遍历整个区间然后修改区间内的元素，但是元素的访问需要时间、频繁访问元素会减慢程序的运行时间。因此，可以使用差分数组来进行优化。&lt;/p&gt;&#10;&lt;h2 id="一维差分数组定义"&gt;一维差分数组定义&lt;/h2&gt;&#10;&lt;p&gt;一维差分数组&lt;span class="katex-inline"&gt; d[n] &lt;/span&gt;定义为原始数组&lt;span class="katex-inline"&gt; nums &lt;/span&gt;相邻元素之间的差，即&lt;span class="katex-inline"&gt;d[i]=nums[i]-nums[i-1]&lt;/span&gt;，其中&lt;span class="katex-inline"&gt;d[0]=nums[0]&lt;/span&gt;。这样原数组就是差分数组的前缀和&#10;&lt;/p&gt;&#10;&lt;div class="katex-display"&gt;&#10;nums[i] = \sum_{k=0}^i d[k].&#10;&lt;/div&gt;&lt;p&gt;由此，我们可以改进原来的区间操作，如对区间&lt;span class="katex-inline"&gt;[a,b]&lt;/span&gt;内每个元素加3，那么只需要在区间的两端进行操作即可，即&#10;&lt;/p&gt;&#10;&lt;div class="katex-display"&gt;&#10;d[a] += 3, d[b+1] -= 3&#10;&lt;/div&gt;&lt;h3 id="证明"&gt;证明&lt;/h3&gt;&#10;&lt;p&gt;假设&lt;span class="katex-inline"&gt;nums1&lt;/span&gt;是修改后的数组，&lt;span class="katex-inline"&gt;d1&lt;/span&gt;是修改后的差分数组，其中&lt;span class="katex-inline"&gt;d1[a]=d[a]+3, d1[b+1]=d[b+1]-3&lt;/span&gt;.&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;hugo里面换行公式需要&lt;code&gt;\\\\&lt;/code&gt;四个反斜杠&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;对于&lt;span class="katex-inline"&gt;0\leq i \lt a&lt;/span&gt;, &lt;span class="katex-inline"&gt;nums1[i] = \sum_{k=0}^i d1[k] = \sum_{k=0}^i d[k] = nums[i]&lt;/span&gt;.&lt;/li&gt;&#10;&lt;li&gt;对于&lt;span class="katex-inline"&gt;a\leq i \leq b&lt;/span&gt;,&#10;&#10;&lt;div class="katex-display"&gt;&#10;\begin{aligned}&#10;nums1[i] &amp; = \sum_{k=0}^i d1[k] \\\\ &#10;&amp; = \sum_{k=0}^{a-1}d[k] + \sum_{k=a+1}^{b}d[k] + d[a] + 3 \\\\ &#10;&amp; = \sum_{k=0}^i d[k] + 3 \\\\ &#10;&amp; = nums[i]+3&#10;\end{aligned}&#10;&lt;/div&gt;&lt;/li&gt;&#10;&lt;li&gt;对于&lt;span class="katex-inline"&gt;i \gt b&lt;/span&gt;,&#10;&#10;&lt;div class="katex-display"&gt;&#10;\begin{align}&#10;nums1[i] &amp;= \sum_{k=0}^i d1[k]\\\\ &#10;&amp;= \sum_{k=0}^{a-1}d[k] + \sum_{k=a+1}^{b}d[k] + \sum_{k=b+1}^{i}d[k] + d[a] + 3 + d[b] - 3\\\\ &amp;= \sum_{k=0}^i d[k] + 3 - 3\\\\ &#10;&amp;= nums[i].&#10;\end{align}&#10;&lt;/div&gt;&#10;由此，可以证明只修改差分数组的两端即可以修改原数组的整个区间。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="代码"&gt;代码&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C++" data-lang="C++"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Solution&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; vector&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; diff;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; vector&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; nums;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;diffNums&lt;/span&gt;() {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; diff[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; nums[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;];&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; nums.size(); &lt;span style="color:#f92672"&gt;++&lt;/span&gt;i) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; diff[i] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; nums[i] &lt;span style="color:#f92672"&gt;-&lt;/span&gt; nums[i&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;];&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;increment&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; a, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; b, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; val) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; diff[a] &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; val;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (b &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; diff.size())&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; diff[b &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;] &lt;span style="color:#f92672"&gt;-=&lt;/span&gt; val;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;() {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; nums[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; diff[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;];&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; diff.size(); i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; nums[i] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; diff[i] &lt;span style="color:#f92672"&gt;+&lt;/span&gt; nums[i &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;];&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; vector&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; corpFlightBookings(vector&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;vector&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&amp;amp;&lt;/span&gt; bookings, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; n) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; nums.resize(n, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; diff.resize(n, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; diffNums();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; bookings.size(); &lt;span style="color:#f92672"&gt;++&lt;/span&gt;i) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; increment(bookings[i][&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;]&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, bookings[i][&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;]&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, bookings[i][&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;]);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; result();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; nums;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="拓展---二维差分数组"&gt;拓展 - 二维差分数组&lt;/h2&gt;&#10;&lt;p&gt;二维差分数组可以在一维差分数组的基础上进行拓展，视为一个平面，定义如下&#10;&lt;/p&gt;</description></item><item><title>LeetCode刷题-二叉树遍历迭代法</title><link>https://lishengxie.top/post/traverse-binary-tree/</link><pubDate>Tue, 17 Oct 2023 20:15:23 +0800</pubDate><guid>https://lishengxie.top/post/traverse-binary-tree/</guid><description>&lt;h2 id="leetcode题目链接"&gt;LeetCode题目链接&lt;/h2&gt;&#10;&lt;p&gt;二叉树的前序遍历：&lt;a href="https://leetcode.cn/problems/binary-tree-preorder-traversal/"&gt;https://leetcode.cn/problems/binary-tree-preorder-traversal/&lt;/a&gt;&#10;二叉树的中序遍历：&lt;a href="https://leetcode.cn/problems/binary-tree-inorder-traversal/"&gt;https://leetcode.cn/problems/binary-tree-inorder-traversal/&lt;/a&gt;&#10;二叉树的后序遍历：&lt;a href="https://leetcode.cn/problems/binary-tree-postorder-traversal/"&gt;https://leetcode.cn/problems/binary-tree-postorder-traversal/&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;二叉树的遍历方法有两种，分别是递归法和迭代法；实际使用中由于系统调用栈有限制，使用递归法可能会导致栈溢出，这里记录三种遍历的迭代做法。最后，介绍二叉树层序遍历的两种方法。&lt;/p&gt;&#10;&lt;p&gt;迭代遍历法借助辅助栈实现，下面是二叉树节点的定义，使用链表实现。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;TreeNode&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; val;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TreeNode &lt;span style="color:#f92672"&gt;*&lt;/span&gt;left;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TreeNode &lt;span style="color:#f92672"&gt;*&lt;/span&gt;right;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TreeNode() &lt;span style="color:#f92672"&gt;:&lt;/span&gt; val(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;), left(&lt;span style="color:#66d9ef"&gt;nullptr&lt;/span&gt;), right(&lt;span style="color:#66d9ef"&gt;nullptr&lt;/span&gt;) {}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TreeNode(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; x) &lt;span style="color:#f92672"&gt;:&lt;/span&gt; val(x), left(&lt;span style="color:#66d9ef"&gt;nullptr&lt;/span&gt;), right(&lt;span style="color:#66d9ef"&gt;nullptr&lt;/span&gt;) {}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TreeNode(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; x, TreeNode &lt;span style="color:#f92672"&gt;*&lt;/span&gt;left, TreeNode &lt;span style="color:#f92672"&gt;*&lt;/span&gt;right) &lt;span style="color:#f92672"&gt;:&lt;/span&gt; val(x), left(left), right(right) {}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="前序遍历"&gt;前序遍历&lt;/h2&gt;&#10;&lt;p&gt;前序遍历的顺序是中左右，每次先处理中间节点，那么先将根节点入栈，然后将右孩子入栈，再将左孩子入栈。先右后左的原因是因为入栈顺序和处理顺序是相反的。前序遍历的处理代码如下：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Solution&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; vector&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; preorderTraversal(TreeNode&lt;span style="color:#f92672"&gt;*&lt;/span&gt; root) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; vector&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; res;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; stack&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;TreeNode&lt;span style="color:#f92672"&gt;*&amp;gt;&lt;/span&gt; st;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (root &lt;span style="color:#f92672"&gt;==&lt;/span&gt; NULL) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; res;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; st.push(root);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;st.empty()) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TreeNode &lt;span style="color:#f92672"&gt;*&lt;/span&gt;cur &lt;span style="color:#f92672"&gt;=&lt;/span&gt; st.top();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; st.pop();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; res.push_back(cur&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;val);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (cur&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;right) st.push(cur&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;right);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (cur&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;left) st.push(cur&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;left);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; res;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="中序遍历"&gt;中序遍历&lt;/h2&gt;&#10;&lt;p&gt;中序遍历处理顺序为左中右，先访问二叉树顶部的节点，随后逐层向下访问直到树最左侧的节点，再开始处理节点，这导致处理节点的顺序和访问节点的顺序不一致。中序遍历的迭代法如下所示：&lt;/p&gt;</description></item><item><title>LeetCode刷题 - 滑动窗口最大值</title><link>https://lishengxie.top/post/leetcode-moving-window-maximum/</link><pubDate>Tue, 17 Oct 2023 20:11:52 +0800</pubDate><guid>https://lishengxie.top/post/leetcode-moving-window-maximum/</guid><description>&lt;h2 id="leetcode刷题---滑动窗口最大值"&gt;LeetCode刷题 - &lt;strong&gt;滑动窗口最大值&lt;/strong&gt;&lt;/h2&gt;&#10;&lt;p&gt;参考链接:&lt;a href="https://programmercarl.com/0239.%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3%E6%9C%80%E5%A4%A7%E5%80%BC.html"&gt;https://programmercarl.com/0239.%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3%E6%9C%80%E5%A4%A7%E5%80%BC.html&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;leetcode题目链接：&lt;a href="https://leetcode.cn/problems/sliding-window-maximum/"&gt;https://leetcode.cn/problems/sliding-window-maximum/&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;给你一个整数数组 nums，有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。&lt;/p&gt;&#10;&lt;p&gt;返回滑动窗口中的最大值 。&lt;/p&gt;&#10;&lt;p&gt;示例 1：&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;输入：nums = [1,3,-1,-3,5,3,6,7], k = 3&#10;输出：[3,3,5,5,6,7]&#10;解释：&#10;滑动窗口的位置 最大值&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;p&gt;[1 3 -1] -3 5 3 6 7 3&#10;1 [3 -1 -3] 5 3 6 7 3&#10;1 3 [-1 -3 5] 3 6 7 5&#10;1 3 -1 [-3 5 3] 6 7 5&#10;1 3 -1 -3 [5 3 6] 7 6&#10;1 3 -1 -3 5 [3 6 7] 7&lt;/p&gt;&#10;&lt;/blockquote&gt;</description></item><item><title>LJson</title><link>https://lishengxie.top/post/ljson/</link><pubDate>Wed, 16 Aug 2023 10:42:01 +0800</pubDate><guid>https://lishengxie.top/post/ljson/</guid><description>&lt;h1 id="ljson"&gt;LJSon&lt;/h1&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;A C++ library for json parse/creation/update&lt;/li&gt;&#10;&lt;li&gt;package地址：&lt;a href="https://github.com/lishengxie/LJson"&gt;https://github.com/lishengxie/LJson&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="开发原因"&gt;开发原因&lt;/h2&gt;&#10;&lt;p&gt;最近在复习C++相关的知识，想要通过一个项目来巩固C++和算法的一些相关知识，但是网上推荐的相关C++项目大多比较复杂，很难下手。刚好最近实验室项目中频繁使用json文件，想到是否可以使用C++来实现一个json的解析库，在github上搜索后看到了一些现有的json仓库，初步了解后开始进行实现。&lt;/p&gt;&#10;&lt;h2 id="参考仓库"&gt;参考仓库&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://github.com/510850111/cJSON/tree/master"&gt;https://github.com/510850111/cJSON/tree/master&lt;/a&gt;，在这个项目中学习了json对象的表示以及如何操作json对象；&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://github.com/ACking-you/MyUtil/tree/master/json-parser"&gt;https://github.com/ACking-you/MyUtil/tree/master/json-parser&lt;/a&gt;，在这个项目中学习了如何从json字符串中解析数据，服用了部分解析json字符串的代码；&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://github.com/nlohmann/json"&gt;https://github.com/nlohmann/json&lt;/a&gt;，著名的json处理库，从中学习了如何使用初始化列表来实现类Python的方式创建和更新json对象。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="json文件格式"&gt;json文件格式&lt;/h2&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;这里只做简单介绍，具体的格式可以参考json官网&lt;a href="http://www.json.org"&gt;http://www.json.org&lt;/a&gt;。&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;json主要基于两种结构，分别是“键值对集合”和“值的有序列表”，前者可以看做字典或哈希表，后者可以看做数组。&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;对象是无序的键值对集合，一个对象被包含在&lt;code&gt;{}&lt;/code&gt;中，每个键值对的格式为&lt;code&gt;key:value&lt;/code&gt;，其中&lt;code&gt;key&lt;/code&gt;是字符串，value可以是字符串、布尔类型(&lt;code&gt;true&lt;/code&gt;/&lt;code&gt;false&lt;/code&gt;)、&lt;code&gt;null&lt;/code&gt;、数值(整数或浮点数)、对象、数组；键值对之间使用&lt;code&gt;,&lt;/code&gt;分隔，对象应该使用key索引对应的值；&lt;/li&gt;&#10;&lt;li&gt;数组是值的有序集合，包含在&lt;code&gt;[]&lt;/code&gt;中，值可以是前面提到的字符串、布尔类型(&lt;code&gt;true&lt;/code&gt;/&lt;code&gt;false&lt;/code&gt;)、&lt;code&gt;null&lt;/code&gt;、数值(整数或浮点数)、对象、数组，值之间使用&lt;code&gt;,&lt;/code&gt;分隔；&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;通过使用对象、数组以及支持两者之间的嵌套，json可以支持复杂的数据格式定义和传递。&lt;/p&gt;&#10;&lt;h2 id="使用数据结构表示json对象"&gt;使用数据结构表示json对象&lt;/h2&gt;&#10;&lt;p&gt;前面提到了json文件的格式，一种很自然的表示json对象的方式应该是使用字典表示对象，字典的值本身也可以是一个json对象，有一些json解析库中使用了这种方式，可以参考Python中&lt;code&gt;json&lt;/code&gt;库对json文件的读写。我们使用了另外一种方式，即使用树形结构来表示整个json对象，如下图所示：&#10;&lt;a href="https://lishengxie.top/uploads/2023/08/json-node-fig.png"&gt;&lt;img src="https://lishengxie.top/uploads/2023/08/json-node-fig.png" alt=""&gt;&lt;/a&gt;&#10;对应的C++定义如下，对象中的每个键值对以及数组中的每个值都使用一个JsonObject对象来表示，整个对象/数组的键值对/值使用双向链表进行表示，遍历整个双向链表即可以遍历整个json对象或数组。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;enum&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;JsonType&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; T_FALSE&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, T_TRUE, T_NULL, T_INT, T_FLOAT, T_STRING, T_ARRAY, T_OBJECT&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;JsonObject&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* next和prev分别指向前一个对象和后一个对象 */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; JsonObject &lt;span style="color:#f92672"&gt;*&lt;/span&gt;next, &lt;span style="color:#f92672"&gt;*&lt;/span&gt;prev;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* Object和Array类型对象需要设置child指针 */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; JsonObject &lt;span style="color:#f92672"&gt;*&lt;/span&gt;child;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* Object的类型 */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; JsonType type;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* String对象的值 */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;valueString;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* 整数对象的值 */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; valueInt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* 浮点数的值 */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;double&lt;/span&gt; valueDouble;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* 键值对的键 */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;key;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;以上图为例，假设有如下的json对象&lt;/p&gt;</description></item><item><title>内网离线服务器使用</title><link>https://lishengxie.top/post/offline-server-usage/</link><pubDate>Sat, 03 Jun 2023 20:34:46 +0800</pubDate><guid>https://lishengxie.top/post/offline-server-usage/</guid><description>&lt;p&gt;最近在跑实验时，自己的电脑出现内存不够用的问题，想到在实验室的一台闲置的服务器上运行程序。但是该服务器只能通过内网连接，无法使用外网，因此这里记录了内网离线服务器使用的一些经历。&#10;可以考虑在服务器上安装docker，然后在自己电脑上配好环境后导出docker镜像到服务器上运行。这里没有使用docker环境，本地环境是WSL2-Ubuntu20.04。&lt;/p&gt;&#10;&lt;h2 id="程序运行环境配置"&gt;程序运行环境配置&lt;/h2&gt;&#10;&lt;h3 id="c"&gt;C++&lt;/h3&gt;&#10;&lt;p&gt;针对C++程序，重新下载代码编译；&lt;/p&gt;&#10;&lt;h3 id="python"&gt;Python&lt;/h3&gt;&#10;&lt;p&gt;重新配置Python环境主要经历了以下步骤：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;下载miniconda安装程序并安装；&lt;/li&gt;&#10;&lt;li&gt;WSL2环境迁移到服务器中，这里选择直接打包WSL2下面的虚拟环境目录并到服务器相应目录下解压，参考了教程&lt;a href="https://blog.csdn.net/qq_45893319/article/details/122226053"&gt;https://blog.csdn.net/qq_45893319/article/details/122226053&lt;/a&gt;;&lt;/li&gt;&#10;&lt;li&gt;直接打包的环境，无法使用pip的问题，可以通过修改pip文件解决，参考教程&lt;a href="https://blog.csdn.net/qq_40933913/article/details/127907916"&gt;https://blog.csdn.net/qq_40933913/article/details/127907916&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;环境迁移后发现在迁移的环境中无法使用clear命令，原因是迁移过来的环境中clear文件有问题。解决方案如下：&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;在出错的环境下，输入&lt;code&gt;which clear&lt;/code&gt;，然后将&lt;code&gt;clear&lt;/code&gt;地址重命名，下次再&lt;code&gt;clear&lt;/code&gt;时会生成新的。&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mv /home/xxx/.conda/envs/yolox/bin/clear /home/xxx/.conda/envs/yolox/bin/clear_old&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="vscode连接服务器开发"&gt;vscode连接服务器开发&lt;/h3&gt;&#10;&lt;p&gt;参考教程&lt;a href="https://blog.csdn.net/ffriend/article/details/126680223"&gt;https://blog.csdn.net/ffriend/article/details/126680223&lt;/a&gt;。&#10;由于服务器离线，使用vscode连接时无法在远程服务器上下载vscode-server，这里需要手动下载一下。步骤如下&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;查看本地vscode的commit id：帮助-关于，复制commit id&lt;/li&gt;&#10;&lt;li&gt;本地下载vscode-server&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;wget https://update.code.visualstudio.com/commit:&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;commit_id&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;/server-linux-x64/stable&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 注意把:${commit_id}替换成对应的Commit ID&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="3"&gt;&#10;&lt;li&gt;复制到服务器并安装&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rm ~/.vscode-server/bin/* -rf &lt;span style="color:#75715e"&gt;#把$HOME/.vscode-server/bin下的内容删干净，防止出错&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd ~/.vscode-server/bin&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;tar -zxf vscode-server-linux-x64.tar.gz&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mv vscode-server-linux-x64 &lt;span style="color:#e6db74"&gt;${&lt;/span&gt;commit_id&lt;span style="color:#e6db74"&gt;}&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 注意把:${commit_id}替换成对应的Commit ID&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="服务器安装screen应用"&gt;服务器安装screen应用&lt;/h3&gt;&#10;&lt;p&gt;参考教程&lt;a href="https://blog.csdn.net/Demo_Null/article/details/110873673"&gt;https://blog.csdn.net/Demo_Null/article/details/110873673&lt;/a&gt;，主要是编译安装screen和ncurses两个可执行程序，这里需要管理员权限，负责无法安装到默认的安装位置。&lt;/p&gt;&#10;&lt;h4 id="screen常用命令如下"&gt;screen常用命令如下&lt;/h4&gt;&#10;&lt;p&gt;1、启动共享窗口：screen -S 名称&#10;2、查看当前所有共享会话：screen -ls&#10;3、进入共享会话：screen -r 名称&#10;4、退出共享会话：ctrl +a +d&lt;/p&gt;</description></item><item><title>建站过程</title><link>https://lishengxie.top/post/website-build/</link><pubDate>Sun, 30 Apr 2023 08:55:32 +0800</pubDate><guid>https://lishengxie.top/post/website-build/</guid><description>&lt;h3 id="购买腾讯云服务器"&gt;购买腾讯云服务器&lt;/h3&gt;&#10;&lt;p&gt;购买腾讯云清量2核4G服务器&lt;a href="https://cloud.tencent.com/act/cps/redirect?redirect=3274&amp;amp;cps_key=822991d9cc1eddb9c45d4c9d51e8cc65&amp;amp;from=console"&gt;直达链接&lt;/a&gt;&lt;/p&gt;&#10;&lt;h3 id="启动镜像"&gt;启动镜像&lt;/h3&gt;&#10;&lt;p&gt;这里选择了Ubuntu server 20.04，启动镜像后设置远程登录(远程登录-&amp;gt;密码/密钥登录-&amp;gt;重置密码)，需要注意这里的用户需要系统中已经存在，默认已经存在一个用户ubuntu，这里我们直接使用该用户。&#10;配置好后可以本地使用Mobaxterm登录云服务器，将云服务器当作Ubuntu虚拟机使用。&lt;/p&gt;&#10;&lt;h3 id="搭建wordpress网站"&gt;搭建wordpress网站&lt;/h3&gt;&#10;&lt;p&gt;网站搭建参考了博客&lt;a href="https://blog.csdn.net/weixin_36338224/article/details/109105047"&gt;https://blog.csdn.net/weixin_36338224/article/details/109105047&lt;/a&gt;。&lt;/p&gt;&#10;&lt;h3 id="主题替换"&gt;主题替换&lt;/h3&gt;&#10;&lt;p&gt;下载&lt;a href="https://github.com/seatonjiang/kratos/releases/tag/v4.1.5"&gt;Kratos主题&lt;/a&gt;并上传替换原有主题，在外观里设置。&lt;/p&gt;&#10;&lt;h3 id="markdownlatex公式使用"&gt;Markdown&amp;amp;Latex公式使用&lt;/h3&gt;&#10;&lt;p&gt;安装WP Editor.md插件，在wordpress中使用markdown编辑。&#10;安装Simple MathJax插件，实现对latex公示的支持，需要注意的是这里行内公式使用&lt;code&gt;\\(...\\)&lt;/code&gt;，例如\(\sigma\)，行间公式使用&lt;code&gt;$$..$$&lt;/code&gt;，例如&lt;/p&gt;&#10;&lt;div class="katex-display"&gt;\sigma&lt;/div&gt;&lt;p&gt;。&lt;/p&gt;</description></item><item><title>Windows常见问题记录</title><link>https://lishengxie.top/post/windows-problem/</link><pubDate>Sun, 30 Apr 2023 08:54:20 +0800</pubDate><guid>https://lishengxie.top/post/windows-problem/</guid><description>&lt;h2 id="触摸板无法使用"&gt;触摸板无法使用&lt;/h2&gt;&#10;&lt;p&gt;在设置中选择“插入鼠标后禁用触摸板”选项后，将鼠标拔出后触摸板仍然无法使用，出现这种问题后&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;关闭“插入鼠标后禁用触摸板”选项，插入鼠标观察触摸板是否可以使用，如果不能使用那么触摸板可能损坏，需要进一步排查；如果可以使用，那么可能是因为设备管理器中出现了虚拟鼠标；&lt;/li&gt;&#10;&lt;li&gt;如果是第一步的第二种情况，需要在设备管理器中禁用第一个鼠标选项，如下图所示：&#10;&lt;a href="https://lishengxie.top/uploads/2023/04/wp_editor_md_ce91cd92c52b92c2f1e07f960f460289.jpg"&gt;&lt;img src="https://lishengxie.top/uploads/2023/04/wp_editor_md_ce91cd92c52b92c2f1e07f960f460289.jpg" alt=""&gt;&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ol&gt;</description></item><item><title>SystemC学习</title><link>https://lishengxie.top/post/systemc-study/</link><pubDate>Sun, 30 Apr 2023 08:52:48 +0800</pubDate><guid>https://lishengxie.top/post/systemc-study/</guid><description>&lt;h3 id="视频教程"&gt;视频教程&lt;/h3&gt;&#10;&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=NCFxBGLB5xs&amp;amp;list=PLcvQHr8v8MQLj9tCYyOw44X1PLisEsX-J&amp;amp;index=2"&gt;教程链接&lt;/a&gt;&lt;/p&gt;&#10;&lt;h3 id="创建模块"&gt;创建模块&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;systemc.h&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// SC_MODULE声明模块，and2对应模块名&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;SC_MODULE(and2){&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#75715e"&gt;// sc_in声明输入端口，DT对应端口变量数据类型&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;sc_in&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;DT&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; a;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;sc_in&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;DT&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; b;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#75715e"&gt;// 声明时钟信号&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;sc_in&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; clk;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#75715e"&gt;// sc_out声明输出端口&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;sc_out&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;DT&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; f;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;func&lt;/span&gt;() {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&lt;span style="color:#75715e"&gt;// 输入端口读数据.read()&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&lt;span style="color:#75715e"&gt;// 输出端口写数据.write()&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;f.write(a.read() &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt; b.read());&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#75715e"&gt;// 模块构造函数&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;SC_CTOR(and2){&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&lt;span style="color:#75715e"&gt;// 声明线程&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;SC_METHOD(func);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&lt;span style="color:#75715e"&gt;// 线程声明后紧接着声明敏感信号列表，以 &amp;lt;&amp;lt; 号隔开&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&lt;span style="color:#75715e"&gt;// 声明a和b为敏感信号&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;sensitive &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; a &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; b;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&lt;span style="color:#75715e"&gt;// 声明clk的上升沿为敏感信号，下降沿为.neg()&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&lt;span style="color:#75715e"&gt;// sensitive &amp;lt;&amp;lt; clk.pos();&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="threads"&gt;Threads&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;A function made to act like a hardware process&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Run concurrently;&lt;/li&gt;&#10;&lt;li&gt;Sensitive to signals, clock edges or fixed amounts of simulation time;&lt;/li&gt;&#10;&lt;li&gt;Not called by the user, always active&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;支持三种threads&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;SC_METHOD()&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Executes once every sensitive event&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Run continuously&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;类似于Verilog @always block&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;可综合&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;组合逻辑或者简单时序逻辑&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;SC_THREAD()&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;只在simulation开始时运行一次&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;可以使用无限循环来以固定频率执行代码段&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;类似于Verilog @initial block&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;不可综合&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;在testbench中用于初始化、描述时钟等&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;SC_CTHREAD()&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&amp;ldquo;clocked thread&amp;rdquo;&lt;/li&gt;&#10;&lt;li&gt;Run continuously&lt;/li&gt;&#10;&lt;li&gt;References a clock edge&lt;/li&gt;&#10;&lt;li&gt;可综合&lt;/li&gt;&#10;&lt;li&gt;Can take one or more clock cycles to execute a single iteration&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Datatypes&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;SystemC has bit-accurate&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Integer Datatypes&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Unsigned and signed&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;sc_uint&amp;lt;N&amp;gt;&lt;/code&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;N是位宽&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;sc_int&amp;lt;N&amp;gt;&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>云服务器软件安装</title><link>https://lishengxie.top/post/cloud-server-software-install/</link><pubDate>Sun, 30 Apr 2023 08:51:16 +0800</pubDate><guid>https://lishengxie.top/post/cloud-server-software-install/</guid><description>&lt;p&gt;&lt;strong&gt;Docker安装(Ubuntu 20.04)&lt;/strong&gt;：参考&lt;a href="https://zhuanlan.zhihu.com/p/143156163"&gt;知乎博客&lt;/a&gt;&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;更新软件包索引，并且安装必要的依赖软件&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;sudo apt update&#10;sudo apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common&#10;&lt;/code&gt;&lt;/pre&gt;&lt;ol start="2"&gt;&#10;&lt;li&gt;使用下面的 curl 导入源仓库的 GPG key：&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -&#10;&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;&#10;&lt;li&gt;将 Docker APT 软件源添加到你的系统：&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;sudo add-apt-repository &amp;#34;deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable&amp;#34;&#10;&lt;/code&gt;&lt;/pre&gt;&lt;ol start="4"&gt;&#10;&lt;li&gt;安装Docker&#10;a. 安装最新版本的Docker&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;sudo apt update&#10;sudo apt install docker-ce docker-ce-cli containerd.io&#10;&lt;/code&gt;&lt;/pre&gt;b. 安装指定版本的docker&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;# 列出所有可用的docker版本&#10;sudo apt update&#10;apt list -a docker-ce&#10;# 安装docker&#10;sudo apt install docker-ce=&amp;lt;VERSION&amp;gt; docker-ce-cli=&amp;lt;VERSION&amp;gt; containerd.io&#10;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&#10;&lt;li&gt;验证安装成功&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;sudo systemctl status docker&#10;docker container run hello-world&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Golang安装&lt;/strong&gt;：参考&lt;a href="https://cloud.tencent.com/developer/article/1623121"&gt;腾讯云博客&lt;/a&gt;&lt;/p&gt;</description></item><item><title>常用资源汇总</title><link>https://lishengxie.top/post/common-resources/</link><pubDate>Sun, 30 Apr 2023 08:49:48 +0800</pubDate><guid>https://lishengxie.top/post/common-resources/</guid><description>&lt;h3 id="python"&gt;python&lt;/h3&gt;&#10;&lt;h4 id="pip国内镜像"&gt;pip国内镜像&lt;/h4&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 清华镜像源&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;https://pypi.tuna.tsinghua.edu.cn/simple&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 豆瓣镜像源&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;http://pypi.douban.com/simple/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 阿里云镜像源&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;http://mirrors.aliyun.com/pypi/simple/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 中国科学技术大学镜像源&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;http://pypi.mirrors.ustc.edu.cn/simple/&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;使用方法为&lt;code&gt;pip install package_name -i 镜像源&lt;/code&gt;&lt;/p&gt;&#10;&lt;h3 id="ubuntu更换镜像源"&gt;Ubuntu更换镜像源&lt;/h3&gt;&#10;&lt;p&gt;如果Ubuntu原始速度还可以的话建议不要换源，常用的有阿里云镜像、清华镜像和搜狐镜像，这里是我使用的镜像，北京外国语大学镜像。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;deb https://mirrors.bfsu.edu.cn/ubuntu/ focal main restricted universe multiverse&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# deb-src https://mirrors.bfsu.edu.cn/ubuntu/ focal main restricted universe multiverse&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;deb https://mirrors.bfsu.edu.cn/ubuntu/ focal-updates main restricted universe multiverse&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# deb-src https://mirrors.bfsu.edu.cn/ubuntu/ focal-updates main restricted universe multiverse&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;deb https://mirrors.bfsu.edu.cn/ubuntu/ focal-backports main restricted universe multiverse&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# deb-src https://mirrors.bfsu.edu.cn/ubuntu/ focal-backports main restricted universe multiverse&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;deb https://mirrors.bfsu.edu.cn/ubuntu/ focal-security main restricted universe multiverse&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# deb-src https://mirrors.bfsu.edu.cn/ubuntu/ focal-security main restricted universe multiverse&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 预发布软件源，不建议启用&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# deb https://mirrors.bfsu.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# deb-src https://mirrors.bfsu.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ubuntu换源的具体操作为&lt;/p&gt;</description></item><item><title>Linux常用命令记录</title><link>https://lishengxie.top/post/linux-command/</link><pubDate>Sun, 30 Apr 2023 08:47:32 +0800</pubDate><guid>https://lishengxie.top/post/linux-command/</guid><description>&lt;h3 id="vim"&gt;Vim&lt;/h3&gt;&#10;&lt;p&gt;&lt;strong&gt;vim删除文件中的所有内容&lt;/strong&gt;： ESC确保退出编辑模式，按下&amp;quot;:&amp;ldquo;切换到命令模式然后输入%d并执行&#10;&lt;strong&gt;vim删除单行内容&lt;/strong&gt;：将光标移动到需要删除的行，ESC确保退出编辑模式，按两次d键。&#10;&lt;strong&gt;vim删除多行内容&lt;/strong&gt;：将光标移动到需要删除的第一行，ESC确保退出编辑模式。在dd命令前面加上要删除的行数。例如，如果要删除第4行以下的3行，请先移动至第四行，再按下3dd。&#10;&lt;strong&gt;vim撤销&amp;amp;恢复&lt;/strong&gt;：u是撤销刚才做的动作，ctrl+r 是恢复刚才撤销的动作。&lt;/p&gt;&#10;&lt;h3 id="文件操作"&gt;文件操作&lt;/h3&gt;&#10;&lt;p&gt;参考博客&lt;a href="https://www.cnblogs.com/liaojie970/p/6746230.html"&gt;https://www.cnblogs.com/liaojie970/p/6746230.html&lt;/a&gt;&lt;/p&gt;&#10;&lt;h4 id="文件复制"&gt;文件复制&lt;/h4&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;命令格式：cp &lt;span style="color:#f92672"&gt;[&lt;/span&gt;-adfilprsu&lt;span style="color:#f92672"&gt;]&lt;/span&gt; 源文件&lt;span style="color:#f92672"&gt;(&lt;/span&gt;source&lt;span style="color:#f92672"&gt;)&lt;/span&gt; 目标文件&lt;span style="color:#f92672"&gt;(&lt;/span&gt;destination&lt;span style="color:#f92672"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cp &lt;span style="color:#f92672"&gt;[&lt;/span&gt;option&lt;span style="color:#f92672"&gt;]&lt;/span&gt; source1 source2 source3 ... directory&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;参数说明：&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;-a:是指archive的意思，也说是指复制所有的目录&#10;-d:若源文件为连接文件(link file)，则复制连接文件属性而非文件本身&#10;-f:强制(force)，若有重复或其它疑问时，不会询问用户，而强制复制&#10;-i:若目标文件(destination)已存在，在覆盖时会先询问是否真的操作&#10;-l:建立硬连接(hard link)的连接文件，而非复制文件本身&#10;-p:与文件的属性一起复制，而非使用默认属性&#10;-r:递归复制，用于目录的复制操作&#10;-s:复制成符号连接文件(symbolic link)，即“快捷方式”文件&#10;-u:若目标文件比源文件旧，更新目标文件 &#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如将/test1目录下的file1复制到/test3目录，并将文件名改为file2,可输入以下命令：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cp /test1/file1 /test3/file2&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="文件移动"&gt;文件移动&lt;/h4&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;命令格式：mv &lt;span style="color:#f92672"&gt;[&lt;/span&gt;-fiv&lt;span style="color:#f92672"&gt;]&lt;/span&gt; source destination&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;参数说明:&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;-f:force，强制直接移动而不询问&#10;-i:若目标文件(destination)已经存在，就会询问是否覆盖&#10;-u:若目标文件已经存在，且源文件比较新，才会更新&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如将/test1目录下的file1移动到/test3 目录，并将文件名改为file2,可输入以下命令：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mv /test1/file1 /test3/file2&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="文件删除"&gt;文件删除&lt;/h4&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;命令格式：rm &lt;span style="color:#f92672"&gt;[&lt;/span&gt;fir&lt;span style="color:#f92672"&gt;]&lt;/span&gt; 文件或目录&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;参数说明：&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;-f:强制删除&#10;-i:交互模式，在删除前询问用户是否操作&#10;-r:递归删除，常用在目录的删除&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如删除/test目录下的file1文件，可以输入以下命令：&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;rm -i /test/file1&#10;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="windows-常用命令"&gt;Windows 常用命令&lt;/h3&gt;&#10;&lt;p&gt;&lt;strong&gt;PowerShell创建新文件夹和新文件&lt;/strong&gt;&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;mkdir 文件夹名称&#10;new-item 文件名称.文件格式 -type file&#10;&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>多目标优化问题及两种常用解法</title><link>https://lishengxie.top/post/algorithm-study-multiopt/</link><pubDate>Sun, 30 Apr 2023 08:45:39 +0800</pubDate><guid>https://lishengxie.top/post/algorithm-study-multiopt/</guid><description>&lt;h3 id="多目标优化问题"&gt;多目标优化问题&lt;/h3&gt;&#10;&lt;p&gt;多目标优化（也称为多目标规划、向量优化、多标准优化、多属性优化或帕累托优化）是多标准决策制定的一个领域，涉及同时优化多个目标函数的数学优化问题，需要在权衡取舍的情况下在两个或多个相互冲突的目标之间做出最佳决策。(&lt;a href="https://en.wikipedia.org/wiki/Multi-objective_optimization"&gt;维基百科&lt;/a&gt;)&lt;/p&gt;&#10;&lt;p&gt;多目标优化问题中目标函数之间通常相互冲突，求解多目标优化问题通常希望找到可以很好地平衡不同优化目标的解，即帕累托最优解。&lt;/p&gt;&#10;&lt;h4 id="多目标优化问题的数学描述"&gt;多目标优化问题的数学描述&lt;/h4&gt;&#10;&lt;div class="katex-display"&gt;\min_{x\in X} (f_1(x),f_2(x),\dots,f_k(x))&lt;/div&gt;&lt;p&gt;其中\(k\geq 2\)，\((f_1(x),f_2(x),\dots,f_k(x))\)式决策函数集合。&lt;/p&gt;&#10;&lt;h4 id="帕累托最优"&gt;帕累托最优&lt;/h4&gt;&#10;&lt;p&gt;帕累托最优是指这样一种情况，没有可用的行动或分配可以使一个人过得更好而不会使另一个人过得更糟。多目标优化问题中我们希望找到的就是帕累托最优解，再由决策者决定具体使用那个解。帕累托最优解集指的是所有可行解中的不可支配解集，下面我们将介绍支配和不可支配解集的概念。&lt;/p&gt;&#10;&lt;h4 id="支配和不可支配解集"&gt;支配和不可支配解集&lt;/h4&gt;&#10;&lt;p&gt;&lt;a href="https://lishengxie.top/uploads/2023/03/22.png"&gt;&lt;img src="https://lishengxie.top/uploads/2023/03/22.png" alt="帕累托前沿"&gt;&lt;/a&gt;&#10;当解\(x_1\)和\(x_2\)满足以下两个条件时&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;对于所有的目标函数，\(f_i(x_1)\leq f_i(x_2)\)，其中\(1\leq i \leq k\)&lt;/li&gt;&#10;&lt;li&gt;至少由一个目标函数\(f_i(x)\)满足\(f_i(x_1) &amp;lt; f_i(x_2)\)，其中\(1\leq i \leq k\)&#10;我们称\(x_1\)支配\(x_2\)，如上图中\(A\)和\(B\)都支配\(C\)，但彼此之间不存在支配关系。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;当一个解集中任何一个解都不能被该集合中其他解支配，那么就称该解集为不可支配解集。一组帕累托最优结果，如上图中红色的边界，称为帕累托前沿或帕累托边界。&lt;/p&gt;&#10;&lt;p&gt;求解多目标优化问题的方法主要分为两类，一种是将多目标优化问题转换成单目标优化问题，常用的方法是对目标函数值加权求和或保留一个目标函数、其余的目标函数被转化为限定条件。但是由于实际应用中目标函数的函数值范围不好确定，因此转换成单目标优化算法的效果常常不好。实际应用更加广泛的是另一种采用多目标的优化算法。&lt;/p&gt;&#10;&lt;h3 id="多目标粒子群算法mopso"&gt;多目标粒子群算法MOPSO&lt;/h3&gt;&#10;&lt;p&gt;多目标粒子群算法最早由Coello等人提出&lt;a href="#refer-anchor"&gt;&lt;sup&gt;[1]&lt;/sup&gt;&lt;/a&gt;，算法的大致处理步骤如下所示：&#10;&lt;a href="https://lishengxie.top/uploads/2023/03/23.png"&gt;&lt;img src="https://lishengxie.top/uploads/2023/03/23.png" alt="MOPSO"&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;和粒子群算法不同的是，这里添加了支配关系判断的步骤，同时选择全局最优解以及更新个体最优的步骤和粒子群算法也有所不同。此外，MOPSO还额外维护了精英解和解空间的网格，下面我们将分别加以介绍。&lt;/p&gt;&#10;&lt;p&gt;首先是支配关系的判断，根据第一部分中对于帕累托前沿和支配关系的介绍，我们知道多目标优化问题中解的优劣由支配关系来加以判断。&lt;/p&gt;&#10;&lt;p&gt;每次迭代开始时，我们需要从精英解集合中选择当前的全局最优解，精英解中包含的是不被其他解支配的解的集合，换言之，精英解包含的是目前获取到的帕累托前沿。选择全局最优解的步骤如下：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;在解集空间中绘制网格，即根据当前的解集中不同目标函数的最大值和最小值，将空间均匀等分并给每个子空间添加索引，确定不同的解所对应的子空间。&lt;/li&gt;&#10;&lt;li&gt;对于包含解的子空间，判断每个子空间中存在的解个数\(N_1,\cdots,N_k\)，使用轮盘赌算法获取当前的全局最优解，轮盘赌的概率和解的个数呈反相关关系（让解稀疏的子空间拥有更大的被选中的概率，设法让解在帕累托前沿上分布更均匀）。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;选择好当前的全局最优解后更新粒子的位置和速度，更新公式和粒子群算法一致。&lt;/p&gt;&#10;&lt;div class="katex-display"&gt; v_i = w \times v_i + c_1\times rand() \times ((p_{best})_i-x_i) + c_2\times rand()\times (g_{best}-x_i)&lt;/div&gt;&lt;p&gt;粒子更新后会根据粒子当前解和局部最优解之间的支配关系更新粒子的局部最优解。在更新局部最优解之前，还可以采取类似于遗传算法的步骤，以一定的概率对粒子的当前解进行变异。&lt;/p&gt;&#10;&lt;p&gt;更新完局部最优解之后更新精英解集合，保留当前不被其他解支配的解，同时为了避免精英解过大，可以设置一个阈值来控制精英解集合中的解数目，多余的精英解被随机抛弃。&lt;/p&gt;&#10;&lt;h3 id="多目标遗传算法nsga-ii"&gt;多目标遗传算法NSGA-II&lt;/h3&gt;&#10;&lt;p&gt;多目标遗传算法NSGA-II由Deb等人提出&lt;a href="#refer-anchor"&gt;&lt;sup&gt;[2]&lt;/sup&gt;&lt;/a&gt;，算法的大致处理步骤如下所示：&#10;&lt;a href="https://lishengxie.top/uploads/2023/03/24.png"&gt;&lt;img src="https://lishengxie.top/uploads/2023/03/24.png" alt="NSGA-II"&gt;&lt;/a&gt;&#10;相较于单目标进化算法添加了快速非支配排序和父代、子代合并操作增加种群多样性，此外从\(rank_i\) 中取出一部分个体有两种方式、一种是拥挤距离排序、另一种是随机选择。下面我们将分别加以介绍。&lt;/p&gt;&#10;&lt;p&gt;对于当前已有的父代解和子代集合，融合两个集合产生当前的解集合，首先执行非支配排序，非支配排序的大致步骤为，先找出解集中的非支配边沿，将这部分的解的\(rank\)置为1；去掉这部分解，继续找出剩下的解集中的非支配边沿，将这部分的解的\(rank\)置为2，重复上述步骤知道遍历完所有的解。实际实现中需要记录每个解支配的解，方便后续的\(rank\)计算，具体可以参考后面的参考代码实现。&lt;/p&gt;&#10;&lt;p&gt;在当前解集合中选取下一轮迭代的父代解集合。需要注意的是对于固定大小的父代解集合，这里依次从\(rank=1\)的解开始加入，知道数量满足要求。最后可能需要从\(rank=i\)的解集合中选取一部分，此时有两种方式，一种是随机选取，一种是根据拥挤度距离排序后选取。拥挤度距离计算的示意图如下，&#10;&lt;a href="https://lishengxie.top/uploads/2023/03/25.png"&gt;&lt;img src="https://lishengxie.top/uploads/2023/03/25.png" alt="拥挤度距离"&gt;&lt;/a&gt;&#10;拥挤度距离可以用来衡量当前解周围的解的密度，优先选择拥挤度距离大(解稀疏)的地方可以使得最后求得的帕累托前沿上解分布更均匀。&lt;/p&gt;&#10;&lt;p&gt;对当前的解执行交叉变异操作产生下一轮迭代的子代解，交叉变异操作可以有不同的实现。&lt;/p&gt;&#10;&lt;h3 id="代码实现"&gt;代码实现&lt;/h3&gt;&#10;&lt;h4 id="目标函数"&gt;目标函数&lt;/h4&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# -*- coding : utf-8 -*-&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; collections &lt;span style="color:#f92672"&gt;import&lt;/span&gt; defaultdict&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; math&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; numpy &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; np&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ZDT1&lt;/span&gt;(x):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; 测试函数——ZDT1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :parameter&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param x: 为 m 维向量，表示个体的具体解向量&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :return f: 为两个目标方向上的函数值&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; poplength &lt;span style="color:#f92672"&gt;=&lt;/span&gt; len(x)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; f &lt;span style="color:#f92672"&gt;=&lt;/span&gt; defaultdict(float)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; g &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;9&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; sum(x[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;:poplength]) &lt;span style="color:#f92672"&gt;/&lt;/span&gt; (poplength &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; f[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; x[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; f[&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; g &lt;span style="color:#f92672"&gt;*&lt;/span&gt; (&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; pow(x[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] &lt;span style="color:#f92672"&gt;/&lt;/span&gt; g, &lt;span style="color:#ae81ff"&gt;0.5&lt;/span&gt;))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; f&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ZDT2&lt;/span&gt;(x):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; poplength &lt;span style="color:#f92672"&gt;=&lt;/span&gt; len(x)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; f &lt;span style="color:#f92672"&gt;=&lt;/span&gt; defaultdict(float)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; g &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;9&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; sum(x[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;:poplength]) &lt;span style="color:#f92672"&gt;/&lt;/span&gt; (poplength &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; f[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; x[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; f[&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; g &lt;span style="color:#f92672"&gt;*&lt;/span&gt; (&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; (x[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] &lt;span style="color:#f92672"&gt;/&lt;/span&gt; g) &lt;span style="color:#f92672"&gt;**&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; f&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;KUR&lt;/span&gt;(x):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; f &lt;span style="color:#f92672"&gt;=&lt;/span&gt; defaultdict(float)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; poplength &lt;span style="color:#f92672"&gt;=&lt;/span&gt; len(x)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; f[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(poplength &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; f[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; f[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;] &lt;span style="color:#f92672"&gt;+&lt;/span&gt; (&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;) &lt;span style="color:#f92672"&gt;*&lt;/span&gt; math&lt;span style="color:#f92672"&gt;.&lt;/span&gt;exp((&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0.2&lt;/span&gt;) &lt;span style="color:#f92672"&gt;*&lt;/span&gt; (x[i] &lt;span style="color:#f92672"&gt;**&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; x[i&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;] &lt;span style="color:#f92672"&gt;**&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;) &lt;span style="color:#f92672"&gt;**&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.5&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(poplength):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; f[&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; abs(x[i]) &lt;span style="color:#f92672"&gt;**&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.8&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; math&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sin(x[i] &lt;span style="color:#f92672"&gt;**&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; f&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 轮盘赌函数&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;RouletteWheelSelection&lt;/span&gt;(P):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; idx &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;argsort(P)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; val &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sort(P)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; prob &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [_&lt;span style="color:#f92672"&gt;/&lt;/span&gt;sum(P) &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; _ &lt;span style="color:#f92672"&gt;in&lt;/span&gt; val] &lt;span style="color:#75715e"&gt;# 概率&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dprob &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;cumsum(prob) &lt;span style="color:#75715e"&gt;# 累积概率&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; seed &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random() &lt;span style="color:#75715e"&gt;# 随机数&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; res &lt;span style="color:#f92672"&gt;=&lt;/span&gt; idx[(dprob&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;seed)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;tolist()&lt;span style="color:#f92672"&gt;.&lt;/span&gt;index(&lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;)] &lt;span style="color:#75715e"&gt;# 选择&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; res&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="mopso"&gt;MOPSO&lt;/h4&gt;&#10;&lt;p&gt;参考了&lt;a href="https://yarpiz.com/59/ypea121-mopso"&gt;Matlab实现&lt;/a&gt;&lt;/p&gt;</description></item><item><title>启发式优化算法学习-模拟退火</title><link>https://lishengxie.top/post/algorithm-study-sa/</link><pubDate>Sun, 30 Apr 2023 08:44:23 +0800</pubDate><guid>https://lishengxie.top/post/algorithm-study-sa/</guid><description>&lt;h2 id="模拟退火算法sa"&gt;模拟退火算法(SA)&lt;/h2&gt;&#10;&lt;p&gt;参考教程 &lt;a href="https://blog.csdn.net/brilliantZC/article/details/124436967"&gt;https://blog.csdn.net/brilliantZC/article/details/124436967&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;模拟退火算法（Simulated Annealing，SA）是一种模拟物理退火过程而设计的优化算法。模拟退火算法采用类似于物理退火的过程。先在一个高温状态下（算法初始化随机解），然后逐渐退火，在每个温度下慢慢冷却，最终达到物理基态（相当于算法找到最优解）。模拟退火算法采用Metropolis准则，并用一组称为冷却进度表的参数控制算法的进程，使得算法在多项式时间里可以给出一个近似最优解。&lt;/p&gt;&#10;&lt;h3 id="sa算法运行流程"&gt;SA算法运行流程&lt;/h3&gt;&#10;&lt;p&gt;step1: 设定当前解（即为当前的最优解)：令\(T =T_0\)，即开始退火的初始温度，随机生成一个初始解\(x_0\)，并计算相应的目标函数值\(E(x_0)\)。&#10;step2: 产生新解与当前解差值：根据当前解\(x_i\)进行扰动，产生一个新解\(x_j\)，计算相应的目标函数值\(E(x_j)\)，得到\(\Delta E = E(x_j)-E(x_i)\)。&#10;step3: 判断新解是否被接受 ：若\(\Delta E&amp;lt; 0\)，则新解\(x_j\)被接受；若\(\Delta E&amp;gt; 0 \)，则新解\(x_j\)按概率\(e^{\frac{-(E(x_j)-E(x_i))}{T_i}}\)被接受，\(T_i\)为当前温度。&#10;step4: 当新解被确定接受时，新解\(x_j\)被作为当前解。&#10;step5: 循环以上四个步骤：在温度\(T_i\)下，重复\(k\)次的扰动和接受过程，接着执行下一步骤。&#10;step6: 最后找到全局最优解：判断\(T\)是否已经达到终止温度\(T_f\)，是，则终止算法；否，则转到循环步骤继续执行。&lt;/p&gt;&#10;&lt;h3 id="sa算法求解映射问题"&gt;SA算法求解映射问题&lt;/h3&gt;&#10;&lt;p&gt;映射问题本质上可以看作一个序列的排序问题，使用SA算法求解时，需要关注的是如何产生新解，这里我们采用如下的方法：再序列中随机选取两个不重合的位置，将这两个位置中间的序列反转达到局部扰动的目的。&lt;/p&gt;&#10;&lt;h3 id="sa算法求解映射问题代码"&gt;SA算法求解映射问题代码&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# -*- coding: utf-8 -*-&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Lishengxie&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 2023-02-23&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Implementation of a Simulated Annealing algorithm for crossbar mapping/placing&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 参考链接: https://blog.csdn.net/weixin_58427214/article/details/125901431&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 参考链接: https://blog.csdn.net/brilliantZC/article/details/124436967&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; numpy &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; np&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; copy&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; sys&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; random&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;SAPlacer&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; SA algorithm&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; -------------&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Class used to find the mapping from computing cores to routers on NoC which minizes the communication cost&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;__init__&lt;/span&gt;(self, dim_x, dim_y, spike_table, L&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;200&lt;/span&gt;, K&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0.95&lt;/span&gt;, S&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0.04&lt;/span&gt;, T&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;, T_threshold&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0.01&lt;/span&gt;):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Initialization of PsoPlacer.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Args:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; dim_x: int, the `x` dimension on NoC &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; dim_y: int, the `y` dimension on NoC &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; spike_table: 2D-array, the number of spikes between core `i` and core `j`&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; L: int, 每个温度下的迭代次数&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; K: float, 温度的衰减参数, T = K*T&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; S: float, 步长因子&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; T: float, 初始温度&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; T_threshold: float, 终止温度&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; dim_x&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_y &lt;span style="color:#f92672"&gt;=&lt;/span&gt; dim_y&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size &lt;span style="color:#f92672"&gt;=&lt;/span&gt; dim_x &lt;span style="color:#f92672"&gt;*&lt;/span&gt; dim_y&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;L &lt;span style="color:#f92672"&gt;=&lt;/span&gt; L&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;K &lt;span style="color:#f92672"&gt;=&lt;/span&gt; K&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;S &lt;span style="color:#f92672"&gt;=&lt;/span&gt; S&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;T &lt;span style="color:#f92672"&gt;=&lt;/span&gt; T&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;T_threshold &lt;span style="color:#f92672"&gt;=&lt;/span&gt; T_threshold&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; spike_table &lt;span style="color:#f92672"&gt;is&lt;/span&gt; &lt;span style="color:#f92672"&gt;not&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;init_solution(spike_table)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;init_solution&lt;/span&gt;(self, spike_table):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Init spike table, hop distance table and solution.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# init spike table&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;spike_table &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;zeros((self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; h, w &lt;span style="color:#f92672"&gt;=&lt;/span&gt; spike_table&lt;span style="color:#f92672"&gt;.&lt;/span&gt;shape&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(h):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; j &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(w):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;spike_table[i,j] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; spike_table[i,j]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# init hop distance table&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;hop_xy()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# init solution&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pre_x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;arange(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;shuffle(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pre_x)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pre_bestx &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pre_x&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pre_x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;arange(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;shuffle(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pre_x)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;prex_cost &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;fitnessFuntcion(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pre_x)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;bestx &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pre_x&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;bestx_cost &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;fitnessFuntcion(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;bestx)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;hop_xy&lt;/span&gt;(self):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; The hop distance between router `x` and `y` in the 2D-Mesh NoC using XY routing&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;hop_dist &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;zeros((self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; j &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;hop_dist[i,j] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; abs(i &lt;span style="color:#f92672"&gt;%&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_x &lt;span style="color:#f92672"&gt;-&lt;/span&gt; j &lt;span style="color:#f92672"&gt;%&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_x) \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; abs(i &lt;span style="color:#f92672"&gt;//&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_x &lt;span style="color:#f92672"&gt;-&lt;/span&gt; j &lt;span style="color:#f92672"&gt;//&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_x)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fitnessFuntcion&lt;/span&gt;(self, solution):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Compute the communication cost for each mapping solution&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Args:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; solution: List, a possible mapping solution&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cost &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; j &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cost &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;spike_table[i,j] &lt;span style="color:#f92672"&gt;*&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;hop_dist[solution[i], solution[j]]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; cost&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;place&lt;/span&gt;(self):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Execute the Simulated Annealing algorithm&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; P &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; next_x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;arange(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;shuffle(next_x)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; nextx_cost &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;fitnessFuntcion(next_x)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;T &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;T_threshold):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;T &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;K &lt;span style="color:#f92672"&gt;*&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;T &lt;span style="color:#75715e"&gt;# 降温&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 当前温度T下迭代次数&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;L):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# ====在此点附近随机选下一点=====&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 选择两个随机位置, 将两个位置之间的数组进行翻转&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; positions &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;choice(list(range(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size)), replace&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;False&lt;/span&gt;, size&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; min(positions[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;], positions[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;])&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; y &lt;span style="color:#f92672"&gt;=&lt;/span&gt; max(positions[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;], positions[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;])&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; mid_reversed &lt;span style="color:#f92672"&gt;=&lt;/span&gt; next_x[x:y&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;][::&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; next_x[x:y&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; mid_reversed&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random() &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.0001&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;shuffle(next_x)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; nextx_cost &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;fitnessFuntcion(next_x)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; nextx_cost &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;bestx_cost:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pre_bestx &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;bestx&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;bestx &lt;span style="color:#f92672"&gt;=&lt;/span&gt; next_x&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;bestx_cost &lt;span style="color:#f92672"&gt;=&lt;/span&gt; nextx_cost&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; nextx_cost &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;prex_cost:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pre_x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; next_x&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;prex_cost &lt;span style="color:#f92672"&gt;=&lt;/span&gt; nextx_cost&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; P &lt;span style="color:#f92672"&gt;=&lt;/span&gt; P &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; changer &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; (nextx_cost &lt;span style="color:#f92672"&gt;-&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;prex_cost) &lt;span style="color:#f92672"&gt;/&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;T&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; p1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;exp(changer)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; p1 &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random():&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pre_x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; next_x&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;prex_cost &lt;span style="color:#f92672"&gt;=&lt;/span&gt; nextx_cost&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; P &lt;span style="color:#f92672"&gt;=&lt;/span&gt; P &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#34;Current T: &lt;/span&gt;&lt;span style="color:#e6db74"&gt;{:.7f}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;, best cost: &lt;/span&gt;&lt;span style="color:#e6db74"&gt;{}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;format(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;T, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;bestx_cost))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;bestx&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>启发式优化算法学习-PSO</title><link>https://lishengxie.top/post/algorithm-study-pso/</link><pubDate>Sun, 30 Apr 2023 08:42:37 +0800</pubDate><guid>https://lishengxie.top/post/algorithm-study-pso/</guid><description>&lt;h2 id="粒子群算法pso"&gt;粒子群算法(PSO)&lt;/h2&gt;&#10;&lt;p&gt;参考教程：&lt;a href="https://cloud.tencent.com/developer/article/1424756"&gt;https://cloud.tencent.com/developer/article/1424756&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;粒子群算法是一种利用群体智能建立的一个简化模型，基于群体中个体对信息的共享使整个群体的运动趋向最优解。粒子群算法使用一群粒子，粒子拥有位置和速度两种属性，根据自身已经找到的最优解和参考整个共享于整个集群中找到的最优解去改变自己的飞行速度和位置。&lt;/p&gt;&#10;&lt;h3 id="粒子速度和位置"&gt;粒子速度和位置&lt;/h3&gt;&#10;&lt;p&gt;粒子群算法使用一定数量的粒子，粒子\(i\)在\(N\)维空间中的位置和速度表示为\(x_i=(x_1,x_2,\cdots,x_N)\) 和 \(v_i=(v_1,v_2,\cdots,v_N)\)。每个粒子都有一个目标函数决定的适应值(fitness value)，并且知道自己到目前为止发现的最好位置(pbest)和现在的位置\(x_i\)。这个可以看作是粒子自己的飞行经验。除此之外，每个粒子还知道到目前为止整个群体中所有粒子发现的最好位置(gbest)(gbest是pbest中的最好值)，这个可以看作是粒子同伴的经验。粒子就是通过自己的经验和同伴中最好的经验来决定下一步的运动。&lt;/p&gt;&#10;&lt;h3 id="粒子速度和位置更新公式"&gt;粒子速度和位置更新公式&lt;/h3&gt;&#10;&lt;p&gt;粒子群算法会给每个粒子一个初始的随机解，并通过迭代寻找最优解，迭代规则如下图所示：&#10;&lt;a href="https://lishengxie.top/uploads/2023/02/19.png"&gt;&lt;img src="https://lishengxie.top/uploads/2023/02/19.png" alt="PSO更新规则"&gt;&lt;/a&gt;&#10;迭代公式中的第一部分和第二部分分别反映了粒子对自身经验和群体经验的学习。基于上述公式还可以对当前的速度引入更新权重&#10;&lt;a href="https://lishengxie.top/uploads/2023/02/20.png"&gt;&lt;img src="https://lishengxie.top/uploads/2023/02/20.png" alt="PSO权重迭代"&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;h3 id="pso算法运行流程"&gt;PSO算法运行流程&lt;/h3&gt;&#10;&lt;p&gt;1）初始化一群微粒(群体规模为N)，包括随机位置和速度；&#10;2）评价每个微粒的适应度；&#10;3）对每个微粒，将其适应值与其经过的最好位置pbest作比较，如果较好，则将其作为当前的最好位置pbest；&#10;4）对每个微粒，将其适应值与其经过的最好位置gbest作比较，如果较好，则将其作为当前的最好位置gbest；&#10;5）根据公式(2)、(3)调整微粒速度和位置；&#10;6）未达到结束条件则转第2）步。&#10;迭代终止条件根据具体问题一般选为最大迭代次数Gk或(和)微粒群迄今为止搜索到的最优位置满足预定最小适应阈值。&lt;/p&gt;&#10;&lt;h3 id="pso算法求解映射问题"&gt;PSO算法求解映射问题&lt;/h3&gt;&#10;&lt;p&gt;映射问题本质上可以看作一个序列的排序问题，使用PSO算法求解映射问题时，粒子位置对应一个序列的排序。这里\(pbest-x_i^{t-1}\)对应将\(x_i^{t-1}\)转换成pbest所需要的交换序列，这里的迭代公式的含义变为对于原来的解序列\(x_i^{t-1}\)，&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;先按照\(c_2\)的概率使用\(pbest-x_i^{t-1}\)的交换序列对\(x_i^{t-1}\)进行交换获得\((x_i^{t-1})^{&amp;rsquo;}\)，&lt;/li&gt;&#10;&lt;li&gt;再按照\(c_3\)的概率使用\(gbest-(x_i^{t-1})^{&amp;rsquo;}\)的交换序列对\((x_i^{t-1})^{&amp;rsquo;}\)进行交换获得\(x_i^{t}\).&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="pso求解映射代码"&gt;PSO求解映射代码&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# -*- coding: utf-8 -*-&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Lishengxie&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 2023-02-19&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Implementation of a PSO algorithm for crossbar mapping/placing&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; numpy &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; np&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; copy&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; sys&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;PsoPlacer&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; PSO algorithm&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; -------------&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Class used to find the mapping from computing cores to routers on NoC which minizes the communication cost&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;__init__&lt;/span&gt;(self, dim_x, dim_y, spike_table, num_particle&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;50&lt;/span&gt;, s1&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt;, s2&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0.04&lt;/span&gt;, s3&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0.02&lt;/span&gt;):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Initialization of PsoPlacer.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Args:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; dim_x: int, the `x` dimension on NoC &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; dim_y: int, the `y` dimension on NoC &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; spike_table: 2D-array, the number of spikes between core `i` and core `j`&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; num_particle: int, number of particles in the PSO algorithm&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; dim_x&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_y &lt;span style="color:#f92672"&gt;=&lt;/span&gt; dim_y&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size &lt;span style="color:#f92672"&gt;=&lt;/span&gt; dim_x &lt;span style="color:#f92672"&gt;*&lt;/span&gt; dim_y&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;num_particle &lt;span style="color:#f92672"&gt;=&lt;/span&gt; num_particle&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;s1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; s1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;s2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; s2&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;s3 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; s3&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;init_particle(spike_table)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;init_particle&lt;/span&gt;(self, spike_table):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Init spike table, particles, local and global best solution&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Args:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; spike_table: 2D-array, the number of spikes between core `i` and core `j`&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# init the spike table, adding `0`s if the dimension of `spike_table` not equal to `dim_size`&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;spike_table &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;zeros((self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; h, w &lt;span style="color:#f92672"&gt;=&lt;/span&gt; spike_table&lt;span style="color:#f92672"&gt;.&lt;/span&gt;shape&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(h):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; j &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(w):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;spike_table[i,j] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; spike_table[i,j]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# init particle vectors with number of `num_particle`, each vector is a mappinng solution&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;solution &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;zeros((self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;num_particle, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size), dtype&lt;span style="color:#f92672"&gt;=&lt;/span&gt;np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;int32)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;num_particle):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;solution[i] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;arange(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;shuffle(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;solution[i])&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# init hop distance table&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;hop_xy()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# init the local/global best solution and their cost&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;local_best_solution &lt;span style="color:#f92672"&gt;=&lt;/span&gt; copy&lt;span style="color:#f92672"&gt;.&lt;/span&gt;deepcopy(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;solution)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;local_best_cost &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;zeros((self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;num_particle,))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;global_best_solution &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;arange(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;global_best_cost &lt;span style="color:#f92672"&gt;=&lt;/span&gt; sys&lt;span style="color:#f92672"&gt;.&lt;/span&gt;maxsize&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;num_particle):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;local_best_cost[i] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;fitnessFuntcion(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;local_best_solution[i])&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;local_best_cost[i] &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;global_best_cost:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;global_best_solution &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;local_best_solution[i]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;global_best_cost &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;local_best_cost[i]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#34;Init, gloabal best cost:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;format(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;global_best_cost))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;hop_xy&lt;/span&gt;(self):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; The hop distance between router `x` and `y` in the 2D-Mesh NoC using XY routing&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;hop_dist &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;zeros((self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; j &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;hop_dist[i,j] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; abs(i &lt;span style="color:#f92672"&gt;%&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_x &lt;span style="color:#f92672"&gt;-&lt;/span&gt; j &lt;span style="color:#f92672"&gt;%&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_x) \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; abs(i &lt;span style="color:#f92672"&gt;//&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_x &lt;span style="color:#f92672"&gt;-&lt;/span&gt; j &lt;span style="color:#f92672"&gt;//&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_x)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fitnessFuntcion&lt;/span&gt;(self, solution):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Compute the communication cost for each mapping solution&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Args:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; solution: List, a possible mapping solution&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cost &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; j &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cost &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;spike_table[i,j] &lt;span style="color:#f92672"&gt;*&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;hop_dist[solution[i], solution[j]]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; cost&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;compute_swap_sequence&lt;/span&gt;(self, src_seq, dst_seq, seq_len):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# TODO: Optimize this algorithm.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Find the swap sequence from source sequecne to destination sequence.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Args:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; src_seq: List, the source sequence&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; dst_seq: List, the destination sequence&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; seq_len: int, the length of source and destination sequence&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Return:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; swap_sequence: the index of each point for `src_seq` in `dst_seq`&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; swap_seq &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;zeros((seq_len,))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(seq_len):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; swap_seq[i] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;where(dst_seq &lt;span style="color:#f92672"&gt;==&lt;/span&gt; src_seq[i])[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; swap_seq&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;applySwap&lt;/span&gt;(self, swap_seq, src_seq, seq_len):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Apply swap sequence to the source sequence&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Args:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; src_seq: List, the source sequence&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; swap_sequence: the index of each point for `src_seq` in `dst_seq`&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; seq_len: int, the length of source and destination sequence&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Return:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; dst_seq: List, the destination sequence&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dst_seq &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;zeros((seq_len,))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(seq_len):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dst_seq[swap_seq[i]] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; src_seq[i]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; dst_seq&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;place&lt;/span&gt;(self, num_iter&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Funciton to execute pso algorithm.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Args:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; num_iter: int, max number of iterations to execute pso update&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Return:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; global best solution after `num_iter` iterations&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; iter &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(num_iter):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;num_particle):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tmp_solution &lt;span style="color:#f92672"&gt;=&lt;/span&gt; copy&lt;span style="color:#f92672"&gt;.&lt;/span&gt;deepcopy(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;solution[i])&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random() &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;s2:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# print(&amp;#34;local&amp;#34;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; swap_seq_local &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;compute_swap_sequence(tmp_solution, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;local_best_solution[i], self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;solution[i] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;applySwap(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;solution[i], swap_seq_local, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random() &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;s3:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# print(&amp;#34;global&amp;#34;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; swap_seq_global &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;compute_swap_sequence(tmp_solution, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;global_best_solution, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;solution[i] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;applySwap(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;solution[i], swap_seq_global, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dim_size)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random() &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.0001&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;shuffle(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;solution[i])&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cost &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;fitnessFuntcion(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;solution[i])&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; cost &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;local_best_cost[i]:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;local_best_cost[i] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; cost&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;local_best_solution[i] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; copy&lt;span style="color:#f92672"&gt;.&lt;/span&gt;deepcopy(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;solution[i])&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;local_best_cost[i] &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;global_best_cost:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;global_best_cost &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;local_best_cost[i]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;global_best_solution &lt;span style="color:#f92672"&gt;=&lt;/span&gt; copy&lt;span style="color:#f92672"&gt;.&lt;/span&gt;deepcopy(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;local_best_solution[i])&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#34;Iteration:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;, global best cost:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;format(iter, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;global_best_cost))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;global_best_solution&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Gdb调试学习</title><link>https://lishengxie.top/post/gdb-study/</link><pubDate>Sun, 30 Apr 2023 08:40:25 +0800</pubDate><guid>https://lishengxie.top/post/gdb-study/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;&#10;&lt;p&gt;使用linux进行systemc的开发时经常出现core dump的文件，对于较大的项目vscode无法很快地进行debug，clion对makefile的支持不是很好，此时想到使用gdb进行调试并学习了一些基本的操作。以下的内容主要参考这篇博客和gdb debug的参考文档。&lt;/p&gt;&#10;&lt;p&gt;参考资料：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;a href="https://www.yanbinghu.com/2019/04/20/41283.html"&gt;https://www.yanbinghu.com/2019/04/20/41283.html&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://www.eecs.umich.edu/courses/eecs373/readings/Debugger.pdf"&gt;Debugging with GDB&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="启动调试"&gt;启动调试&lt;/h2&gt;&#10;&lt;p&gt;GDB需要一个带有调试信息的可执行文件进行调试，因此编译过程中出现的错误无法使用GDB进行排除。通常对于C或者C++程序来说，在编译时加上&lt;code&gt;-g&lt;/code&gt;参数可以保留调试信息，否则不能使用GDB进行调试。使用cmake时，可以在&lt;code&gt;CMakeLists.txt&lt;/code&gt;文件中添加以下指令以支持GDB调试。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cmake" data-lang="cmake"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;SET(&lt;span style="color:#e6db74"&gt;CMAKE_BUILD_TYPE&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Debug&amp;#34;&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;SET(&lt;span style="color:#e6db74"&gt;CMAKE_CXX_FLAGS_DEBUG&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb&amp;#34;&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;SET(&lt;span style="color:#e6db74"&gt;CMAKE_CXX_FLAGS_RELEASE&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;$ENV{CXXFLAGS} -O3 -Wall&amp;#34;&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果程序不是自己编译的，那么如何判断文件中是否带有调试信息呢，这篇&lt;a href="https://www.yanbinghu.com/2019/04/20/41283.html"&gt;博客&lt;/a&gt;中给出了几种调试的方法。&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;使用gdb&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ gdb main&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Reading symbols from main...&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果提示no debugging symbols found, 那么不可以使用gdb调试该可执行文件。&#10;2. readelf&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# main是可执行文件名称&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ readelf -S main | grep debug&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="3"&gt;&#10;&lt;li&gt;file查看strip状况&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ file main&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果输出内容为xxx stripped, 那么说明该文件的调试信息已经被去除，不能使用gdb调试。但是not stripped的情况不能说明该文件可以被调试。&lt;/p&gt;&#10;&lt;h2 id="启动调试-1"&gt;启动调试&lt;/h2&gt;&#10;&lt;h3 id="无参数程序"&gt;无参数程序&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ gdb main&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;(&lt;/span&gt;gdb&lt;span style="color:#f92672"&gt;)&lt;/span&gt; run&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;输入run命令即可运行程序。&lt;/p&gt;</description></item><item><title>Makefile使用学习</title><link>https://lishengxie.top/post/makefile-study/</link><pubDate>Sun, 30 Apr 2023 08:37:37 +0800</pubDate><guid>https://lishengxie.top/post/makefile-study/</guid><description>&lt;h2 id="参考教程"&gt;参考教程&lt;/h2&gt;&#10;&lt;p&gt;原文：&lt;a href="https://makefiletutorial.com/"&gt;https://makefiletutorial.com/&lt;/a&gt;&#10;中文翻译：&lt;a href="https://makefiletutorial.vercel.app"&gt;https://makefiletutorial.vercel.app&lt;/a&gt;&lt;/p&gt;&#10;&lt;h2 id="makefile常用内容"&gt;Makefile常用内容&lt;/h2&gt;&#10;&lt;p&gt;本文主要基于以上教程记录一些平时阅读&lt;code&gt;Makefile&lt;/code&gt;可能会用到的信息。&lt;/p&gt;&#10;&lt;h3 id="makefile基础使用"&gt;Makefile基础使用&lt;/h3&gt;&#10;&lt;p&gt;首先，Makefile用于帮助决定一个大型程序的哪些部分需要重新编译，如果有任何文件的依赖项发生改变，那么该文件将会重新编译。Makefile通常由一组规则组成，规则通常如下所示：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-makefile" data-lang="makefile"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;target&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; prerequisites&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;command&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;command&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;command&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;target&lt;/code&gt;是文件名，以空格分隔，通常每个规则只有一个。&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;command&lt;/code&gt;通常是用于制作目标的一系列步骤，需要以制表符&lt;code&gt;Tab&lt;/code&gt;而不是空格开头。&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;prerequisites&lt;/code&gt;也是文件名，称为依赖项，以空格分隔，在运行针对目标的命令之前，这些文件需要存在。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;下面是一个&lt;code&gt;Makefile&lt;/code&gt;的实例：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-makefile" data-lang="makefile"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;blah&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; blah.o&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;gcc blah.o -o blah &lt;span style="color:#75715e"&gt;# Runs third&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;blah.o&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; blah.c&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;gcc -c blah.c -o blah.o &lt;span style="color:#75715e"&gt;# Runs second&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Typically blah.c would already exist, but I want to limit any additional required files&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;blah.c&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;echo &lt;span style="color:#e6db74"&gt;&amp;#34;int main() { return 0; }&amp;#34;&lt;/span&gt; &amp;gt; blah.c &lt;span style="color:#75715e"&gt;# Runs first&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;使用&lt;code&gt;make&lt;/code&gt;时默认会执行第一个目标&lt;code&gt;blah&lt;/code&gt;，或者可以指定目标进行生成&lt;code&gt;make blah&lt;/code&gt;。上面的Makefile在执行&lt;code&gt;make&lt;/code&gt;指令后按照一系列步骤进行调用：&lt;/p&gt;</description></item><item><title>Cmake 常用指令学习</title><link>https://lishengxie.top/post/cmake-study/</link><pubDate>Sun, 30 Apr 2023 08:36:41 +0800</pubDate><guid>https://lishengxie.top/post/cmake-study/</guid><description>&lt;h2 id="参考教程"&gt;参考教程&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Cmake Cookbook:&lt;a href="https://www.bookstack.cn/read/CMake-Cookbook/README.md"&gt;https://www.bookstack.cn/read/CMake-Cookbook/README.md&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;Cmake官方文档:&lt;a href="https://cmake.org/cmake/help/latest/guide/tutorial/index.html"&gt;https://cmake.org/cmake/help/latest/guide/tutorial/index.html&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;Cmake入门实战: &lt;a href="https://www.hahack.com/codes/cmake/"&gt;https://www.hahack.com/codes/cmake/&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;CMake 生成静态库与动态库：&lt;a href="https://blog.csdn.net/zhiyuan2021/article/details/129032343"&gt;https://blog.csdn.net/zhiyuan2021/article/details/129032343&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="cmake介绍"&gt;Cmake介绍&lt;/h2&gt;&#10;&lt;p&gt;Cmake是一种支持跨平台编译的工具，允许通过配置独立的配置文件&lt;code&gt;CMakeList.txt&lt;/code&gt;来定制编译流程，随后在不同的平台上进一步生成本地的&lt;code&gt;Makefile&lt;/code&gt;和工程文件(Linux平台的&lt;code&gt;Makefile&lt;/code&gt;和Windows平台的&lt;code&gt;Visual Studio&lt;/code&gt;工程等)。在linux平台下使用Cmake编译程序的主要流程是：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;编写CMakeLists.txt；&lt;/li&gt;&#10;&lt;li&gt;执行&lt;code&gt;cmake PATH&lt;/code&gt;生成&lt;code&gt;Makefile&lt;/code&gt;；&lt;/li&gt;&#10;&lt;li&gt;执行&lt;code&gt;make&lt;/code&gt;编译生成可执行程序或动态/静态链接库。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="cmake使用"&gt;Cmake使用&lt;/h2&gt;&#10;&lt;h3 id="基础案例"&gt;基础案例&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cmake" data-lang="cmake"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# CMake 最低版本号要求&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cmake_minimum_required (&lt;span style="color:#e6db74"&gt;VERSION&lt;/span&gt; &lt;span style="color:#e6db74"&gt;2.8&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 项目信息&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;project (&lt;span style="color:#e6db74"&gt;project_name&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 指定生成目标&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;add_executable(&lt;span style="color:#e6db74"&gt;project_name&lt;/span&gt; &lt;span style="color:#e6db74"&gt;main.cc&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;CMakeLists.txt&lt;/code&gt;的语法由命令、注释和空格组成，命令不区分大小写，&lt;code&gt;#&lt;/code&gt;后面的内容是注释。命令由命令名称、小括号和参数组成，参数之间使用空格进行间隔。上面的示例中&lt;code&gt;CmakeLists.txt&lt;/code&gt;中使用了几个常用的命令，依次是&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;code&gt;cmake_minimum_required&lt;/code&gt;：指定运行当前配置文件需要的最低的Cmake版本；&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;project&lt;/code&gt;：指定项目名称&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;add_executable&lt;/code&gt;：将&lt;code&gt;main.cc&lt;/code&gt;源文件编译成名为&lt;code&gt;project_name&lt;/code&gt;的可执行文件。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;实际使用中可能有多个源文件，逐个添加源文件是一件非常麻烦的事情，可以使用&lt;code&gt;aux_source_directory&lt;/code&gt;命令来获取指定目录下的所有源文件，并将结果存到指定变量名中，使用示例如下：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cmake" data-lang="cmake"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 查找当前目录下的所有源文件&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 并将名称保存到 DIR_SRCS 变量&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;aux_source_directory(&lt;span style="color:#e6db74"&gt;.&lt;/span&gt; &lt;span style="color:#e6db74"&gt;DIR_SRCS&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 指定生成目标&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;add_executable(&lt;span style="color:#e6db74"&gt;Demo&lt;/span&gt; &lt;span style="color:#f92672"&gt;${&lt;/span&gt;DIR_SRCS&lt;span style="color:#f92672"&gt;}&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="cmake生成动态和静态链接库"&gt;Cmake生成动态和静态链接库&lt;/h3&gt;&#10;&lt;p&gt;静态和动态链接库的主要目的是为了提供接口供其他程序调用，两者的主要区别在于：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;静态链接库的拓展名通常为&lt;code&gt;.a&lt;/code&gt;或&lt;code&gt;.lib&lt;/code&gt;，在编译时会直接整合到目标程序中，编译成功的可执行文件可以独立运行（不再需要静态库）；&lt;/li&gt;&#10;&lt;li&gt;动态链接库的拓展名通常为&lt;code&gt;.so&lt;/code&gt;或&lt;code&gt;.dll&lt;/code&gt;，在编译时不会放到目标程序中，可执行文件无法离开动态链接库单独执行。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;Cmake用于生成动态和静态链接库的命令为&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cmake" data-lang="cmake"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 动态链接库&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;add_library(&lt;span style="color:#e6db74"&gt;project_name&lt;/span&gt; &lt;span style="color:#e6db74"&gt;SHARED&lt;/span&gt; &lt;span style="color:#f92672"&gt;${&lt;/span&gt;SRC_FILE&lt;span style="color:#f92672"&gt;}&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 静态链接库&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;add_library(&lt;span style="color:#e6db74"&gt;project_name&lt;/span&gt; &lt;span style="color:#e6db74"&gt;STATIC&lt;/span&gt; &lt;span style="color:#f92672"&gt;${&lt;/span&gt;SRC_FILE&lt;span style="color:#f92672"&gt;}&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="cmake引用外部库文件"&gt;Cmake引用外部库文件&lt;/h3&gt;&#10;&lt;p&gt;Cmake中另外一个常用的使用场景是使用外部库，对于外部库，我们通常需要进行两步操作，即引入头文件和添加链接库，具体示例如下所示：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cmake" data-lang="cmake"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 引入头文件所在路径&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;include_directories{include_path}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 添加链接库&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;target_link_libraries(&lt;span style="color:#e6db74"&gt;project_name&lt;/span&gt; &lt;span style="color:#e6db74"&gt;lib_name&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="其他常见的cmkae命令"&gt;其他常见的Cmkae命令&lt;/h2&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cmake" data-lang="cmake"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 设置C++标准为C++14&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;set(&lt;span style="color:#e6db74"&gt;CMAKE_CXX_STANDARD&lt;/span&gt; &lt;span style="color:#e6db74"&gt;14&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Snn &amp; NoC 仿真器收集</title><link>https://lishengxie.top/post/snn-simulator/</link><pubDate>Sun, 30 Apr 2023 08:33:39 +0800</pubDate><guid>https://lishengxie.top/post/snn-simulator/</guid><description>&lt;h2 id="noc仿真器"&gt;NoC仿真器&lt;/h2&gt;&#10;&lt;p&gt;NoC(Network on chip)是连接同构或者异构多核心的重要的系统互联结构，NoC仿真器提供了对NoC中多种性能指标的仿真。下面这篇博客中列出了常用的开源NoC仿真器，&lt;a href="https://networkonchip.wordpress.com/2011/02/22/simulators/"&gt;https://networkonchip.wordpress.com/2011/02/22/simulators/&lt;/a&gt; ，目前了解到最常用的两种分别是&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;noxim，基于SystemC语言开发，修改和添加新功能较为灵活。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;开源地址：&lt;a href="https://github.com/davidepatti/noxim"&gt;https://github.com/davidepatti/noxim&lt;/a&gt;&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;ol start="2"&gt;&#10;&lt;li&gt;booksim，基于C++语言开发，是 &lt;a href="http://cva.stanford.edu/books/ppin/"&gt;Principles and Practices of Interconnection Networks&lt;/a&gt; 这本书的配套教程。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;开源地址：&lt;a href="https://github.com/booksim/booksim"&gt;https://github.com/booksim/booksim&lt;/a&gt;，&lt;a href="https://github.com/booksim/booksim2"&gt;https://github.com/booksim/booksim2&lt;/a&gt;&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;h2 id="snn仿真器"&gt;SNN仿真器&lt;/h2&gt;&#10;&lt;p&gt;SNN是第三代人工神经网络，基于脉冲传递数据和信息，由于SNN本身具有稀疏性（连接稀疏性和脉冲稀疏性），因此有许多神经形态硬件（Loihi、SpiNNaker、TianjiC、Darwin等）被开发出来用于SNN加速。这里主要列出一些在通用的CPU和GPU平台上进行SNN加速的一些SNN仿真器。&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;NEST，可以用于SNN网络信息处理，网络活动动态、学习和突触可塑性等&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;开源地址：&lt;a href="https://github.com/nest/nest-simulator/"&gt;https://github.com/nest/nest-simulator/&lt;/a&gt;&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;ol start="2"&gt;&#10;&lt;li&gt;Brain2，时钟驱动的SNN仿真器&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;开源地址：&lt;a href="https://github.com/brian-team/brian2"&gt;https://github.com/brian-team/brian2&lt;/a&gt;&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;ol start="3"&gt;&#10;&lt;li&gt;GeNN，GPU加速的SNN仿真器&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;开源地址：&lt;a href="https://github.com/genn-team/genn"&gt;https://github.com/genn-team/genn&lt;/a&gt;&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;ol start="4"&gt;&#10;&lt;li&gt;Carlsim，GPU加速的SNN仿真器&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;开源地址：&lt;a href="https://github.com/UCI-CARL/CARLsim6"&gt;https://github.com/UCI-CARL/CARLsim6&lt;/a&gt;&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;ol start="5"&gt;&#10;&lt;li&gt;Auryn，RSNN仿真器&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;开源地址：&lt;a href="https://github.com/fzenke/auryn"&gt;https://github.com/fzenke/auryn&lt;/a&gt;&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;ol start="6"&gt;&#10;&lt;li&gt;ANNarchy&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;开源地址：&lt;a href="https://github.com/ANNarchy/ANNarchy"&gt;https://github.com/ANNarchy/ANNarchy&lt;/a&gt;&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;ol start="7"&gt;&#10;&lt;li&gt;Spike， GPU加速的SNN仿真器&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;开源地址：&lt;a href="https://github.com/nasiryahm/Spike"&gt;https://github.com/nasiryahm/Spike&lt;/a&gt;&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;ol start="8"&gt;&#10;&lt;li&gt;Spice，多GPU、时钟驱动的SNN仿真器&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;开源地址：&lt;a href="https://github.com/denniskb/spice"&gt;https://github.com/denniskb/spice&lt;/a&gt;&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;ol start="9"&gt;&#10;&lt;li&gt;Nengo，基于Python的神经网络仿真&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;开源地址：&lt;a href="https://github.com/nengo/nengo"&gt;https://github.com/nengo/nengo&lt;/a&gt;&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;ol start="10"&gt;&#10;&lt;li&gt;Brain2Loihi，基于brain2实现的Loihi模拟器&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;开源地址：https://github.com/sagacitysite/brian2_loihi&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;ol start="11"&gt;&#10;&lt;li&gt;NeuroSync&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;开源地址：&lt;a href="https://github.com/SNU-HPCS/NeuroSync"&gt;https://github.com/SNU-HPCS/NeuroSync&lt;/a&gt;&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;ol start="12"&gt;&#10;&lt;li&gt;dynapse-simulator，Dynap-SE1神经形态硬件仿真器&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;开源地址：&lt;a href="https://github.com/YigitDemirag/dynapse-simulator"&gt;https://github.com/YigitDemirag/dynapse-simulator&lt;/a&gt;&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;ol start="13"&gt;&#10;&lt;li&gt;待添加&lt;/li&gt;&#10;&lt;/ol&gt;</description></item><item><title>Verilog Note</title><link>https://lishengxie.top/post/verilog-note/</link><pubDate>Sun, 30 Apr 2023 08:30:15 +0800</pubDate><guid>https://lishengxie.top/post/verilog-note/</guid><description>&lt;h3 id="参考书籍"&gt;参考书籍：&lt;/h3&gt;&#10;&lt;p&gt;《手把手教你学FPGA设计：基于大道至简的至简设计法》&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;百度网盘链接：https://pan.baidu.com/s/12knuxzb4Z6z_8gR-By-l-A&#10;提取码：mwzd&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;自己实现的书中的模块和相应的testbench测试：&lt;a href="https://github.com/lishengxie/verilog-learning.git"&gt;https://github.com/lishengxie/verilog-learning.git&lt;/a&gt;&lt;/p&gt;&#10;&lt;h3 id="计数器"&gt;计数器&lt;/h3&gt;&#10;&lt;h4 id="设计规则"&gt;设计规则&lt;/h4&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;计数器需要考虑三要素：初值、加一条件和结束值（通常依次考虑）；&lt;/li&gt;&#10;&lt;li&gt;计数初值必须为0；&lt;/li&gt;&#10;&lt;li&gt;使用某个计数值时必须同时满足加1条件；例如加1条件为&lt;code&gt;add_cnt&lt;/code&gt;且&lt;code&gt;add_cnt &amp;amp;&amp;amp; cnt==4&lt;/code&gt;时表示计数到第五个，而&lt;code&gt;add_cnt==0 &amp;amp;&amp;amp; cnt==4&lt;/code&gt;不表示计数到第五个；&lt;/li&gt;&#10;&lt;li&gt;计数条件必须&lt;strong&gt;同时满足加一条件&lt;/strong&gt;，且结束值必须是&lt;code&gt;x-1&lt;/code&gt;的形式；&lt;/li&gt;&#10;&lt;li&gt;当从计数器取某个数时，assign形式必须为：&lt;code&gt;(加一条件) &amp;amp;&amp;amp; (cnt==计数值-1)&lt;/code&gt;；&lt;/li&gt;&#10;&lt;li&gt;结束后计数值需要回到0；&lt;/li&gt;&#10;&lt;li&gt;需要限定范围时，推荐使用&lt;code&gt;&amp;gt;=&lt;/code&gt;和&lt;code&gt;&amp;lt;&lt;/code&gt;两种符号，尽量不要使用大于或者小于等于两种符号；&lt;/li&gt;&#10;&lt;li&gt;计数器设计时，先写计数器的always段，条件用名字代替，随后使用assign语句依次写出加一条件和结束条件；由此可以得出计数器的模板写法如下所示&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-verilog" data-lang="verilog"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 中文词语方便理解，实际使用需要更改为相应的变量名&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;always&lt;/span&gt; @(&lt;span style="color:#66d9ef"&gt;posedge&lt;/span&gt; clk &lt;span style="color:#66d9ef"&gt;or&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;negedge&lt;/span&gt; rst_n) &lt;span style="color:#66d9ef"&gt;begin&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(rst_n&lt;span style="color:#f92672"&gt;==&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;&amp;#39;b0&lt;/span&gt;)&lt;span style="color:#66d9ef"&gt;begin&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cnt &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#960050;background-color:#1e0010"&gt;加一条件&lt;/span&gt;)&lt;span style="color:#66d9ef"&gt;begin&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#960050;background-color:#1e0010"&gt;结束条件&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cnt &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cnt &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; cnt &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;assign&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;加一条件&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; xxxxxx;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;assign&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;结束条件&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#960050;background-color:#1e0010"&gt;加一条件&lt;/span&gt;) &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; (cnt&lt;span style="color:#f92672"&gt;==&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;计数值&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="9"&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;加一条件必须与计数器严格对齐，其他信号一律向计数器对齐；例如，现在需要输出两个信号&lt;code&gt;dout0&lt;/code&gt;和&lt;code&gt;dout1&lt;/code&gt;，&lt;code&gt;dout0&lt;/code&gt;在计数到6时拉高，&lt;code&gt;dout1&lt;/code&gt;在计数到7时拉高，因此&lt;code&gt;dout0&lt;/code&gt;变1的条件为&lt;code&gt;add_cnt &amp;amp;&amp;amp; cnt==6-1&lt;/code&gt;，&lt;code&gt;dout1&lt;/code&gt;变1的条件有两种写法&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;dout0 == 1&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;add_cnt &amp;amp;&amp;amp; cnt==7-1&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;第一种写法是间接向计数器对齐，是非常不好的方法，建议使用第二种直接向计数器对齐；&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;加一条件统一前缀为&lt;code&gt;add_&lt;/code&gt;，结束条件统一前缀为&lt;code&gt;end_&lt;/code&gt;；&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;暂不使用减1计数器。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h3 id="状态机"&gt;状态机&lt;/h3&gt;&#10;&lt;h4 id="设计规则-1"&gt;设计规则&lt;/h4&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;使用四段式写法&#10;第一段为同步时序的always模块，用于格式化描述次态迁移到现态寄存器；&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-verilog" data-lang="verilog"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;always&lt;/span&gt; @(&lt;span style="color:#66d9ef"&gt;posedge&lt;/span&gt; clk &lt;span style="color:#66d9ef"&gt;or&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;negedge&lt;/span&gt; rst_n) &lt;span style="color:#66d9ef"&gt;begin&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#f92672"&gt;!&lt;/span&gt;rst_n) &lt;span style="color:#66d9ef"&gt;begin&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;state_c &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; IDLE;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;begin&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;state_c &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; state_n;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;第二段为组合逻辑的always块，用于描述状态转移条件判断，以三个状态的状态机IDLE-&amp;gt;S1-&amp;gt;S2-&amp;gt;IDLE为例；&lt;/p&gt;</description></item><item><title>Gin框架学习</title><link>https://lishengxie.top/post/go-study/</link><pubDate>Sun, 30 Apr 2023 08:26:45 +0800</pubDate><guid>https://lishengxie.top/post/go-study/</guid><description>&lt;h2 id="概述"&gt;概述&lt;/h2&gt;&#10;&lt;p&gt;&lt;strong&gt;Gin框架地址&lt;/strong&gt;：https://github.com/gin-gonic/gin&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;参考文档&lt;/strong&gt;：&#10;&lt;a href="https://www.kancloud.cn/shuangdeyu/gin_book"&gt;https://www.kancloud.cn/shuangdeyu/gin_book&lt;/a&gt;&#10;&lt;a href="https://github.com/piexlmax/1010class"&gt;https://github.com/piexlmax/1010class&lt;/a&gt;&lt;/p&gt;&#10;&lt;h2 id="gin服务入门"&gt;Gin服务入门&lt;/h2&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;github.com/gin-gonic/gin&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#a6e22e"&gt;r&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;gin&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Default&lt;/span&gt;()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#a6e22e"&gt;r&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;GET&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/ping&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;func&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;gin&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Context&lt;/span&gt;) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;JSON&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;200&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;gin&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;H&lt;/span&gt;{&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&#9;&lt;span style="color:#e6db74"&gt;&amp;#34;message&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;pong&amp;#34;&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;})&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;})&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#a6e22e"&gt;r&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Run&lt;/span&gt;() &lt;span style="color:#75715e"&gt;// listen and serve on 0.0.0.0:8080&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="gin获取getpost参数"&gt;Gin获取Get/Post参数&lt;/h2&gt;&#10;&lt;h3 id="获取get参数"&gt;获取Get参数&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#a6e22e"&gt;router&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;gin&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Default&lt;/span&gt;()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#75715e"&gt;// 匹配的url格式: /welcome?firstname=Jane&amp;amp;lastname=Doe&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#a6e22e"&gt;router&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;GET&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/welcome&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;func&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;gin&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Context&lt;/span&gt;) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&lt;span style="color:#a6e22e"&gt;firstname&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;DefaultQuery&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;firstname&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;Guest&amp;#34;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// DefaultQuery可以在参数值不存在时使用传入的默认值&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&lt;span style="color:#a6e22e"&gt;lastname&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Query&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;lastname&amp;#34;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// 是 c.Request.URL.Query().Get(&amp;#34;lastname&amp;#34;) 的简写&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;String&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;StatusOK&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;Hello %s %s&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;firstname&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;lastname&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;})&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#a6e22e"&gt;router&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Run&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;:8080&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="获取post参数"&gt;获取Post参数&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#a6e22e"&gt;router&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;gin&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Default&lt;/span&gt;()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#a6e22e"&gt;router&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;POST&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/form_post&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;func&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;gin&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Context&lt;/span&gt;) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&lt;span style="color:#a6e22e"&gt;message&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;PostForm&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;message&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&lt;span style="color:#a6e22e"&gt;nick&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;DefaultPostForm&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;nick&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;anonymous&amp;#34;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// 此方法可以设置默认值&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;JSON&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;200&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;gin&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;H&lt;/span&gt;{&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&#9;&lt;span style="color:#e6db74"&gt;&amp;#34;status&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;posted&amp;#34;&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&#9;&lt;span style="color:#e6db74"&gt;&amp;#34;message&amp;#34;&lt;/span&gt;: &lt;span style="color:#a6e22e"&gt;message&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&#9;&lt;span style="color:#e6db74"&gt;&amp;#34;nick&amp;#34;&lt;/span&gt;: &lt;span style="color:#a6e22e"&gt;nick&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;})&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;})&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#a6e22e"&gt;router&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Run&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;:8080&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="get和post参数混合使用"&gt;Get和Post参数混合使用&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#a6e22e"&gt;router&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;gin&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Default&lt;/span&gt;()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#a6e22e"&gt;router&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;POST&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/post&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;func&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;gin&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Context&lt;/span&gt;) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&lt;span style="color:#a6e22e"&gt;id&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Query&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&lt;span style="color:#a6e22e"&gt;page&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;DefaultQuery&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;page&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;0&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;PostForm&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&lt;span style="color:#a6e22e"&gt;message&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;PostForm&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;message&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;id: %s; page: %s; name: %s; message: %s&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;page&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;message&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;})&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#a6e22e"&gt;router&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Run&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;:8080&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;&#10;&lt;p&gt;请求示例：&lt;/p&gt;&#10;&lt;/blockquote&gt;</description></item><item><title>Go Gin Chat</title><link>https://lishengxie.top/post/go-gin-chat/</link><pubDate>Sun, 30 Apr 2023 08:22:37 +0800</pubDate><guid>https://lishengxie.top/post/go-gin-chat/</guid><description>&lt;p&gt;项目地址：https://github.com/hezhizheng/go-gin-chat&lt;/p&gt;&#10;&lt;h2 id="gin框架学习"&gt;Gin框架学习&lt;/h2&gt;&#10;&lt;p&gt;参考&lt;a href="https://www.lishengxie.top/gin%e6%a1%86%e6%9e%b6%e5%ad%a6%e4%b9%a0/"&gt;笔记&lt;/a&gt;&lt;/p&gt;&#10;&lt;h2 id="websocket学习"&gt;Websocket学习&lt;/h2&gt;&#10;&lt;p&gt;Websocket连接是升级的HTTP连接，在连接被客户端或服务器终止之前一直存在，基于Websocket可以实现客户端和服务端之间的双工通信，而不需要对HTTP端口进行持续轮询，大大节省了网络资源开销。&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;go-gin-chat&lt;/code&gt;中基于&lt;code&gt;gorilla/websocket&lt;/code&gt;实现websocket的使用，下面是该软件包使用的示例，可以参考&lt;a href="https://zhuanlan.zhihu.com/p/455635795"&gt;博客&lt;/a&gt;。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// We&amp;#39;ll need to define an Upgrader&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// this will require a Read and Write buffer size&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;upgrader&lt;/span&gt; = &lt;span style="color:#a6e22e"&gt;websocket&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Upgrader&lt;/span&gt;{&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;ReadBufferSize&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;1024&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;WriteBufferSize&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;1024&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;wsEndpoint&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;w&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ResponseWriter&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;r&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Request&lt;/span&gt;) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;upgrader&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;CheckOrigin&lt;/span&gt; = &lt;span style="color:#66d9ef"&gt;func&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;r&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Request&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// upgrade this connection to a WebSocket connection&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;ws&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;upgrader&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Upgrade&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;w&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;r&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#75715e"&gt;// 向连接的客户端写入信息&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Client Connected&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; = &lt;span style="color:#a6e22e"&gt;ws&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;WriteMessage&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, []byte(&lt;span style="color:#e6db74"&gt;&amp;#34;Hi Client!&amp;#34;&lt;/span&gt;))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// listen indefinitely for new messages coming&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// through on our WebSocket connection&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;go&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;reader&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;ws&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// define a reader which will listen for&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// new messages being sent to our WebSocket&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// endpoint&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;reader&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;conn&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;websocket&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Conn&lt;/span&gt;) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// read in a message&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;messageType&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;p&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;conn&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ReadMessage&lt;/span&gt;()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// print out that message for clarity&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(string(&lt;span style="color:#a6e22e"&gt;p&lt;/span&gt;))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;conn&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;WriteMessage&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;messageType&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;p&lt;/span&gt;); &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="websocket心跳检测"&gt;Websocket心跳检测&lt;/h3&gt;&#10;&lt;p&gt;参考博客 &lt;a href="https://www.cnblogs.com/tugenhua0707/p/8648044.html"&gt;https://www.cnblogs.com/tugenhua0707/p/8648044.html&lt;/a&gt;&lt;/p&gt;</description></item><item><title>关于我</title><link>https://lishengxie.top/pages/about/</link><pubDate>Sun, 30 Apr 2023 08:15:52 +0800</pubDate><guid>https://lishengxie.top/pages/about/</guid><description>&lt;p&gt;你好，我是 Lishengxie，一名后端开发工程师，正在持续学习 Java 技术栈，也尝试用 AI 辅助编程，把想法做成有趣的东西。&lt;/p&gt;&#10;&lt;h2 id="这里记录什么"&gt;这里记录什么&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;后端与数据结构&lt;/strong&gt;：分布式 ID、Redis 数据结构，以及开发中遇到的问题。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Linux 与部署实践&lt;/strong&gt;：服务器配置、HTTPS 证书、Nginx 和建站过程。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;算法学习&lt;/strong&gt;：刷题笔记、优化算法与深度学习课程中的推导。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;论文阅读&lt;/strong&gt;：SNN、NoC 与神经网络映射相关的阅读记录。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;这些文章是我的学习与实践笔记。我希望把解决问题的过程、关键细节和参考资料留下来，方便自己回看，也供遇到类似问题的人参考。&lt;/p&gt;&#10;&lt;h2 id="从这里开始"&gt;从这里开始&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://lishengxie.top/post/distributed-id-generator-algo/"&gt;分布式 ID 生成方案：从数据库到雪花算法&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://lishengxie.top/post/redis-listpack-ziplist/"&gt;Redis ziplist、quicklist 和 listpack&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://lishengxie.top/post/algorithm-study-multiopt/"&gt;多目标优化问题及两种常用解法&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;更多笔记可以在&lt;a href="https://lishengxie.top/post/"&gt;文章列表&lt;/a&gt;或&lt;a href="https://lishengxie.top/archives/"&gt;归档&lt;/a&gt;中找到。&lt;/p&gt;&#10;&lt;h2 id="找到我"&gt;找到我&lt;/h2&gt;&#10;&lt;p&gt;可以通过 &lt;a href="https://github.com/lishengxie"&gt;GitHub&lt;/a&gt; 或&lt;a href="mailto:1141751053@qq.com"&gt;邮件&lt;/a&gt;交流。&lt;/p&gt;</description></item><item><title>联系</title><link>https://lishengxie.top/pages/contact/</link><pubDate>Sun, 30 Apr 2023 08:15:52 +0800</pubDate><guid>https://lishengxie.top/pages/contact/</guid><description>&lt;p&gt;如果你发现笔记中的问题，或想交流开发与学习经验，可以通过以下方式找到我：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://github.com/lishengxie"&gt;GitHub · lishengxie&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="mailto:1141751053@qq.com"&gt;邮件 · 1141751053@qq.com&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>SNN映射论文阅读 Neu-NoC</title><link>https://lishengxie.top/post/snn-paper-neu_noc/</link><pubDate>Sun, 30 Apr 2023 00:19:30 +0800</pubDate><guid>https://lishengxie.top/post/snn-paper-neu_noc/</guid><description>&lt;p&gt;&lt;strong&gt;Neu-NoC&lt;/strong&gt;: A High-efﬁcient Interconnection Network for Accelerated Neuromorphic Systems&lt;/p&gt;&#10;&lt;p&gt;提出了一种环形+Mesh结合的NoC结构，同时基于该结构提出了相应的映射算法、广播协议和基于权重稀疏性的通信量减少方案，相较于现有的2D-Mesh的方法有效地减少了通信的延迟和能量消耗。&#10;&lt;a href="https://lishengxie.top/uploads/2023/02/16.png"&gt;&lt;img src="https://lishengxie.top/uploads/2023/02/16.png" alt="Neu-NoC整体架构"&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;h4 id="motivation"&gt;&lt;strong&gt;Motivation&lt;/strong&gt;&lt;/h4&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;相邻层之间通信频繁，导致NoC中大部分的通信量分布在较少的通信信道上；&lt;/li&gt;&#10;&lt;li&gt;全连接层中前一层的一个神经元给下一层的所有神经元发送的数据本质上是一样的，因此传输的数据包中有相当一部分是重复的数据。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h4 id="neu-noc结构介绍"&gt;&lt;strong&gt;Neu-NoC结构介绍&lt;/strong&gt;&lt;/h4&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Mesh+ring结合，同一层中的神经元映射到一个ring中来减少数据的搬运，ring中提供两条信道，分别用于接收和发送数据以提高信息的传输速度；&lt;/li&gt;&#10;&lt;li&gt;ring中使用ring路由，根据上图c)可以看到ring路由包含相应的2选1多选器、缓存和打包解包模块，同时提供分配模块用于仲裁(例如，正在传输的包比刚输入的包优先级更高)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h4 id="nn-aware-mapping"&gt;&lt;strong&gt;NN-aware Mapping&lt;/strong&gt;&lt;/h4&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;将神经元映射到具体的物理计算核心上，使得神经元之间的通信跳数最小&lt;/li&gt;&#10;&lt;li&gt;本质是贪婪算法，寻找局部最优的映射方案&#10;&lt;a href="https://lishengxie.top/uploads/2023/02/17.png"&gt;&lt;img src="https://lishengxie.top/uploads/2023/02/17.png" alt="Neu-NoC映射算法"&gt;&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h4 id="packet广播"&gt;&lt;strong&gt;packet广播&lt;/strong&gt;&lt;/h4&gt;&#10;&lt;p&gt;在packet的header中添加一段标志位用于支持广播协议，标志位长度和Mesh路由的总数目相同；如1-&amp;gt;7-&amp;gt;9-&amp;gt;10中分别广播到9和10，因此将9和10的标志位置为1，经过9后，9的标志位被置为0随后继续传递给10；&lt;/p&gt;&#10;&lt;h4 id="稀疏感知的通信量减少"&gt;&lt;strong&gt;稀疏感知的通信量减少&lt;/strong&gt;&lt;/h4&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;利用神经网络中特征图的稀疏性，提出了all-zero flit，该flit中使用特殊标志位，同时在payload中指出有多少个连续的全0包。根据这种方式将多个全0的数据包压缩成一个，由Mesh和ring之间的路由提供支持。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h4 id="实验"&gt;&lt;strong&gt;实验&lt;/strong&gt;&lt;/h4&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;针对全连接层&lt;/li&gt;&#10;&lt;li&gt;基于Booksim仿真器：https://github.com/booksim/booksim2&lt;/li&gt;&#10;&lt;li&gt;ring中的局部延迟和全局通信跳数随着同一个ring中支持的PE数量增加呈现出先增后减的趋势；&lt;/li&gt;&#10;&lt;li&gt;实验中发现通过将低于某个阈值的激活值置为0，提高特征图的稀疏性之后，精度不会受到严重的影响，因此可以在提高稀疏性和保持精度之间做一定的权衡；&lt;/li&gt;&#10;&lt;li&gt;提出的方法可以获得较好的性能，相较于普通的2D-Mesh的方法可以降低23.2%的包传输延迟和31.1%的能量消耗。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h4 id="思考"&gt;&lt;strong&gt;思考：&lt;/strong&gt;&lt;/h4&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;ring加Mesh结合的方法比较有特点；&lt;/li&gt;&#10;&lt;li&gt;能否直接在现有的2D-Mesh之间实现相应的映射方法，将同一层的神经元映射到相邻的PE上，但是相较于顺序方式需要一定的性能提升？&lt;/li&gt;&#10;&lt;li&gt;多播和0数据压缩的方式可以参考，尤其是对于SNN可以在时间维度上进行压缩，减少传输的延迟。&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>SNN映射论文阅读-SentryOS</title><link>https://lishengxie.top/post/snn-paper-sentryos/</link><pubDate>Sun, 30 Apr 2023 00:13:55 +0800</pubDate><guid>https://lishengxie.top/post/snn-paper-sentryos/</guid><description>&lt;p&gt;&lt;strong&gt;SentryOS：&lt;/strong&gt; Design of Many-Core Big Little µBrains for Energy-Efficient Embedded Neuromorphic Computing&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;开源地址：&lt;/strong&gt; 暂无&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;使用芯片：&lt;/strong&gt; µBrain&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;优化指标：&lt;/strong&gt; 芯片使用面积和功耗&lt;/p&gt;&#10;&lt;p&gt;在uBrain神经形态核心上拓展实现的神经形态系统（基于分段总线）和映射框架（SentryOS）。&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;使用分段总线，实现核心之间的一对一互联（实际根据运行数据存在分时复用）；&lt;/li&gt;&#10;&lt;li&gt;基于异构大小核，大网络分割后的子网络规模不同，使用异构大小核来减少uBrain核心中的硬件空闲率&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;a href="https://lishengxie.top/uploads/2023/01/10.png"&gt;&lt;img src="https://lishengxie.top/uploads/2023/01/10.png" alt="uBrain使用的三层全连接结构"&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;center&gt;&lt;b&gt; uBrain使用的三层全连接结构 &lt;/b&gt;&lt;/center&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;异构大小核设计&#10;根据uBrain中使用的三层全连接结构，作者分析了LeNet、AlextNet、VGGNet、ResNet和DenseNet五种模型中L1和L2 neighbors 的数目，发现对于不同应用差别较大，因此使用异构的不同大小的uBrain核心可以提高硬件资源（神经元和突触连接）的利用率。&#10;&lt;a href="https://lishengxie.top/uploads/2023/01/11.png"&gt;&lt;img src="https://lishengxie.top/uploads/2023/01/11.png" alt="整体架构"&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;分段总线互联&#10;文中使用分段总线连接不同的uBrain核心来完成通信，相较于传统的共享式的总线结构，分段式总线结构可以价格总线分段，不同段之间可以并行通信，互不影响。为了实现同一时刻所有核心之间可以并行通信，需要多条并行总线，基于训练数据获取到同一时刻最大的并行通行量，从而可以确定所需要的最小的并行总线数目。&#10;&lt;a href="https://lishengxie.top/uploads/2023/01/12.png"&gt;&lt;img src="https://lishengxie.top/uploads/2023/01/12.png" alt="分段总线"&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;SentryOS设计&lt;/p&gt;&#10;&lt;p&gt;a. SentryC编译器：将大网络分割成多个可以映射到uBrain核心的子网络，具体的映射算法如下，主要分为四个步骤&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;对于每个输出神经元，根据神经元到其的最长路径计算两者之间的距离；&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;根据第一步算出的距离给神经元添加索引，需要确保所有子网络中的神经元具有连续索引（论文中的阐述）&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;将所有距离小于2的神经元形成集合，\(S_0 = {N_j | dist(N_j ) ≤ 2}\)，产生一个子网络，剩下的神经元递归组成其他子网络，这一步中可能会插入权重为1的神经元（调整阈值每来一个脉冲就发放一个脉冲？）；&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;融合两个子网络\(S_i\) 和\(S_j\) 当且仅当&#10;&lt;/p&gt;&#10;&lt;div class="katex-display"&gt;Area(S_i,j) \lt Area(S_i) + Area(S_j)&lt;/div&gt;&lt;p&gt;&#10;&lt;/p&gt;&#10;&lt;div class="katex-display"&gt;Power(S_i,j)\lt Power(S_i)+ Power(S_j)&lt;/div&gt;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;文中提到可以将SentryOS的方案扩展到基于crossbar的神经形态硬件上，即认为crossbar为两层全连接结构（uBrain是三层）&#10;&lt;a href="https://lishengxie.top/uploads/2023/01/13.png"&gt;&lt;img src="https://lishengxie.top/uploads/2023/01/13.png" alt="SentryC算法"&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;b. SentryRT运行时：类似于DFSynthesizer，使用Max-Plus Algebras的方式确定自网络之间的执行顺序，这篇文章在DFSynthesizer上进一步改善，一方面使用多流水线来执行一个网络，另一方面使用Batch依次运算多个输入图片提高吞吐量。&#10;&lt;a href="https://lishengxie.top/uploads/2023/01/14.png"&gt;&lt;img src="https://lishengxie.top/uploads/2023/01/14.png" alt="SentryRT"&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;实验评估&lt;/p&gt;&#10;&lt;p&gt;a. 使用异构大小核设计可以提高突触等资源的利用率，降低能量消耗，提高吞吐量；&lt;/p&gt;&#10;&lt;p&gt;b. 使用分段总线可以避免运行整段总线，同时基于训练数据最小化了总线数目，降低了能量消耗；另一方面，uBrain核心之间通信不再需要路由算法，在映射时所有的通信方案已经确定，减少了通信的延迟。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ol&gt;</description></item><item><title>SNN映射论文阅读-NEUTRAMS</title><link>https://lishengxie.top/post/snn-paper-neutrams/</link><pubDate>Sun, 30 Apr 2023 00:10:08 +0800</pubDate><guid>https://lishengxie.top/post/snn-paper-neutrams/</guid><description>&lt;p&gt;&lt;strong&gt;Neutrams&lt;/strong&gt;: NEUTRAMS: Neural Network Transformation and Co-design under Neuromorphic Hardware Constraints&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;开源代码地址&lt;/strong&gt;：https://github.com/hoangt/neutrams&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;使用芯片&lt;/strong&gt;：TianJi，Prime&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;优化指标&lt;/strong&gt;：Crossbar之间的脉冲通信量&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://lishengxie.top/uploads/2023/01/3.png"&gt;&lt;img src="https://lishengxie.top/uploads/2023/01/3.png" alt="Neutrams提出的工具链层级"&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;center&gt;&lt;b&gt;图 1.&lt;/b&gt; NEUTRAMS提出的工具链的层级结构&lt;/center&gt;&#10;&lt;p&gt;&lt;strong&gt;实现步骤&lt;/strong&gt;：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;神经网络表示&#10;类似其他模拟器中常用的方式，将神经网络看成神经元分组和神经元分组之间的连接组成。神经元分组之间都认为使用全连接，不存在的边认为使用权重为0的虚拟边。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Training-based transformation(神经网络训练&amp;amp;神经元分组)&lt;/p&gt;&#10;&lt;p&gt;a. 使用BP算法训练神经网络&lt;/p&gt;&#10;&lt;p&gt;b. 连接稀疏化，通过交换矩阵的行或列来将连接矩阵转换为满足crossbar大小限制的多个子矩阵，并将其余连接权重置为0，目标是最大化剩余的原有连接的绝对值权重之和。&lt;/p&gt;&#10;&lt;p&gt;c. 权重量化，将原有的浮点数权重量化为低精度权重，同时使用BP算法微调模型(BP算法中仍然使用浮点数计算)。&lt;/p&gt;&#10;&lt;p&gt;d. 在原有的两层中间插入新的全连接层，对于大小为m和n的两个层之间的连接，插入\(\frac{m+n}{2}\)的全连接层，重新训练后减少准确度的损失。&lt;/p&gt;&#10;&lt;p&gt;e. 对于复杂的神经网络(非顺序连接的/循环的)：对于复杂的神经网络，可以通过图2所示的复制和合并的方式，逐层训练神经元分组之间的突触连接；对于循环神经网络，脉冲神经网络需要将循环连接暂时删除，然后记录循环连接中的信息，将上一时刻信息送入连接后神经元并保存当前时刻连接前神经元送入的信息。&#10;&lt;a href="https://lishengxie.top/uploads/2023/01/4.png"&gt;&lt;img src="https://lishengxie.top/uploads/2023/01/4.png" alt="复杂神经网络训练"&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;center&gt;&lt;b&gt;图 2.&lt;/b&gt; 复杂神经网络训练&lt;/center&gt;&#10;&lt;ol start="3"&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Mapping&#10;使用Kernighan-Lin(KL)算法进行神经元子块到crossbar上的映射，目标是最小化crossbar之间的脉冲通信量。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Cycle-accurate simulator&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;&lt;strong&gt;实验&lt;/strong&gt;&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;考察指标：错误率，能量消耗，芯片有效速度(反比于每个仿真周期内的芯片时钟周期数，芯片有效速度的最大值对应于超过该值部分脉冲无法在一个仿真周期内到达目标神经元)。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;结论&lt;/p&gt;&#10;&lt;p&gt;a. 插入新的全连接层精度损失低于扩展crossbar规模，插入新的全连接层会增加能量损失、降低有效速度；&lt;/p&gt;&#10;&lt;p&gt;b. 基于已训练的前神经元节点训练后节点可以避免误差的积累；&lt;/p&gt;&#10;&lt;p&gt;c. 连接稀疏化对于精度影响较大，但是后续可以通过微调网络改善；&lt;/p&gt;&#10;&lt;p&gt;d. 部分神经元参数可以同步变大或减小，而不影响最终的输出；&lt;/p&gt;&#10;&lt;p&gt;e. 网络规模越大，芯片有效速度越小。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ol&gt;</description></item><item><title>SNN映射论文阅读-PSOPART</title><link>https://lishengxie.top/post/snn-paper-psopart/</link><pubDate>Sat, 29 Apr 2023 22:14:32 +0800</pubDate><guid>https://lishengxie.top/post/snn-paper-psopart/</guid><description>&lt;h3 id="图优化方法"&gt;图优化方法&lt;/h3&gt;&#10;&lt;p&gt;&lt;strong&gt;PSOPART&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Mapping of local and global synapses on spiking neuromorphic hardware&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;开源代码地址&lt;/strong&gt;：https://github.com/Jinouwen/Mapping&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;优化指标&lt;/strong&gt;：神经元分块之间的脉冲通信量&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;类脑芯片&lt;/strong&gt;：CxQuad&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;基本步骤&lt;/strong&gt;&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;使用Carlsim进行脉冲神经网络运行模拟，构建脉冲神经网络图结构；&lt;/li&gt;&#10;&lt;li&gt;使用PSO(Partial Swarm Optimization)算法进行脉冲神经网络的分割，产生符合硬件限制的子块，这一步中优化的指标为神经元分块之间的脉冲通信量。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;&lt;a href="https://lishengxie.top/uploads/2023/01/2.png"&gt;&lt;img src="https://lishengxie.top/uploads/2023/01/2.png" alt="PSO算法执行流程"&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;center&gt;&lt;b&gt;图1. PSO算法执行流程&lt;/b&gt;&lt;/center&gt;&#10;&lt;p&gt;&lt;strong&gt;创新点&lt;/strong&gt;&#10;提出使用进化算法(PSO)用于脉冲神经网络分割。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;问题&lt;/strong&gt;&#10;没有考虑到神经元分块到crossbar的物理映射问题，优化算法映射时间过长。&lt;/p&gt;</description></item><item><title>SNN映射论文阅读-SpiNeMap</title><link>https://lishengxie.top/post/snn-paper-spinemap/</link><pubDate>Sat, 29 Apr 2023 22:14:32 +0800</pubDate><guid>https://lishengxie.top/post/snn-paper-spinemap/</guid><description>&lt;h3 id="图优化方法"&gt;图优化方法&lt;/h3&gt;&#10;&lt;h4 id="spinemap"&gt;&lt;strong&gt;SpiNeMap&lt;/strong&gt;&lt;/h4&gt;&#10;&lt;p&gt;Mapping spiking neural networks to neuromorphic hardware.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;开源代码地址&lt;/strong&gt;：https://github.com/Jinouwen/SpiNeMap&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;优化指标&lt;/strong&gt;：Global spikes，latency，energy consumptions&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;类脑芯片&lt;/strong&gt;：DYNAP-SE&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://lishengxie.top/uploads/2023/01/1.png"&gt;&lt;img src="https://lishengxie.top/uploads/2023/01/1.png" alt="Comparison with NEUTRAMS, PACMAN, PSOPART"&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;步骤分析&lt;/strong&gt;:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;SNN模拟与分析：使用SNN软件模拟器(CARLSim)提取经过训练的SNN网络的拓扑结构和神经元的行为，形成无向SNN图以及脉冲行为轨迹；&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;无向SNN图以神经元为节点、神经元与神经元之间的突触为边；&lt;/li&gt;&#10;&lt;li&gt;脉冲行为轨迹包含源神经元以及目的神经元的编号和激发时间&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;划分：随机无向SNN图划分为多个SNN子块，使用启发式算法Kernighan-Lin graph partitioning algorithm，通过在不同子块之间交换神经元优化SNN子块之间的脉冲通信量；&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;每个SNN子块中神经元数目不能超过单个crossbar所能容纳的神经元数&lt;/li&gt;&#10;&lt;li&gt;每个SNN子块只会被分配给一个crossbar&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;映射：使用启发式搜索算法（PSO，粒子群算法）找到一个最优的映射方案将SNN子块分配给目标硬件上的神经元核，最小化目标硬件上脉冲在crossbar之间传播的平均延迟和能量消耗(通过最小化脉冲传播的平均跳数实现)。基于拓展的Noxim平台（Noxim++）实现搜索算法中的指标函数计算。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;&lt;strong&gt;创新点&lt;/strong&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;将SNN网络的划分和SNN网络分块到物理硬件的映射一起考虑，形成完整的映射方案。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;strong&gt;问题&lt;/strong&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;没有提到神经元的扇入突触超过crossbar限制如何解决？&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;strong&gt;ISI distortion&lt;/strong&gt;：inter-spike intervals失真，会引起模型精度的下降，定义为&#10;&lt;/p&gt;&#10;&lt;div class="katex-display"&gt; I\_j^s\|\_{distortion}=I\_j^s|_{new}-I\_j^s = \delta\_j^s-\delta\_{j-1}^s &lt;/div&gt;&lt;p&gt;&#10;，其中&lt;span class="katex-inline"&gt; \delta\_j^s &lt;/span&gt;表示第j个脉冲在第s个突触上传播的延迟，当突触位于crossbar上时，可以认为&lt;span class="katex-inline"&gt;I\_j^s\|\_{distortion}=0&lt;/span&gt;，当突触映射到NoC上时，&lt;span class="katex-inline"&gt;I\_j^s\|\_{distortion}\neq 0&lt;/span&gt;。当输入编码方案为速率编码时，ISI distortion可能没有影响，论文中提出了另一种直觉的spike disorder的指标&#10;&lt;/p&gt;&#10;&lt;div class="katex-display"&gt; \sum\_{j=1}^{n\_i}[(F\_j^i-\hat{F}\_j^i)^2]/n\_i &lt;/div&gt;&lt;p&gt;&#10;，&lt;span class="katex-inline"&gt;F\_j^i&lt;/span&gt;和&lt;span class="katex-inline"&gt;\hat{F}\_j^i&lt;/span&gt;分别表示神经元i中的第j个脉冲到达的频率。&lt;/p&gt;</description></item><item><title>My First Blog</title><link>https://lishengxie.top/post/my-first-blog/</link><pubDate>Fri, 24 Feb 2023 14:43:42 +0800</pubDate><guid>https://lishengxie.top/post/my-first-blog/</guid><description>&lt;p&gt;This is the first blog for &lt;a href="https://lishengxie.github.io"&gt;https://lishengxie.github.io&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;同步备份typecho站点中的个人博客，博客网址&lt;a href="https://www.lishengxie.top"&gt;https://www.lishengxie.top&lt;/a&gt;.&lt;/p&gt;</description></item></channel></rss>