《九章算术》方程章直除法:两千年前的高斯消元法
《九章算术》里的“方程”并不是你初中课本上那个含有x的等式。它是中国古人用算筹解线性方程组的一整套完整算法放在今天看就是高斯消元法的老祖宗。这篇文章要解决一个很具体的问题当你翻开“方程章”看到那些被后人反复引用的原文时它到底让你在算筹上做什么动作这些动作又是怎样一步步算出最终答案的我会先用现代语言把原文翻译成你能动手操作的步骤再用一道真实例题从头算到尾顺带解释几个特别容易读错的细节。不管你是对数学史感兴趣的读者还是想给学生讲点课本外知识的人这份拆解应该都能直接上手用。1. 九章算术里的“方程”和我们想的不是一回事1.1 “方”是排成方阵“程”是按规程计算先说点基础概念。“方程”两个字在今天已经被定义为“含有未知数的等式”但在《九章算术》里它指的不是一个等式而是整整齐齐排成方阵的一组数据。书里的原话是刘徽在注《九章算术》时写的程课程也。群物总杂各列有数总言其实。令每行为率二物者再程三物者三程皆如物数程之并列为行故谓之方程。翻译成大白话是把不同的物品分列成几行每一行记录它的数量和总数有几种物品就排几行像方阵一样列出来所以叫“方程”。“方”就是方阵“程”就是按规范算。换句话说它更像我们今天线性代数里的增广矩阵而不是单独一条等式。这一点很关键。因为古人不设未知数、不写符号他们处理“方程组”的方式就是把系数和常数项像表格一样摆在地上然后对整行数据做操作。你如果不理解“方阵”这个视角光看原文很容易一头雾水。1.2 它不是“解一个x”而是“解整个系统”现代中学生学的方程核心动作是移项、合并同类项、两边同乘同除盯住一个未知数来回折腾。而《九章算术》的“方程”一次要处理多个未知数而且它们的地位是并列的上禾、中禾、下禾牛羊猪米麦豆……每种物品占一列总数占一列数据按某种对应关系摆好。打个比方如果你面前有一堆账目记录了三种粮食合计多少斗、每种粮食与其他两种配比各是什么比例你要做的事情不是盯着某一个数硬猜而是把这堆账目当成一个整体反复做“整行加减”让某一行里只留下一个未知数。这个思路跟现代解线性方程组的“消元法”是同一件事只是古人用算筹代替了纸笔用“减”代替了符号变换。1.3 古人为什么会用到方程组现代人看到鸡兔同笼都会感叹古代数学好玩但《九章算术》里出现方程组绝对不是为了趣味题和脑筋急转弯。从同时代的历史文献看这些题直接对应现实中的分配、赋税、物价、粮食折算问题。比如原书里大量题目涉及“出钱买物”“谷物兑换”“禾田产量”。多种物品的数量、单位价格、总值交织在一起不列方程组根本算不干净。用现代术语说九章算术的“方程章”解决的就是“有限数据下的线性关系推断”。它是最早被系统化、程序化的算法比欧洲同类成果早了上千年。2. 看不懂原文不要紧先看算筹怎么把方程“摆”出来2.1 算筹计数法一张“口袋里的表格”《九章算术》成书的年代没有纸笔计算也没有小数和负号。古人用一把小棍子——算筹——在地上或木板上来回摆。摆法很简单个位、十位、百位……从右往左哪一位有数就摆几根空位就空着不摆。这里有个特别容易忽略的点当时已经有了用红黑算筹区分正负数的方法正数用红筹负数用黑筹这在位值制记数法里是很超前的。换句话说古代筹算家和今天用Excel记账没什么本质区别。你看到的那一堆小棍就是一张活生生的“表格”。2.2 原题上禾、中禾、下禾的“三元一次方程组”我们直接拿方程章第一题来演示。这道题在《九章算术》里的原文是今有上禾三秉中禾二秉下禾一秉实三十九斗上禾二秉中禾三秉下禾一秉实三十四斗上禾一秉中禾二秉下禾三秉实二十六斗。问上、中、下禾实一秉各几何现代人一眼就能看出来这就是一个三元一次方程组。设三种禾每秉的产量分别是 x、y、z则题目等价于3x 2y z 392x 3y z 34x 2y 3z 26有意思的是古人完全不需要写xyz他们只在筹算盘上摆三行数字把一次方程组的系数矩阵和常数项排成下图这个样子位置上禾系数中禾系数下禾系数实常数项右行32139中行23134左行12326每一行对应一个“方程”每列对应一种禾的系数。请注意这里的“行”是按竖排说的右行就是右边那一列中行是中间那一列左行是左边那一列。理解了这组排列后面的消元操作就非常好懂了。2.3 从原文到现代矩阵很多第一次读九章原文的人会卡在这个地方“以右行上禾遍乘中行”“以直除”……这些字根本没提到数字也没有等于号。实际上你只要把原文翻译成“对方程组做初等变换”就全通了。“以右行上禾三遍乘中行”意思是把中间这一行的所有数都乘以3“直除”的意思是连续相减把中间这一行的头一个系数减成0。这和高斯消元法里的“某行乘以倍数再与另一行相减”完全相同。后面我们会全程用现代演算手把手演示你马上就会发现古人和现代人的算法其实只差了一个等号和几个字母。3. 直除法实操三步消元手把手算一遍3.1 直除法的核心逻辑“直除法”的名字有点吓人本质却朴素得不得了。你看三行数据都在那摆着目标很明确把上禾系数变成第一行有、第二行第三行没有再把中禾的系数变成第二行有、第三行没有最后只剩第三行有下禾于是下禾的数量直接就能读出来——这就是从“多未知数”一步步“消元”的过程。生活化类比想象你面前有三个配方要配出三种不同比例的混合物。你不想一个个猜而是先想办法让某一种成分在另外两个配方里消失剩下只含另一种成分的“纯净配方”再倒推回去。古人用算筹做的就是这套“消去法”只不过每一步都是整行整行地乘、整行整行地减。3.2 第一步用右行上禾系数把中行、左行的上禾消成0把上一节的矩阵再抄一遍右行3 2 1 | 39中行2 3 1 | 34左行1 2 3 | 26先处理中行。右行的上禾系数是3中行的上禾系数是2。要让中行的上禾变成0常规办法是“两个行都调整到上禾系数相同再相减”。古人选了一个整数倍数把中行整体乘以3得到中行6 9 3 | 102然后从中行里减去右行的2倍。右行的2倍是6 4 2 | 78两行相减中行0 5 1 | 24这样中行的上禾系数就被消掉了。同一个道理处理左行把左行整体乘以3得到左行3 6 9 | 78再减去右行的1倍即3 2 1 | 39得到左行0 4 8 | 39第一轮做完矩阵变成右行3 2 1 | 39中行0 5 1 | 24左行0 4 8 | 39到这一步整个问题的维度已经降了一档我们只剩下两个含两个未知数的方程了。这里要提醒一句乘3和减去右行的倍数并不是随手选的。乘以3是为了让中行上禾系数变成6和右行上禾系数3的倍数对齐减右行的2倍也正是因为6÷32。用刘徽的话说这叫“齐同”先让两组数的相应位置“齐”起来再相减“同”出结果。这个“齐同原理”贯穿了《九章算术》的很多算法。3.3 第二步用中行的中禾系数把左行的中禾消成0现在只用看两行数据中行0 5 1 | 24左行0 4 8 | 39中行的中禾系数是5左行的中禾系数是4。想让左行的中禾变成0就把左行整体乘以5中行作为基准左行变成0 20 40 | 195再减去中行的4倍因为20÷54。中行的4倍是0 20 4 | 96相减后左行0 0 36 | 99第二轮做完矩阵变成右行3 2 1 | 39中行0 5 1 | 24左行0 0 36 | 99你看第三行现在只剩一个未知数“下禾”了这跟高斯消元法最后得到的“阶梯形矩阵”一模一样。现代人把这个过程叫“化上三角”古人叫“如方程”本质完全一致。3.4 第三步从下往上回代求出三种禾左行现在写出来就是 36×下禾 99所以下禾一秉等于 99/36约分一下得到 11/4也就是 2又3/4斗。写成原书里的答案叫“下禾一秉二斗四分斗之三”。接着回代到中行。中行是 5×中禾 1×下禾 24下禾已经知道是 11/4于是5×中禾 11/4 245×中禾 96/4 - 11/4 85/4中禾 85/20 17/4也就是“中禾一秉四斗四分斗之一”。最后把中禾、下禾的值代回右行。右行是 3×上禾 2×中禾 1×下禾 393×上禾 39 - 2×(17/4) - 11/4 156/4 - 34/4 - 11/4 111/4上禾 111/12 37/4也就是“上禾一秉九斗四分斗之一”。到这里整道题的答案就出来了。和你用现代方法解三元一次方程组得到的结果一模一样。合上书再看一遍原文里那句“上禾一秉九斗四分斗之一”你大概就能想象出汉代算家是如何在一堆小棍中间拨来拨去最终读出答案的了。4. 直除法与现代高斯消元法的对照与思考4.1 两百年前的高斯用的还是同一套思路高斯消元法是19世纪由高斯系统化的解线性方程组方法如今在世界各地的线性代数课本里都是第一章内容。它的标准流程是把增广矩阵写成阶梯形然后回代求未知数。这跟《九章算术》的直除法几乎没有区别。做一个直观对照现代线性代数步骤九章算术直除法做法将方程组写成增广矩阵用算筹摆成“方程”方阵把第一列除第一个主元外全消成0以右行头位遍乘中、左行再直除把第二列消成阶梯形以中行头位遍乘左行再直除回代求解从最小未知数开始逐一倒推所以你可以说高斯消元法的成熟形式在两千年前的《九章算术》里就已经出现了。这并不是后世谁抄袭谁而是线性方程组的数量关系决定了最有效的解题策略只有这一条路逐列消元回代求解。4.2 古代算法里几个“超前”的设计直除法里最让人惊讶的还不是消元思路本身而是配套的细节设计。第一个是“遍乘”操作。今天做高斯消元时最烦的就是分数系数。古人为了避免马上出现分数先让整行乘以一个整数“齐”一下再做减法这样只要有可能就能保持在整数范围内运算。这不是数学上的侥幸而是为了适应筹算算筹摆整数方便摆分数麻烦所以算法在设计上天然偏好整数路径。这种“尽量减少分数出现”的思路在现代数值分析中仍然是最朴素的稳定性原则。第二个是“直除”本身。古人用“减”来代替“除”让运算落地成连续相减的机械动作。这种可重复、可机械化的操作正是“算法”的本义。今天计算机里的高斯消元程序本质上也是一遍遍重复“乘倍数、做减法”。你从九章算术里看到的不是一堆孤立技巧而是一套程序化的指令序列。4.3 用现代线性代数语言重看这道题用今天的语言来总结前面那道题作者在开篇其实已经做了3x 2y z 392x 3y z 34x 2y 3z 26系数矩阵是321231123增广矩阵就是上一节我们摆出的方阵。对它做初等行变换后变成上三角形式然后回代。全套流程放回九章“方程章”名称从“矩阵”变成“方程”从“行变换”变成“遍乘直除”但数学内核没有任何变化。这种“翻译”不是牵强附会。刘徽在注释里明确描述了“令每行为率”“总言其实”这就是增广矩阵的定义。古人没有把“行”抽象成向量但已经按向量的方式去操作它了。所以每当有人问“中国古代到底有没有线性代数思想”时回答是不仅有而且已经做出了完整的算法示范。5. 常见疑问与历史细节避坑指南5.1 “直除”的“除”到底是除还是减这是读九章第一眼最容易误会的地方。现代汉语里“除”是除法可在古汉语里“除”有“去除、减去”的含义比如“除旧迎新”里的除就是“去掉”的意思。“直除”的意思是直接相减反反复复地减直到减尽或者够减为止。刘徽在注释里说“直除”是“以少减多更相减损”已经解释得非常清楚。这个细节会影响你怎么理解整个算法。你如果以为是做除法会觉得每一步都很绕一旦明白它是连续的减法整道题的逻辑就顺了。古人之所以用减法而不是除法实际也是为了迁就算筹的操作习惯——算筹可以直接做累减但做商除就需要更复杂的步骤。5.2 负数的出现算筹上怎么处理“不够减”既然直除法一直在做减法必然会出现“减少了”的局面。古典数学遇到这种情况会卡壳但《九章算术》的方程章走得更远它专门记录了一节“正负术”给出正负数加减的运算法则。这是世界数学史上对负数运算规则最早的系统描述之一。具体操作上古人在使用算筹时会拿红、黑两种颜色的筹来区分正负红筹表示正数黑筹表示负数。加减时同色相加、异色相减这跟现代代数的符号法则是一致的。你在原书里看到“同名相除异名相益”之类的话翻译过来就是在讲正负数的运算法则。正因如此直除法在消元过程中即使产生了负数也能继续算下去不会因为“减不动”而中断这是算法完整性的一大保证。5.3 方程章的数学“辐射范围”到底有多大《九章算术》成书后成为中国古代数学最重要的经典之一历代数学家都对其做过注释和推广。刘徽的注解在三国时期完成贾宪、杨辉、秦九韶等后来的数学家都在此基础上继续推进。书里的“方程”技术本质上奠定了中国传统的“多元一次方程组解法”的基石。这套算法对世界数学史的贡献同样不可忽略。当线性方程组的系统解法后来在欧洲独立发展起来时数学史研究者追溯到的最早完备算法形式就是《九章算术》里的直除法。今天在大学线性代数课上学的“高斯消元法”其实可以看作“直除法”在新的符号体系里的化身。了解这段历史再看增广矩阵和初等行变换会多一层“原来我在做古人也做过的事情”的亲切感。最后再分享一个比较个人化的体会。我最初读“方程章”时总觉得那些“遍乘”“直除”“正负”的用词生硬难懂直到自己用小纸片代替算筹把上面那道题完整摆了三轮才突然理解为什么古人管它叫“方程”——数据一排排列在面前每次操作都是在调整整个方阵的平衡就像整理一个多维天平。从那天起再看现代代码里的“矩阵消元循环”我总觉得内核里站着一个拿着红色和黑色小棍的中国古人。建议你也找几十根牙签或者干脆用纸笔按本文第3节亲手算一遍这种“手算对照原文”的体验比单纯读十遍注释都管用。

相关新闻

UFS3.1协议实战解析:从物理层眼图到UPIU级调试

UFS3.1协议实战解析:从物理层眼图到UPIU级调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 14:50:12 阅读更多 →
MeterSphere 开源持续测试平台:功能架构、技术栈与快速部署指南

MeterSphere 开源持续测试平台:功能架构、技术栈与快速部署指南

质量保障接口测试测试后端前端AI 应用DevOps 【免费下载链接】metersphere MeterSphere 是新一代的开源持续测试工具,内置 AI 助手,让软件测试工作更简单、更高效,不再成为持续交付的瓶颈。 项目地址: https://gitcode.com/gh_mir…

2026/10/2 14:50:12 阅读更多 →
Agent Skills 实战:用 SKILL.md 让 Claude 按规范自动干活

Agent Skills 实战:用 SKILL.md 让 Claude 按规范自动干活

1. 从“skills”这个热词说起:它到底是什么,为什么突然火了如果你最近在开发者社区、技术群或者视频平台上频繁刷到“skills”这个词,大概率不是指传统意义上的“技能”泛称,而是特指围绕 Claude 生态衍生出来的一套能力扩展机制—…

2026/10/2 14:50:12 阅读更多 →

最新新闻

裸金属驱动适配与PCIe/USB设备透传实战指南

裸金属驱动适配与PCIe/USB设备透传实战指南

1. 项目概述:裸金属场景下驱动与透传问题的实战破局点“驱动装不上、透传总报错”——这句话不是一句抱怨,而是裸金属服务器交付现场最常听到的三秒沉默前奏。我干这行十年,从第一批国产化替代试点开始,到如今在龙蜥社区参与Skill…

2026/10/2 17:38:48 阅读更多 →
AT7456E OSD芯片:为监控摄像头叠加时间水印与Logo的硬件方案

AT7456E OSD芯片:为监控摄像头叠加时间水印与Logo的硬件方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 17:38:48 阅读更多 →
同一个判断,为什么会有多个“合理”解释?——SHAP解释多重性与AI透明度的工程真相

同一个判断,为什么会有多个“合理”解释?——SHAP解释多重性与AI透明度的工程真相

同一个判断,为什么会有多个“合理”解释?——SHAP解释多重性与AI透明度的工程真相期数:AI透明度卷 第1期 作者:Valhalla Matrix治理实验室 原创声明:本文为原创技术博客,基于Valhalla工程实践编写。 论文锚…

2026/10/2 17:38:48 阅读更多 →
pcb沉金遇上二次元

pcb沉金遇上二次元

2026/10/2 17:38:48 阅读更多 →
动态内存管理(c++方向必看)

动态内存管理(c++方向必看)

引言: 学 C 的时候,我一度觉得 malloc 挺多余——数组不是挺好用吗? 直到写了个小练习:让用户输入一串数字再排序。写完发现卡住了,数组长度写多少?写 10,用户输入 11 个就崩;写 100…

2026/10/2 17:38:48 阅读更多 →
STM32F103国产替代实战:GPS定位平台MCU替换与串口移植解析

STM32F103国产替代实战:GPS定位平台MCU替换与串口移植解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 17:37:48 阅读更多 →

日新闻

从零搭建AI工程化:模型之外的完整闭环

从零搭建AI工程化:模型之外的完整闭环

先搞清楚一件事:从零开始做 AI 工程化,难的从来不是调模型、写提示词,而是把一套原型 Demo 变成长得像是“正经系统”的东西。你手里可能已经有了能跑通的代码,也可能刚读完一些概念,但真到了要把它变成可维护、可观测…

2026/10/2 0:00:20 阅读更多 →
大模型训练显存估计与混合精度训练实战指南

大模型训练显存估计与混合精度训练实战指南

1. 大模型训练显存估计与混合精度训练详解显存不够用,几乎是每个做大模型训练的人都会撞上的第一堵墙。你可能也经历过:模型代码写完了,数据管道跑通了,满心欢喜地按下训练启动脚本,结果几秒钟后终端弹出一行红字——C…

2026/10/2 0:00:20 阅读更多 →
小样本学习数据集选型指南:27个真正可用的高质量数据集

小样本学习数据集选型指南:27个真正可用的高质量数据集

1. 小样本学习的“弹药库”:为什么你总在找数据集,却总找不到真正能用的? 小样本、数据集——这两个词最近半年在我处理的200多个AI项目咨询里,出现频率排进前三。不是模型调不好,不是代码写不对,而是卡在…

2026/10/2 0:00:20 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/10/1 19:40:48 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/10/1 19:41:40 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/10/1 20:05:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 10:36:31 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 5:26:06 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 6:09:11 阅读更多 →