LaTeX 基本概念
这是关于 LaTeX 基础概念的笔记,不涉及具体的 LaTeX 语法细节,而是从宏观层面,包括历史和命令行用法等,来进一步理解 TeX 和 LaTeX 。(标准写法是 \(\TeX{}\) 和 \(\LaTeX{}\),但是显示效果不好,下文不采用) TeX 语言 TeX 排版系统是 Knuth 发明的一种宏语言,提供了几百个类似 \def 的基础指令用于排版,主要解决的是自动断行,以及公式布局等排版问题。TeX 语言的版本在升级到 3.0 之后,主版本号就不再发生变动,而是以 3.1,3.14,3.141 的形式在更新时不断接近 pi,这体现了 TeX 语言的稳定性。 关于排版系统的基本介绍,有一篇博客可以参考: 排版引擎纵谈:程序员的视角 TeX 语言并不适合直接使用: 最早设计时不支持非 ASCII 编码,更不要说 Unicode 字符和中文支持等 字体需要额外配置,不能利用系统现有的字体 原始的几百个基础指令太繁琐又太简陋,需要考虑很多细节 后续有很多基于 TeX 基本指令封装的宏集,让使用者可以忽略很多细节,例如在 LaTeX 格式中的 center 环境是如下...
LaTeX Tex Live 安装
整理一下 Tex Live 2024 在Windows和Linux(Ubuntu22)中的安装过程,主要参考TeX Live 2024 安装教程(Windows/WSL/Linux)以及一份简短的关于 LATEX 安装的介绍。 在Linux系统上的LaTeX编译速度普遍比Windows更快,而且速度提升非常明显,并且TexLive的安装也是如此,在Linux中的安装过程比Windows更快,这种优势即使是在WSL2中也是很明显的,因此我选择在Windows和WSL2中都进行安装。 下载Texlive镜像 随便找一个 CTAN 镜像站下载 texlive2024 即可,例如清华镜像。 texlive 的下载安装其实非常友好,在不同系统上都只需要同一个镜像文件(texlive2024.iso,大约 5 个 G)。 安装Texlive Windows 直接点击install-tl-windows.bat脚本安装即可,默认有GUI显示,根据提示进行确认即可。 其实也可以加上--no-gui选项关掉GUI,此时的安装过程和Linux类似。 最好重新设置一下安装目录,例如D:/texlive...
Brainfuck语言与解释器
图灵机 图灵机(Turing machine)是图灵提出的一种抽象计算模型,它主要包括一个无限长的纸带(tape)、一个读写头(head)以及一系列状态和指令规则: 纸带(tape):图灵机的纸带被划分为单元格,每个单元格上可以存储一个字符。纸带是无限长的,可以向左或向右无限延伸。 字符表(alphabet):即字符的集合,它包含纸带上可能出现的所有字符。其中包含一个特殊的空白字符(blank),意思是此格子没有任何字符,这是默认状态。 读写头(head):读写头是指向纸带上的一个单元格的指针,可以读取/擦除/写入当前单元格的内容,也可以根据移动到相邻的单元格。 指令集(instructions table):包括一组有限长度的指令,它根据当前机器所处的状态以及当前读写头所指的格子上的符号来确定读写头下一步的动作,并改变状态寄存器的值,令机器进入一个新的状态。 状态寄存器(state register):它用来保存图灵机当前所处的状态。图灵机的所有可能状态的数目是有限的,并且有一个特殊的状态,称为停机状态。 图灵机可以接受一些输入并产生输出,并根据状态转换规则进行计算。这个模...
C语言 宏的学习笔记
对于宏有很多花里胡哨的用法,虽然C++已经不推荐使用复杂的宏,但是也要看得懂,因此整理一下。 基本概念 预处理器是一个正式编译C语言的源代码之前的文本处理工具,它负责执行预处理指令(#开头的指令),通常包括头文件包含,条件编译,宏等。 宏是预处理器支持的一种重要功能,允许程序员定义一些简单的代码替换规则:通过宏创建符号常量或者简单的代码片段,并在代码中多次使用。 这些宏会在编译前被预处理器替换为相应的内容。值得注意的是,预处理器只是文本处理工具,它不会分析任何语法层面的内容,行为完全是文本层面的。 预处理器支持的命令主要包括 文件包含:#include 用于在源文件中包含其他文件的内容 条件编译:#if、#ifdef、#ifndef、#elif、#else、#endif 用于条件编译,根据条件决定编译部分代码 宏定义:#define 用于创建宏,可以是简单的文本替换或带参数的宏 取消宏定义:#undef 用于取消已定义的宏 除此之外,还有几个不常见的命令: 错误指示:#error 用于在预处理阶段生成一个错误消息,编译终止,通常是用在条件编译中终止某个错误情形。警告指示#w...
Git 配置文件
包括三种配置文件: .gitconfig .gitattributes .gitignore .gitconfig .gitignore是Git的忽略规则配置文件,Git 会在如下位置依次进行检查(优先级由高到低): 第一层是仓库级,在仓库目录下,文件为.git/config 第二层是用户级,在用户主目录下,文件为~/.gitconfig(主要修改的是用户级配置) 第三层是系统级,在安装目录下,安装时的选项会保存在这里 Git也可以使用符合XDG规范的配置文件:~/.config/git/config。 123456789101112131415161718192021[user] name = xxx email = xxx@xx.com[init] # 默认主分支名称 defaultBranch = main[core] # 默认编辑器 editor = vim # 确保git正确显示中文信息 quotepath = false # 在提交时将所有文本的换行符转换为LF,检出时不转换 autocrlf =...
遗传算法及Python实现
遗传算法虽然相比于深度学习,神经网络等新兴的人工智能算法过于原始,相比于有严格数学理论的优化算法又显得那么粗糙,但是作为一类思路独特的算法还是值得了解一下的。 介绍 遗传算法(Genetic Algorithm)是美国J.Holland教授于1975年首先提出的一种启发式优化方法,灵感来自于进化理论:它模拟了生物进化过程中的自然选择、遗传机制和变异规律,用于解决搜索和优化问题。 遗传算法的基本思想是将问题的解表示为一组基因序列,然后使用遗传操作(如选择、交叉和变异)对这些基因序列进行进化(迭代),使优秀的解逐渐从种群中浮现出来。 遗传算法作为一种启发式优化方法,具有如下特点: 适用性:遗传算法的计算框架是普适性的,可以应用于求解各种优化问题,特别是对于搜索空间庞大、复杂的优化问题,如组合优化、参数优化等 并行性:可以并行处理多个解决方案,提高搜索效率 全局或局部最优:由于具有随机性和多样性,遗传算法有助于跳出局部最优解,更有可能找到全局最优解,但是这依赖于初始种群的生成和参数的设置 灵活性/复杂性: 包含很多待定参数,需要根据问题的特点进行调整和改进,这既是算法的灵活性体现,也...
生命游戏及Python实现
生命游戏,如果我小时候能做出这玩意,我能自己玩一整天,看着各种复杂混沌的演化过程,最终归于寂静。 介绍 生命游戏(Game of Life)是由数学家 John Conway 在 1970 年创造的一种细胞自动机。 它是一种零玩家游戏,意味着其演化是由初始状态决定的,无需玩家干预。 游戏设定在一个二维的网格世界中,每个格子代表一个存活(标记为1)或死亡(标记为0)的细胞。 基于一组简单的规则,所有细胞会在每个时刻进行同步更新,从一个状态转变到另一个状态,象征着时间推进中生命的演化。 这些规则根据细胞周围的存活细胞数量来确定:(一个细胞受到周围八个细胞的影响) 对于活细胞: 如果周围有两个或三个活细胞,则它在下一个时刻仍然存活 如果周围的活细胞数量少于两个,它在下一个时刻会死亡(孤立) 如果周围的活细胞数量超过三个,它在下一个时刻也会死亡(拥挤) 对于死细胞: 如果周围有三个活细胞,它在下一个时刻会成为活细胞(繁殖) 生命游戏的演化是由给定或随机生成的初始状态开始,并按照这些简单规则不断迭代。即使这些规则非常简单,但它们可以产生出极其复杂和不可预测的行为,包括静态、振荡...
MPDE 方法以及 Mathematica 实现
MPDE方法是一类用来分析数值格式的耗散色散性质的方法,它的思路为: 对于求解问题PDE(a),我们通过离散设计得到了数值格式, 现在反过来,找出一个与数值格式最契合的PDE(b),通常是原本的PDE(a)加上一些高阶余项,分析PDE(b)的耗散和色散性质,尤其关注它相比于PDE(a)多出来的高阶项,就可以得到数值格式的耗散和色散性质。 准备 MPDE的分析依赖于下面的结论:对于PDE \[ 0 = u_t - P u = u_t - \sum_{j=1}^n a_j \frac{\partial^j u}{\partial x^j} \] 其中 \(a_i \in \mathbb{R}\) 。一般性的结论如下: \(u_x\):不会对耗散和色散做出任何贡献 \(u_{xx}\) 或者更高的偶数阶导数项:对耗散性有贡献,对色散性无贡献 \(u_{xxx}\) 或者更高的奇数阶导数项:对色散性有贡献,对耗散性无贡献 低阶项的贡献是主要的,因此通常可以忽略高阶项,只关注最低阶的系数非零的一个偶数阶导数项和一个奇数阶导数项(不含 \(u_x\) )。 这里要求系数都是实值,如果系...
八皇后问题与回溯法
问题介绍 八皇后问题是以国际象棋为背景的经典问题: 如何能够在8×8的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?(皇后可以攻击与它处于同一条横行,纵列或者斜线上的其它棋子) 我们考虑的是一般化的\(n\times n\)的棋盘上放置\(n\)个皇后的问题(\(n > 1\)),理论分析表明当且仅当\(n \ge 4\)时问题有解: 对于\(n=4\)的最简问题,有2个解 对于\(n=8\)的原始问题,有92个解 回溯求解 回溯算法又称为试探法,算法思路主要为:每进行一步,都是抱着试试看的态度,如果发现当前选择并不是最好的,或者这么走下去肯定达不到目标,立刻做回退操作重新选择。这种走不通就回退再走的方法就是回溯法,属于递归求解。 对于八皇后问题可以采用回溯法进行逐步求解:逐行进行放置,假设当前考虑在第m行的放置问题,遍历第m行的所有位置,检查是否与前m-1行已放置的皇后冲突(整列检查,两个斜线检查),如果位置仍然可行,则进行临时放置,并进入下一层的放置问题,在子问题退出之后,撤销第m行的临时放置,并考虑m行的下一个位置,直到最后一行放置完成得...
Hanoi塔问题求解(递归与非递归算法)
Hanoi塔是经典的递归算法的应用,但是有意思的是我之前学习的算法或数据结构的课都漏掉了这个例子,补一下吧,包括两类三种算法实现。 问题介绍 Hanoi塔问题为:考虑三根杆子A,B,C,A杆上有 N 个 (N>1) 穿孔圆盘,圆盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至 C 杆: 每次只能移动一个圆盘; 大盘不能叠在小盘上面。 问:如何移动?最少要移动多少次? 递归分析 重点关注最大的圆盘,它是整个任务的核心:虽然它在最底层不会影响别的圆盘的操作,但是将它从A移动到C时,必然其他N-1个盘都处于B。 据此可以把问题分解为三个子任务: 将N-1个圆盘从A移动到B,此时C可以用作临时存放区 将最大的圆盘从A直接移动到C 将N-1个圆盘从B移动到C,此时A可以用作临时存放区(和第一步的任务是等价的) 记\(f(n)\)为n个圆盘时最少的移动次数,显然有初值\(f(1)=1\),以及递推关系 \[ f(n) = 1 + 2f(n-1) \] 因此解得\(f(n)=2^n-1\)为最少移动次数。 这里的理论分析直接提供了递归算法的思路,但是理论分析的结果并非仅仅...