<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>絵夢の小站</title><description>满载的梦化与字句飘落</description><link>https://blog.emumu.xyz/</link><language>zh_CN</language><item><title>新建文件夹 (3)</title><link>https://blog.emumu.xyz/posts/2026-10-07-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-10-07-00/</guid><description>上大学之前，我简直是在瞎学。</description><pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;最近突然悟了。我不是学不好习，而是单纯不喜欢听课。&lt;/p&gt;
&lt;p&gt;在我看来别人分两种，学习好的，学习差的。有些是天生差人一截，听也听不懂，俗称笨，有些是天生强人一档，听一遍举一反三，俗称聪明，但也都是能听得进去课或者听不懂课的。我跳出三界之外，不在五行之中，我不听课。&lt;/p&gt;
&lt;p&gt;少数我在旁人看起来像是在认真听课的场景中，大概率是我在课下闲的没事把课本里的东西理解了个半斤八两，然后上课的时候嘉豪地接老师话，因为是事先学的，看起来像班里第一个懂了的，小学经常被说成神童。&lt;/p&gt;
&lt;p&gt;初中本身好，所有人都在预习，我也没了优势。不过这里豪一下，我自认为自己还算是比较聪明的，所以初中靠自学并没有到堕落的程度。不过高中模式开始全面大牢，我一整个反抗心理+未开智+不听课，就算再小聪明也是跟不上了。而且我的这种小聪明仅在一节一节课上的理科上有一点用，像语文英语这种单节课几乎没什么用、必须持之以恒才能提升的课就完全没有正反馈了，再加上发现豪不动之后全面堕落，连预习都不做了，自然坠机了。&lt;/p&gt;
&lt;p&gt;大学一开始还是堕落，但自从发现我可以随便上网搜并学自己喜欢的东西之后就开始逐渐开智了，python就是我在这期间掌握的。虽然不爱听课，但我爱思考 :spoiler[深度瞎想&amp;amp;反驳型人格]和问问题。问老师的话会问我为什么不听讲并骂我，但ChatGPT会非常正经地回答我，于是我开始在大学的自学极为有效。那时候ChatGPT还是时尚单品，claude-3.7和gpt-4o是我买不起的模型，很长一段时间是和3.5 turbo、4o-mini一起度过的。&lt;/p&gt;
&lt;p&gt;这也让我直到不久前还认为ai最应该进军教育界。在足有$1\times10^0$个样本级别的调查下，ai辅助学习真的很有成效。它相对于一对一家教的唯一劣势是给它看图的时候必须先拍照。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;那天我问别人，问：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;有问题为什么问我，不去问ai，ai能随时给你更全面的回答&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;他说人类能给他“他想要的回复”。比如说明确的“接下来xxx”的指示，而不是一大堆解释。我&lt;em&gt;可能&lt;/em&gt;明白了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;① &lt;em&gt;拒绝学习&lt;/em&gt;: 他们不想要一长串科普，只是想解决问题，尽管阅读完整的科普后他们就能完整掌握这个东西，他们不愿意阅读和掌握。&lt;/li&gt;
&lt;li&gt;② &lt;em&gt;无法解决问题&lt;/em&gt;: ai的解释差或难以理解。&lt;/li&gt;
&lt;li&gt;③ &lt;em&gt;活人依赖&lt;/em&gt;: 人类的解释更能给他们安全感。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对于②，一个ai的回答确实很大程度上取决于一个ai的水平。你敢信2026年ai还会把凹凸函数堂而皇之说反吗（明指豆包。事后以“部分国内教材”和“上凸下凸”强行解释）。&lt;/p&gt;
&lt;p&gt;但这样的错误回答在豆包回复里也不多，能真正解决问题的情况明显更多。除非你想事不带脑子，不然就真成信豆包tv了。&lt;/p&gt;
&lt;p&gt;对于①，我承认对于自己完全不懂的领域有时候确实也想得到最直接的做法了事，但另一方面，这是否也有&lt;em&gt;责任绑架&lt;/em&gt;的嫌疑呢？只要A愿意做出“指导”，B照着A的方法做了，一旦失败，B失败的责任伦理上便全是A的了。这也是强制“不能构成投资建议”的一个原因吧。伦理归伦理，生活中的小事总归没有那么严重，但总体上，问了别人并跟着做了之后，得到的要么是问题的正确解决方案，要么是正当的让别人给你收拾烂摊子的权利。只要A认真回答了，对B来说问题就解决了。当然这也仍然还是一个伦理上的推论。日常场景下A只要来一句“那我也不会了”就真的没招了。A如果这时候真的没招了，那哪怕A再有责任，B也没办法了。所以总体上并不能算责任绑架，只能算&lt;em&gt;责任附加&lt;/em&gt;。其实这件事和以前传统的“你不会百度吗”一样，不过当时②的效应更强，一方面是真的很难找到有效回答，另一方面是搜到的内容大多数有明显的学习成本，不去理解是不能用的。&lt;/p&gt;
&lt;p&gt;其实只要他们认真去看了问题相关的科普，他们自己就能解决。问题是上个decade很多人根本无法通过简单的搜索分辨自己接下来要学习的东西是个多深的坑，情有可原。&lt;/p&gt;
&lt;p&gt;③是最扑朔迷离的，考研搭子经常跟我请教数学，每个问题都能答上来的感觉还是挺爽的。为什么问问题不问ai，原因很迷，就是单纯的没这习惯。当然我也认为我的回答可能比ai更活人感一点，比如经常犯傻问题，IBNLT $ln(x**2)=2lnx$的各种变形。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ps:他经常公式崇拜（张宇书挺好，但我说实话公式真不要给太全吧，他经常背公式，比如$AA^*=|A|E$这种能推出几十个小公式的底层公式不背，他背那几十个小公式）。&lt;/p&gt;
&lt;p&gt;扯远了。不过教学法确实很有用。至少五种理论都分别说“教学”是学习的最终手段，这话真不假。&lt;/p&gt;
&lt;p&gt;又扯远了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;哪怕是学习，别人都是在“教师”的指导下进行的，教师有一种亲切感不假。但在我看来，一个亲切的老师真不如随时随地能找、能骗、能逗、又快、又什么都愿意跟我从头开始细细讲出来的ai。&lt;/p&gt;
&lt;p&gt;会用ai的人不一定被淘汰，不用ai的人一定会被淘汰。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;但这还不算真正的学习，纯粹兴趣驱动的学习的效率还是不够考研的。至少在9月之前，我甚至无法体会什么叫“每天学8小时”。:spoiler[他们不打游戏的吗？]&lt;/p&gt;
&lt;p&gt;今年我才算体验到什么叫真正的学习。可能是高中的时候学校觉得我们该知道的，不是在学校安排下的做题区那种盲目扭曲的被动学习，是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;知道自己&lt;em&gt;为了什么&lt;/em&gt;而学&lt;/li&gt;
&lt;li&gt;知道自己&lt;em&gt;要学什么&lt;/em&gt;，要学到&lt;em&gt;什么地步&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;知道自己&lt;em&gt;学到了&lt;/em&gt;什么&lt;/li&gt;
&lt;li&gt;知道自己学习的&lt;em&gt;进度&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;了解自己所使用的各种&lt;em&gt;学习方式&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;能&lt;em&gt;安排&lt;/em&gt;自己的学习时间和方式&lt;/li&gt;
&lt;li&gt;知晓自己在各学习方式下的&lt;em&gt;提升&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;清楚自己考高分/考上XX的&lt;em&gt;下一个目的&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;一定程度上&lt;em&gt;知晓自己的竞争力&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;在上大学之前，我简直是在瞎学。&lt;/p&gt;
</content:encoded></item><item><title>AI时代通识课: 大模型应用</title><link>https://blog.emumu.xyz/posts/2026-08-23-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-08-23-00/</guid><description>系统性介绍一个只能输出文本的AI是怎么在你眼前呈现各种东西的</description><pubDate>Mon, 24 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;在人工智能快速发展的今天，&lt;em&gt;大语言模型&lt;/em&gt;（Large Language Model, LLM）已经从实验室走向了大众日常的生产力场景。我确实认为大学生们，至少在靠AI写论文的大学生们，确实需要了解一些关于AI应用上的东西，而不是盲目地去买豆包专业版。&lt;/p&gt;
&lt;p&gt;不同于真的大学纯水通识课，本文不会说什么&lt;em&gt;神经网络&lt;/em&gt;、&lt;em&gt;Transformer&lt;/em&gt;这种底层知识，而是从实际落地出发，面向普通人介绍如今AI的&lt;strong&gt;真正能力边界&lt;/strong&gt;。对于非计算机专业背景的学习者而言，我们只需要学会如何正确、高效地与大模型进行交互，并将大模型的能力融合进现实的业务流程与工作流中。&lt;/p&gt;
&lt;h2&gt;一、大语言模型与文本生成式AI&lt;/h2&gt;
&lt;h3&gt;1.1 纯文本交互&lt;/h3&gt;
&lt;p&gt;大语言模型最基础的使用方式是&lt;em&gt;纯文本交互&lt;/em&gt;。用户通过输入自然语言&lt;em&gt;提示词&lt;/em&gt;（Prompt），模型根据概率预测逐字生成文本回复。&lt;/p&gt;
&lt;p&gt;纯文本交互的本质是上下文续写。模型并没有人类意义上的思考过程，而是基于海量数据训练出来的语言规律，根据当前输入的上文预测下一个最可能出现的词。在上下文中，历史消息以外的、针对当前任务的新消息称为&lt;em&gt;提示词&lt;/em&gt;。模型可接收到的所有文本（多模态模型包括图片等）称为&lt;em&gt;上下文&lt;/em&gt;。&lt;/p&gt;
&lt;p&gt;模型收到的上下文是多个被分类的块，包括一个&lt;em&gt;系统提示词&lt;/em&gt;、数个&lt;em&gt;用户消息&lt;/em&gt;、数个&lt;em&gt;模型输出&lt;/em&gt;和数个&lt;em&gt;工具调用结果&lt;/em&gt;。大模型厂商以此区分每段文本的身份定位，对模型进行针对性训练，这使得模型更能理解自己当前的角色进行回复，我们也能看到它明确的回答开始和结束。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;系统提示词&lt;/em&gt;由开发者设计。模型训练时通常被训练得不容易被透露给用户。遵循等级一般最高。&lt;/li&gt;
&lt;li&gt;&lt;em&gt;用户输入&lt;/em&gt;包含用户对模型下达的指令。模型分辨它们来自用户，在与系统冲突时模型会拒绝用户。&lt;/li&gt;
&lt;li&gt;&lt;em&gt;模型输出&lt;/em&gt;包含模型对以上所有内容所进行的回复。模型会读取历史的所有系统提示词、用户输入和模型输出，然后向用户输出文本作为回复。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph Sen1 [&quot; &quot;]
        direction TB
        S1[&quot;System&amp;lt;br&amp;gt;你是一个猫娘&quot;]
        U1[&quot;User&amp;lt;br&amp;gt;你好，请自我介绍一下&quot;]
        S1 --&amp;gt; U1
    end

    subgraph Sen2 [&quot; &quot;]
        direction TB
        S2[&quot;System&amp;lt;br&amp;gt;你是一个猫娘&quot;]
        U2[&quot;User&amp;lt;br&amp;gt;你好，请自我介绍一下&quot;]
        A2[&quot;Assistant&amp;lt;br&amp;gt;主人好喵~ 我是您的专属猫娘，今天想玩什么呢喵？&quot;]
        S2 --&amp;gt; U2 --&amp;gt; A2
    end
    
    subgraph Sen3 [&quot; &quot;]
        direction TB
        S3[&quot;System&amp;lt;br&amp;gt;你是一个猫娘&quot;]
        U3[&quot;User&amp;lt;br&amp;gt;你好，请自我介绍一下&quot;]
        A3[&quot;Assistant&amp;lt;br&amp;gt;主人好喵~ 我是您的专属猫娘，今天想玩什么呢喵？&quot;]
        U31[&quot;User&amp;lt;br&amp;gt;卡丘似了喵&quot;]
        S3 --&amp;gt; U3 --&amp;gt; A3 --&amp;gt; U31
    end

    Sen1 --&amp;gt;|发送| Sen2 --&amp;gt; Sen3

    style S1 fill:#FF4D4F,color:#000000,stroke:#D9363E,stroke-width:1px
    style S2 fill:#FF4D4F,color:#000000,stroke:#D9363E,stroke-width:1px
    style S3 fill:#FF4D4F,color:#000000,stroke:#D9363E,stroke-width:1px
    style U1 fill:#70DBFF,color:#000000,stroke:#33B5E5,stroke-width:1px
    style U2 fill:#70DBFF,color:#000000,stroke:#33B5E5,stroke-width:1px
    style U3 fill:#70DBFF,color:#000000,stroke:#33B5E5,stroke-width:1px
    style U31 fill:#70DBFF,color:#000000,stroke:#33B5E5,stroke-width:1px
    style A2 fill:#52C41A,color:#000000,stroke:#389E0D,stroke-width:1px
    style A3 fill:#52C41A,color:#000000,stroke:#389E0D,stroke-width:1px
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::tip&lt;/p&gt;
&lt;p&gt;纯文本中，中文和英文各自有一套标点符号，它们本质上就不是同一个字符。举例来说:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;英文逗号&lt;code&gt;,&lt;/code&gt;, 英文句号&lt;code&gt;.&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;中文逗号&lt;code&gt;，&lt;/code&gt;, 中文句号&lt;code&gt;。&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;纯文本在计算机领域也称&lt;em&gt;字符串&lt;/em&gt;。即一个个字符组成的串。&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;1.2 工具调用&lt;/h3&gt;
&lt;p&gt;在纯文本交互中，模型输出的内容完全由其内部预训练的参数和提供的上下文决定。这使得它无法实时获取外部信息（如查询今日天气或实时汇率），也无法准确执行复杂的数学计算或对外部系统发起真实操作。为了让模型理解“自主获取信息”的概念，&lt;strong&gt;工具调用系统&lt;/strong&gt;被训练、分化出来用于模型语义主动地获取信息。组成工具调用的基本功能包括&lt;em&gt;工具调用结果上下文&lt;/em&gt;和&lt;em&gt;模型工具调用输出&lt;/em&gt;。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;模型工具调用输出&lt;/em&gt;是模型的“手”。是模型在合适的上下文下输出的一种不同于纯文本的输出模式。它允许模型：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;以字符串方式指定一个工具，再通过某种参数化方式传入执行参数。其中参数化方式通常为JSON格式。&lt;/li&gt;
&lt;li&gt;获取工具调用的结果。工具调用应当是无需用户参与的。
模型在合适的上下文下才会进行工具调用。常见的情景是系统提示词包含了工具调用的说明时。此时模型就会遵循系统提示词的介绍进行工具调用。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;em&gt;工具调用结果上下文&lt;/em&gt;是模型的“眼”。在模型发出工具调用时，收到它的&lt;em&gt;处理机&lt;/em&gt;(&lt;em&gt;Harness&lt;/em&gt;)应当具有处理该工具调用的能力。在完成工具调用后，返回一个工具调用结果上下文插入上下文历史中，再次返还给模型进行续写。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;处理该工具调用的能力，具体来说，就是
&lt;ol&gt;
&lt;li&gt;识别模型给出的模型工具调用输出，提取对应的工具和参数。&lt;/li&gt;
&lt;li&gt;获取对应的工具，进行工具的执行。&lt;/li&gt;
&lt;li&gt;返回该工具的执行结果。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;模型可能会在多次请求中依次调用工具调用。也会在一次请求中并行附带多个工具调用。部分模型也支持模型同时输出工具调用和文本。&lt;/li&gt;
&lt;li&gt;语言大模型天生具有&lt;strong&gt;泛化性&lt;/strong&gt;。如果处理机返回“该工具不可调用”，模型会采取一系列措施绕过该方式，包括但不限于尝试使用其他方式、向用户说明服务确实暂时无法使用、甚至可以自行尝试修复处理机(或工具)本身。&lt;/li&gt;
&lt;li&gt;我们后续会称这种处理机为&lt;em&gt;Harness&lt;/em&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以&lt;strong&gt;AI应用&lt;/strong&gt;作为&lt;em&gt;Harness&lt;/em&gt;，一个完整的AI应用通过工具调用获取信息的完整工作流程为：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;开发者通过系统提示词等方式配置，将一系列可调用的工具（含&lt;strong&gt;工具名称&lt;/strong&gt;、&lt;strong&gt;功能描述&lt;/strong&gt;及&lt;strong&gt;所需参数格式&lt;/strong&gt;）告知模型。&lt;/li&gt;
&lt;li&gt;用户向AI应用发送指令，指令以用户消息的形式送达模型。&lt;/li&gt;
&lt;li&gt;当用户的指令需要借助外部工具时，模型输出一个结构化的工具调用输出，其中指定了模型要调用的&lt;strong&gt;工具名称&lt;/strong&gt;以及由模型填入的&lt;strong&gt;参数&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;AI应用捕获到模型的工具调用请求后，拦截该指令，并在现实世界中执行对应的代码逻辑或 API 调用。&lt;/li&gt;
&lt;li&gt;宿主程序将执行后获得的数据以&lt;em&gt;工具调用结果上下文&lt;/em&gt;的形式重新拼接到上下文中传回给模型。模型读取到最新的工具结果后，总结并输出最终面向用户的解答。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;flowchart TD
    subgraph S1 [&quot;System&quot;]
        S1_M[&quot;当前系统环境有python，你可以使用bash工具执行。&amp;lt;br&amp;gt;使用get_weather工具可以获得天气信息。&quot;]
    end
    
    subgraph U1 [&quot;User&quot;]
        U1_M[&quot;查一下北京今天的天气，顺便求解x+2=e^x&quot;]
    end

    subgraph A1 [&quot;Assistant&quot;]
	    direction TB
	    
	    M1_M1[&quot;我将查询北京天气并求解x+2=e^x..我们可以使用python计算...&quot;]
	    M1_TC1[&quot;工具调用&amp;lt;br&amp;gt;get_weather(&amp;lt;br&amp;gt;city=&apos;Beijing&apos;&amp;lt;br&amp;gt;)&quot;]
        M1_M2[&quot;工具调用&amp;lt;br&amp;gt;bash(bash=&amp;amp;quot;python -c &amp;amp;quot;import scipy.optimize...print...&amp;amp;quot;)&quot;]
        
        M1_End[&quot;停止原因: 工具调用&quot;]
        
        M1_M1 --&amp;gt; M1_TC1
        M1_M1 --&amp;gt; M1_M2
        M1_TC1 --&amp;gt; M1_End
        M1_M2 --&amp;gt; M1_End
    end

    subgraph TR1 [&quot;Harness 自动执行&quot;]
	    direction TB
	    TR1_M[&quot;终止原因为工具调用，Harness 执行工具调用&quot;]
        TR1_T1[&quot;Tool Result&amp;lt;br&amp;gt;get_weather&amp;lt;br&amp;gt;{&apos;temp&apos;: &apos;22℃&apos;, &apos;condition&apos;: &apos;晴&apos;}&quot;]
        TR1_T2[&quot;Tool Result&amp;lt;br&amp;gt;bash&amp;lt;br&amp;gt;{&apos;stdout&apos;: &apos;[-1.8414056604369606, 1.1461932206205825]&apos;, &apos;code&apos;: 0}&quot;]
        TR1_M --&amp;gt; TR1_T1
        TR1_M --&amp;gt; TR1_T2
    end

    subgraph A2 [&quot;模型整合输出回复&quot;]
        M2_T[&quot;北京今天天气晴朗，气温为 22℃。另外，$x+2=e^x$ 的两个根分别是 $x_1=-1.84140$, $x_2=1.14619$。&quot;]
    end

    S1 --&amp;gt; U1 --&amp;gt; A1 --&amp;gt; TR1 --&amp;gt; A2

    style U1 fill:#70DBFF,color:#000000,stroke:#33B5E5,stroke-width:1px
    style A1 fill:#52C41A,color:#000000,stroke:#389E0D,stroke-width:1px
    style TR1 fill:#FF4D4F,color:#000000,stroke:#D9363E,stroke-width:1px
    style A2 fill:#52C41A,color:#000000,stroke:#389E0D,stroke-width:1px
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过这种机制，大模型能够体现一定的&lt;em&gt;能动性&lt;/em&gt;，感知外部环境、调度多种计算资源。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;马克思主义认为，能动性(&lt;strong&gt;Agency&lt;/strong&gt;)是人区别于一般物的自觉活动能力，在实践基础上能动地认识世界和改造世界。&lt;/p&gt;
&lt;p&gt;在极为充分的Harness环境下，大模型体现了与人类极为相似的能动性，我们称这种组合体为&lt;strong&gt;Agent&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;s&gt;思考：Agent是否拥有主观能动性？&lt;/s&gt; :spoiler[马原背疯了说是]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h3&gt;1.3 处理机 (Harness)&lt;/h3&gt;
&lt;p&gt;模型本身只提供接收一段上下文，返回一段文本或工具调用的接口，而用户面对的是网页、终端或编辑器。介于二者之间、负责把请求送出去并把结果取回来的程序称为 &lt;em&gt;Harness&lt;/em&gt;。Harness 位于用户界面与模型之间，负责模型提供接口不做、但所有可以按预期自动化执行的任务。&lt;/p&gt;
&lt;p&gt;以一次普通的对话为例，Harness 至少完成了以下工作：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;拼装请求&lt;/strong&gt;：保存历史消息，在每次请求时把系统提示词、历史消息与用户的新输入按顺序拼接为完整的上下文，并携带 API 密钥发送给模型接口。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;接收与呈现输出&lt;/strong&gt;：接收模型返回的纯文本，流式输出时逐字显示在界面上；其中的标记语言交由渲染器转换为富文本。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;执行工具&lt;/strong&gt;：当模型输出工具调用时，解析其中的工具名与参数，执行这些工具，并把执行结果作为新的上下文块写回历史。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;管理上下文长度&lt;/strong&gt;：历史消息过长时，对上下文进行截断或摘要。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;处理异常与用量&lt;/strong&gt;：网络中断后的重试、接口限速的处理、用量与费用的统计。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;需要强调的是，Harness 不必提供工具调用功能（例如网页版对话界面也属于一种 Harness），但&lt;strong&gt;工具调用功能一定由 Harness 提供&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;:::note
Harness 一词的广泛使用出现于2026年，目前尚无正式的中文译名，各类资料中通常直接沿用英文原词。本文在行文中一律写作 Harness。&lt;/p&gt;
&lt;p&gt;“处理机”一词仅用于辅助理解，指的是 Harness 所处的位置，即处理模型请求与输出的那一层，并非通用译名。
:::&lt;/p&gt;
&lt;p&gt;:::note
在接口与用户之间的程序，在IT界也称为&lt;em&gt;前端&lt;/em&gt;。但由于对大模型的自动流程控制已经成为一个活跃新生领域，所以有必要对这类对接用户和大模型标准接口的程序作特殊讨论。本文将使用大量篇幅介绍Harness的原理。
:::&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;二、富文本&lt;/h2&gt;
&lt;p&gt;从上个世纪电脑刚普及开始，人们对于想在文本中指出&lt;strong&gt;重点&lt;/strong&gt;这件事上就一直非常努力。&lt;/p&gt;
&lt;p&gt;纯文本虽然能够完成绝大多数信息的传递，但在日常办公、学术研究和网页排版中，仅靠纯文本难以展现清晰的结构与视觉效果。包含加粗、标题、列表、表格甚至更奢侈的复杂样式的文本，我们称之为&lt;em&gt;富文本&lt;/em&gt;。&lt;/p&gt;
&lt;p&gt;在AI时代，掌握如何用纯文本字符来表达排版格式即&lt;em&gt;文本编码语法&lt;/em&gt;变得至关重要。因为大语言模型本质上只能输出纯文本字符串，它&lt;strong&gt;能且只能&lt;/strong&gt;通过生成特定的格式控制语法，再由 Harness 交给渲染器将其转换为视觉丰富的富文本界面。&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;2.1 图形界面工具与办公软件&lt;/h3&gt;
&lt;p&gt;在传统的办公环境中，我们最熟悉的是&lt;em&gt;可视化图形界面&lt;/em&gt;（GUI）工具，例如 Microsoft Office和 WPS Office（包括其中的Word、PowerPoint、Excel）。这类工具采用&lt;strong&gt;所见即所得&lt;/strong&gt;的模式，用户通过点击鼠标按键（如“加粗”、“设置字号”）来调整样式。点击功能按钮时，软件实际上将当前操作的文本/段落对应的数据结构进行修改。这个数据结构中包含了大量&lt;strong&gt;刻意对用户隐藏&lt;/strong&gt;的配置和样式，这使得用户界面十分简洁易用，但也经常导致找不到某个选项来进行某种修改。“字符底纹”和“文本突出显示颜色”就是一对这样的例子。&lt;/p&gt;
&lt;p&gt;我们无法展示Office的语法。它的语法不是一种语言，它们被层层压缩到文件中，纯文本基本无法描述Word文档。这样的工具也&lt;strong&gt;并不匹配大模型的工作逻辑&lt;/strong&gt;。人类使用图形界面的高效在于手眼协调，而模型有更好的方式编写带格式的文本，而不是输入文本后低效地模拟人类进行格式设置。&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;2.2 HTML5&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;HTML5&lt;/em&gt;（超文本标记语言，H5）负责定义网页的结构与内容（如段落、标题、图片、表格），而 &lt;em&gt;CSS&lt;/em&gt;（层叠样式表）则负责定义内容的视觉呈现（如颜色、字号、布局、动画）。我们不需要学习它的完整语法，仅了解它的有限特性即可。它的表示类似于：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;section&amp;gt;
	&amp;lt;h2&amp;gt;二级标题&amp;lt;/h2&amp;gt;
	&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;重点&amp;lt;/b&amp;gt;&amp;lt;i&amp;gt;区分&amp;lt;/i&amp;gt;&amp;lt;u&amp;gt;下划线&amp;lt;/u&amp;gt;&amp;lt;/p&amp;gt;
	&amp;lt;p style=&quot;font-size: 20pt; color: red&quot;&amp;gt;20磅 红色&amp;lt;/p&amp;gt;
&amp;lt;/section&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;显示起来就是：&lt;/p&gt;
&lt;p&gt;&amp;lt;div style=&quot;border: 3px solid gray;&quot;&amp;gt;
&amp;lt;section&amp;gt;
&amp;lt;h2&amp;gt;二级标题&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;重点&amp;lt;/b&amp;gt;&amp;lt;i&amp;gt;区分&amp;lt;/i&amp;gt;&amp;lt;u&amp;gt;下划线&amp;lt;/u&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;p style=&quot;font-size: 20pt; color: red&quot;&amp;gt;20磅 红色&amp;lt;/p&amp;gt;
&amp;lt;/section&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;一方面，HTML/CSS是&lt;strong&gt;现代互联网排版的基石&lt;/strong&gt;。互联网中几乎所有能看到的界面都可以通过它们实现。模型输出HTML/CSS代码，可以生成极其丰富且定制化程度极高的可交互界面。自然，几乎所有在Word文档中能做到的排版内容也都可以使用HTML/CSS实现。&lt;/p&gt;
&lt;p&gt;另一方面，如上所示，HTML实现简单的语法依赖大量而繁琐的&lt;strong&gt;前后闭合标签&lt;/strong&gt;，CSS依赖大量重复的关键词，这对上下文有限的大语言模型的理解上是不利的。模型生成冗长而繁琐的代码会消耗大量的&lt;em&gt;Token&lt;/em&gt;，导致响应速度变慢，且还容易因少写一个闭合标签而导致排版错乱。因此，在不需要复杂专业场景时，&lt;strong&gt;通常不会直接让模型输出原始的 HTML/CSS&lt;/strong&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;它们常被市场宣传统称为“HTML5 技术”，以至于你可以使用&quot;&lt;em&gt;H5&lt;/em&gt;&quot;来简称它。这默认包含了HTML5+CSS3。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;lt;style&amp;gt;
.__body .glass::after{content:&quot;&quot;;position:absolute;inset:-40%;background:linear-gradient(115deg,transparent 38%,rgba(255,255,255,.4) 50%,transparent 62%);transform:translateX(-120%);transition:transform .9s cubic-bezier(.2,.8,.2,1)}
.__body .glass:hover::after{transform:translateX(120%)}
.__body .glass:hover{transform:translateY(-8px) rotateX(5deg) rotateY(-4deg);box-shadow:0 30px 54px -24px rgba(0,0,0,.9)}
.__body .btn:hover{background-position:100% 0;transform:translateY(-2px) scale(1.04)}
.__body .ghost:hover{transform:translateY(-2px);box-shadow:0 14px 28px -14px #38bdf8;border-color:#38bdf8;color:#fff}
&amp;lt;/style&amp;gt;
&amp;lt;div class=&quot;__body&quot; style=&quot;border-radius:3rem;margin:0;padding:8px;display:flex;align-items:center;justify-content:center;perspective:1000px;font-family:system-ui,-apple-system,&apos;PingFang SC&apos;,&apos;Microsoft YaHei&apos;,sans-serif;-webkit-font-smoothing:antialiased;overflow-x:hidden;background:radial-gradient(1200px 600px at 8% -12%,#3b0764 0%,transparent 55%),radial-gradient(900px 520px at 100% 0%,#0e7490 0%,transparent 52%),radial-gradient(820px 620px at 50% 122%,#be185d 0%,transparent 56%),linear-gradient(160deg,#070b18,#0b1226 45%,#05070f);background-attachment:fixed&quot;&amp;gt;
&amp;lt;section class=&quot;glass&quot; style=&quot;position:relative;overflow:hidden;width:100%;max-width:560px;padding:8px 22px;border-radius:20px;border:1px solid rgba(255,255,255,.18);background:linear-gradient(150deg,rgba(255,255,255,.15),rgba(255,255,255,.04));backdrop-filter:blur(16px) saturate(1.4);-webkit-backdrop-filter:blur(16px) saturate(1.4);box-shadow:0 18px 38px -20px rgba(0,0,0,.9);transition:transform .45s cubic-bezier(.2,.8,.2,1),box-shadow .45s&quot;&amp;gt;
&amp;lt;h1 style=&quot;margin:0 0 2px;font-size:18px;font-weight:900;color:transparent;background:linear-gradient(92deg,#67e8f9,#a78bfa 40%,#f472b6 72%,#fbbf24);-webkit-background-clip:text;background-clip:text;filter:drop-shadow(0 6px 18px rgba(167,139,250,.45))&quot;&amp;gt;
这个内容块完全由HTML+CSS呈现
&amp;lt;/h1&amp;gt;
&amp;lt;p style=&quot;margin:0;font-size:14px;color:#9fb0d0&quot;&amp;gt;
确切来说，是在Markdown内容中嵌入的HTML。按钮没有实际功能。
&amp;lt;/p&amp;gt;
&amp;lt;div style=&quot;display:flex;flex-wrap:wrap;justify-content:center;gap:20px;margin-top:4px&quot;&amp;gt;
&amp;lt;button class=&quot;btn&quot; href=&quot;#&quot; style=&quot;padding:4px 18px;border-radius:999px;font-size:12px;font-weight:800;letter-spacing:.4px;text-decoration:none;color:#04121f;background:linear-gradient(92deg,#67e8f9,#a78bfa,#f472b6);box-shadow:0 12px 28px -14px rgba(167,139,250,.95);transition:background-position .6s ease,transform .25s ease&quot;&amp;gt;确定&amp;lt;/button&amp;gt;
&amp;lt;button class=&quot;ghost&quot; href=&quot;#&quot; style=&quot;padding:4px 18px;border-radius:999px;font-size:12px;font-weight:800;letter-spacing:.4px;text-decoration:none;color:#e9eefb;border:1px solid rgba(255,255,255,.28);background:rgba(255,255,255,.05);backdrop-filter:blur(8px);transition:transform .25s ease,box-shadow .25s ease,border-color .25s ease,color .25s ease&quot;&amp;gt;取消&amp;lt;/button&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/section&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;2.3 LaTeX&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;LaTeX&lt;/em&gt; 是一种基于 &lt;em&gt;Plain TeX&lt;/em&gt; 的排版系统，广泛应用于学术界、科研机构以及出版业。它能够精准处理高质量的文档排版，特别是在&lt;strong&gt;复杂数学公式&lt;/strong&gt;的呈现上具有不可替代的优势。对于有数学任务，模型经常主动在输出中使用LaTeX表达式来表达数学公式。它的表示类似于：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;\begin{cases}
\dfrac{-b \pm \sqrt{b^2 - 4ac}}{2a} \\[6pt]
s(x)=\displaystyle\int_0^x\sqrt{1+\left[y&apos;(t)\right]^2}\,dt
\end{cases}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以上代码将渲染为：&lt;/p&gt;
&lt;p&gt;$$
\begin{cases}
\dfrac{-b \pm \sqrt{b^2 - 4ac}}{2a} \[6pt]
s(x)=\displaystyle\int_0^x\sqrt{1+\left[y&apos;(t)\right]^2},dt
\end{cases}
$$&lt;/p&gt;
&lt;p&gt;大模型在解答数学题或撰写学术论文时，会自动将推导过程中的公式用 LaTeX 标记输出。Harness的&lt;strong&gt;渲染引擎&lt;/strong&gt;（如有，如MathJax或KaTeX）会自动将其转化为美观的公式图形。&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;2.4 Markdown&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Markdown&lt;/em&gt; 是一种&lt;em&gt;轻量级标记语言&lt;/em&gt;，它允许人们使用极为易读易写的纯文本格式编写文档，然后转换成有效HTML来显示。由于其语法简单、占用的 Token 少、对模型极度友好，Markdown 已成为大模型&lt;strong&gt;默认的富文本输出标准&lt;/strong&gt;。顺带一提，本博客使用 Markdown 进行写作。&lt;/p&gt;
&lt;p&gt;Markdown 语言创造者 John Gruber 说：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Markdown 不是 HTML 的替代品，甚至远远不是。它的语法只覆盖 HTML 的一个很小的子集。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;对于 Markdown 没覆盖的标记，你直接写 HTML 就行。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://daringfireball.net/projects/markdown/syntax&quot;&gt;Daring Fireball: Markdown Syntax Documentation&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;关于Markdown的基础语法，网上已有大量极为成熟、阅读时间不超过五分钟的教程，本文不再作冗长介绍。&lt;/p&gt;
&lt;p&gt;Markdown在发展过程中，不同的平台和软件对其语法进行了扩充，形成了多种&lt;em&gt;方言&lt;/em&gt;（Dialects）。大模型有时会自发地使用其中的一种或多种常见方言：&lt;/p&gt;
&lt;h4&gt;GFM (GitHub Flavored Markdown)&lt;/h4&gt;
&lt;p&gt;这是目前最流行的方言标准。在基础语法上增加了&lt;strong&gt;删除线&lt;/strong&gt;（&lt;code&gt;~~内容~~&lt;/code&gt;）、&lt;strong&gt;任务列表&lt;/strong&gt;（&lt;code&gt;- [x] 已完成&lt;/code&gt;）、&lt;strong&gt;自动链接&lt;/strong&gt;以及&lt;strong&gt;表格支持&lt;/strong&gt;。&lt;/p&gt;
&lt;h4&gt;LaTeX 数学公式&lt;/h4&gt;
&lt;p&gt;使用单个美元符号 &lt;code&gt;$&lt;/code&gt; 包裹以绘制&lt;em&gt;行内公式&lt;/em&gt;。例如 &lt;code&gt;$E = mc^2$&lt;/code&gt; 渲染为 $E = mc^2$。
使用双美元符号 &lt;code&gt;$$&lt;/code&gt; 包裹以绘制&lt;em&gt;块级公式&lt;/em&gt;，独占一行并居中。例如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$$
\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
$$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;渲染为&lt;/p&gt;
&lt;p&gt;$$
\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
$$&lt;/p&gt;
&lt;h4&gt;Mermaid 图表&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;Mermaid&lt;/em&gt; 是一种纯文本驱动的可视化图表生成器，Harness 将 Mermaid 语言的代码块转换为 Mermaid 图表。它的表示类似于：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;```mermaid
graph LR
A--&amp;gt;B
```
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;渲染为&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;graph LR
A--&amp;gt;B
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第一章中部分图表就使用Mermaid渲染。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;三、命令行&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;2026年初“小龙虾”爆火。圈外人也不知道为什么火，我圈内人也不知道为什么火。它既不万能也不无能，本质上还是个工具。我们上面已有&lt;strong&gt;工具调用&lt;/strong&gt;的基础，再谈它的底层原理就是一句话：&lt;/p&gt;
&lt;p&gt;“AI直接使用一台&lt;strong&gt;完整独立服务器命令行&lt;/strong&gt;作为&lt;strong&gt;工具调用&lt;/strong&gt;。”&lt;/p&gt;
&lt;p&gt;等等，什么是命令行？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;相比基于人类手眼协调操作所制作的图形界面软件，大模型更适合使用简洁明确的&lt;strong&gt;文本化交互方式&lt;/strong&gt;来进行工作。好在，这种交互模式早已成熟且仍然存在。&lt;/p&gt;
&lt;p&gt;2025年2月，Anthropic 发布了 Claude Code，这是一个直接在终端中运行的研究预览版 AI 编程工具，能够自主读代码、改文件、运行命令&lt;a href=&quot;https://notes.kamacoder.com/llm/claude/agent_cli.html&quot;&gt;(1)&lt;/a&gt;。随后，OpenAI 的 Codex CLI（2025年4月）和 Google 的 Gemini CLI（2025年6月）相继发布。这三大 AI 实验室的产品发布，标志着“&lt;strong&gt;大模型直接使用命令行&lt;/strong&gt;”作为一种主流产品范式的正式确立。它们都属于 Harness。&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;3.1 操作系统的命令行&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;命令行&lt;/em&gt;是通过输入文本指令来&lt;strong&gt;控制计算机操作系统&lt;/strong&gt;的界面。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Windows 操作系统&lt;/em&gt;：常见的命令行环境有 &lt;code&gt;cmd&lt;/code&gt;（命令提示符）和 &lt;code&gt;PowerShell&lt;/code&gt;。其中 PowerShell(pwsh) 功能更为强大，支持复杂的自动化脚本。&lt;/li&gt;
&lt;li&gt;&lt;em&gt;macOS / Linux 操作系统&lt;/em&gt;：使用的是基于 Unix/Linux 架构的终端（Terminal），默认的 Shell 环境通常为 &lt;code&gt;bash&lt;/code&gt; 或 &lt;code&gt;zsh&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::tip
Deepseek V4 pro 0813发布后被社区批评效果依赖特定环境。有反馈指出，该模型在 Linux 环境下表现正常，但在 Windows 上效果差。这被归因于模型对 &lt;strong&gt;Bash 语法&lt;/strong&gt;的高度依赖，在 Windows 的 PowerShell 环境中，其在处理引号、斜杠等语法时会出现困难，严重污染上下文，导致 Agent 能力下降。
:::&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;此处的“&lt;em&gt;控制计算机操作系统&lt;/em&gt;”要回到电脑&lt;strong&gt;没有图形界面&lt;/strong&gt;的年代去理解，一切操作是基于电脑&lt;strong&gt;没有可视化操作&lt;/strong&gt;实现的，我们使用&lt;em&gt;命令&lt;/em&gt;来进行所有基本操作，这包括创建删除修改查看文件和文件夹内容、以及运行各种&lt;strong&gt;命令行软件&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;命令行上以&lt;em&gt;字符&lt;/em&gt;为单位。在命令行上除了纯粹使用计算机执行的办公任务，没有什么“能玩”的东西。你能在命令行中看到分辨率最高的东西很可能是ascii艺术画。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;要让大模型对电脑进行操作(读取文件等)，使用人类的方式阅读屏幕、进行屏幕点击等模拟鼠标操作是&lt;strong&gt;极为低效&lt;/strong&gt;的。进入2026年后，大模型训练普遍提高了“&lt;strong&gt;智能体&lt;/strong&gt;”能力的训练权重，其中就包括对命令行操作的能力。&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;3.2 基本结构与约定规范&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;注意：本文中，我们不系统性地学习所有命令，此处只做基本的命令结构&lt;strong&gt;常识&lt;/strong&gt;介绍&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在命令行中，一条完整指令通常由&lt;em&gt;命令名称&lt;/em&gt;、&lt;em&gt;选项/参数&lt;/em&gt; 和&lt;em&gt;操作对象&lt;/em&gt;组成。我们仍然不需要学习各种命令的完整用法，也不需要背诵所有命令，仅了解它的有限特性即可。以 Linux/macOS 列出目录文件的命令为例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ls -l -a /home/user
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;命令&lt;/em&gt;：&lt;code&gt;ls&lt;/code&gt;（list，列出目录内容）。&lt;/li&gt;
&lt;li&gt;&lt;em&gt;选项&lt;/em&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-l&lt;/code&gt; - 使用长格式显示详细信息.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-a&lt;/code&gt; - 显示包含隐藏文件在内的所有文件.&lt;/li&gt;
&lt;li&gt;单个字母的参数通常以连字符 &lt;code&gt;-&lt;/code&gt; 开头.&lt;/li&gt;
&lt;li&gt;多个字母的参数以双连字符 &lt;code&gt;--&lt;/code&gt; 开头，如大多数应用都提供 &lt;code&gt;--help&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;多个单字母参数通常可以简写连写，如 &lt;code&gt;-la&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;操作对象（Argument）&lt;/em&gt;：&lt;code&gt;/home/user&lt;/code&gt;，指定要操作的目标路径。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;Pasted%20image%2020260930192842.png&quot; alt=&quot;命令的输出示例&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ls&lt;/code&gt; 是bash中最基础的用于查看目录下文件的命令。它和大量其他命令包括:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;pwd&lt;/code&gt; - 显示当前所在的绝对路径&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cd&lt;/code&gt; - 切换目录&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ls&lt;/code&gt; - 列出目录内容&lt;/li&gt;
&lt;li&gt;&lt;code&gt;touch&lt;/code&gt; - 创建空文件或更新文件时间戳&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mkdir&lt;/code&gt; - 创建目录&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cat/less/more/head/tail&lt;/code&gt; - 以各种方式查看文件&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cp&lt;/code&gt; - 复制文件或目录&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mv&lt;/code&gt; - 移动或重命名文件/目录&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rm&lt;/code&gt; - 删除文件或目录&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rmdir&lt;/code&gt; - 删除空目录&lt;/li&gt;
&lt;li&gt;&lt;code&gt;find&lt;/code&gt; - 在磁盘上查找文件或目录&lt;/li&gt;
&lt;li&gt;&lt;code&gt;grep&lt;/code&gt; - 在文件内容中搜索文本&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chmod&lt;/code&gt; - 修改文件权限&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chown&lt;/code&gt; - 修改文件属主&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;等一同组成一组控制电脑的基本文件系统操作，大模型会频繁大量使用这些命令来与文件系统交互，如&lt;strong&gt;阅读和修改文件代码&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;除了文件系统，还有如&lt;code&gt;ps&lt;/code&gt;以各种方式查看&lt;em&gt;进程&lt;/em&gt;等命令操作，但涉及较深操作系统相关知识，此处不再介绍。&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;3.3 Shell&lt;/h3&gt;
&lt;p&gt;单条命令通常只完成一个动作，实际任务则需要若干动作按顺序配合。为此，命令行提供了一套用于组合与控制的符号。这些符号由 &lt;em&gt;Shell&lt;/em&gt; 解释，而不是由被调用的程序解释。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Shell 允许把一条命令的输出直接交给另一条命令作为输入，这称为&lt;em&gt;管道&lt;/em&gt;（&lt;code&gt;|&lt;/code&gt;），中间结果不经过屏幕。管道可以连续使用，形成一条&lt;em&gt;处理链&lt;/em&gt;，每一环只负责一件事，这也是命令行软件普遍遵循的设计方式。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Shell 允许改变一条命令的输入来源与输出去向，称为&lt;em&gt;重定向&lt;/em&gt;，包括 &lt;code&gt;&amp;gt;&lt;/code&gt; 将输出写入文件，&lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; 将输出追加到文件末尾，&lt;code&gt;&amp;lt;&lt;/code&gt; 从文件读取输入，以代替键盘输入等。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Shell 允许把多条命令写在一行中，称为&lt;em&gt;命令的连接&lt;/em&gt;，如&lt;code&gt;;&lt;/code&gt; 依次执行，前一条失败也继续，&lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; 在前一条执行成功时才执行后一条，&lt;code&gt;||&lt;/code&gt; 在前一条执行失败时才执行后一条。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Shell 中可以使用 &lt;code&gt;*&lt;/code&gt; 匹配任意长度的任意字符。如 &lt;code&gt;*.md&lt;/code&gt; 表示当前目录下所有 Markdown 文件。使用 &lt;code&gt;?&lt;/code&gt; 匹配单个字符。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Shell 中表示字符串时，双引号 &lt;code&gt;&quot;AA$NAME&quot;&lt;/code&gt; 中的变量会被正常替换 &lt;code&gt;AAuser&lt;/code&gt;，单引号 &lt;code&gt;&apos;AA$NAME&apos;&lt;/code&gt; 中的内容一律按字面处理 &lt;code&gt;AA$NAME&lt;/code&gt;，反斜杠 &lt;code&gt;\&lt;/code&gt; 可以使其后的任意单个字符失去特殊含义，此反斜杠本身不会展示，可以使用 &lt;code&gt;\\&lt;/code&gt; 表示反斜杠本身(转义自身)。路径或文件名中含空格时需要用引号包裹。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;变量替换&lt;/em&gt;与&lt;em&gt;命令替换&lt;/em&gt;让一条命令的输出成为另一条命令的组成部分。&lt;code&gt;$HOME&lt;/code&gt;、&lt;code&gt;$PATH&lt;/code&gt; 等环境变量写在命令中，由 Shell 替换为具体值。&lt;code&gt;$(命令)&lt;/code&gt; 先执行括号内的命令，再把输出拼接进当前位置。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;以 &lt;code&gt;#&lt;/code&gt; 开头的部分为&lt;em&gt;注释&lt;/em&gt;，Shell 不会执行。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;示例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;LOG=/var/log/nginx/access.log
OUT=$HOME/nginx_report

mkdir -p &quot;$OUT&quot; &amp;amp;&amp;amp;  # 创建目录；成功才继续
    echo &quot;开始 $(date)&quot; &amp;gt;  # 输出开始时间，重定向到
    &quot;$OUT/report.txt&quot; ||  # 报告文件；如果前面失败
    echo &quot;创建目录失败&quot; &amp;gt;&amp;gt;  # 记录错误到
    /tmp/nginx_report.err  # 错误文件

grep &apos; 500 &apos; &quot;$LOG&quot; |  # 筛选 500 错误
    awk &apos;{print $1}&apos; |  # 提取第一列 IP
    sort |  # 排序
    uniq -c |  # 去重并计数
    sort -nr &amp;gt;  # 按次数降序排序，并重定向到
    &quot;$OUT/500_ips.txt&quot;  # 结果文件

wc -l &amp;lt;  # 从文件读取输入，统计行数
    &quot;$OUT/500_ips.txt&quot; &amp;gt;&amp;gt;  # 输入文件；追加到
    &quot;$OUT/report.txt&quot;  # 报告文件

cd &quot;$OUT&quot; ||  # 进入输出目录；失败则
    exit 1;  # 退出；然后依次执行
tar -czf 500_ips.tgz 500_ips.txt report.txt  # 打包结果文件

echo &quot;结束 $(date)&quot; &amp;gt;&amp;gt;  # 追加结束时间到
    &quot;$OUT/report.txt&quot;  # 报告文件
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;实际上模型更可能输出这样的命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DIR=/tmp/shell_demo; FILE=&quot;$DIR/report.txt&quot;; mkdir -p &quot;$DIR&quot; &amp;amp;&amp;amp; echo &quot;开始 $(date)&quot; &amp;gt; &quot;$FILE&quot; || echo &quot;初始化失败 $(date)&quot; &amp;gt;&amp;gt; /tmp/shell_demo_error.log; grep -v &apos;^#&apos; &amp;lt; /etc/hosts | sort | uniq &amp;gt; &quot;$DIR/hosts.txt&quot;; wc -l &amp;lt; &quot;$DIR/hosts.txt&quot; &amp;gt;&amp;gt; &quot;$FILE&quot;; echo &quot;完成 $(date)&quot; &amp;gt;&amp;gt; &quot;$FILE&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;用于极为复杂的单次自动化操作。&lt;/p&gt;
&lt;p&gt;以上关于Shell语法的内容作为拓展掌握，掌握后我们可以基本识别模型对电脑进行的操作大意。&lt;/p&gt;
&lt;p&gt;:::note
以上符号只对 Shell 有意义。Harness 执行命令时，需要把整条命令交给 Shell 解释（通常写作 &lt;code&gt;bash -c &quot;...&quot;&lt;/code&gt;），而不是把第一个词当作程序名直接启动；否则 &lt;code&gt;|&lt;/code&gt;、&lt;code&gt;&amp;gt;&lt;/code&gt; 会被当作普通参数传给程序。命令行之所以难以被单个工具调用替代，原因也在这里。
:::&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;3.4 命令行软件&lt;/h3&gt;
&lt;p&gt;除了操作系统自带的基础命令外，开发者和用户还会安装各种&lt;em&gt;命令行软件&lt;/em&gt;来完成特定任务。&lt;/p&gt;
&lt;p&gt;这些软件提供了复杂的功能，如 &lt;code&gt;curl&lt;/code&gt;（网络请求工具）、&lt;code&gt;git&lt;/code&gt;（代码版本控制工具）、&lt;code&gt;ffmpeg&lt;/code&gt;（音视频处理工具）、&lt;code&gt;markitdown&lt;/code&gt;（二进制文件转文本工具）、甚至 &lt;code&gt;python&lt;/code&gt; 这种家喻户晓的编程语言本身，在没有外部封装的情况下也是需要使用命令行调用的。它们同样&lt;strong&gt;完全使用命令行进行操作&lt;/strong&gt;，而且是相当一部分图形界面软件内部调用的基础组件。&lt;/p&gt;
&lt;p&gt;大模型可以通过上一章提到的工具调用能力，将复杂的业务需求转化为一行具体的 &lt;em&gt;CLI&lt;/em&gt; 工具命令并交给 Harness 执行。例如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ffmpeg -i input.mp4 -vn -acodec libmp3lame output.mp3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;模型通过输出上述命令，直接将一段视频文件中的音频提取为 MP3 格式。&lt;/p&gt;
&lt;p&gt;:::note
大多命令行应用的反馈是输出简单的一串文本，但有一部分命令行应用提供复杂的命令行界面。它们或是受复杂的功能所限，在运行时可能需要同时显示大量信息如 &lt;code&gt;vim&lt;/code&gt;（常说的大神编辑器）；或是专门提供特殊的功能，如 &lt;code&gt;tail -f&lt;/code&gt; 用于动态跟踪文件更改；或是单纯用于提供图形化体验，如 &lt;code&gt;cacaplay&lt;/code&gt; 用于使用ascii艺术播放视频。这些命令行界面应用&lt;strong&gt;对人类友好&lt;/strong&gt;，但&lt;strong&gt;对大模型的交互并不友好&lt;/strong&gt;，一般来说大模型也用不上这些工具。&lt;/p&gt;
&lt;p&gt;命令行界面也有表述：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;CLI (Command-Line Interface)&lt;/em&gt; - 命令行界面&lt;/li&gt;
&lt;li&gt;&lt;em&gt;TUI (Terminal User Interface)&lt;/em&gt; - 终端用户界面&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;3.5 命令输出与控制流&lt;/h3&gt;
&lt;p&gt;任何软件在退出后都会输出一个退出状态码。&lt;em&gt;退出状态码&lt;/em&gt;(&lt;em&gt;Exit Code&lt;/em&gt;)是程序执行结束后向系统返回的一个整数数值。按通用约定，退出码为&lt;code&gt;0&lt;/code&gt;表示执行成功，非 &lt;code&gt;0&lt;/code&gt; 的值（如 &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;127&lt;/code&gt; 等）表示出现了某种异常或错误。&lt;/p&gt;
&lt;p&gt;不考虑复杂的命令行控制，软件还可以以纯文本的形式向两个特殊的文件&lt;em&gt;标准输出&lt;/em&gt;(&lt;code&gt;stdout&lt;/code&gt;)和&lt;em&gt;标准错误&lt;/em&gt;(&lt;code&gt;stderr&lt;/code&gt;)去输出文本。一般地，程序正常运行产生的结果文本将输出到标准输出，也就是命令行所看到的标准输出。程序运行失败时返回的错误原因或警告日志会输出到标准错误。这两个输出也是 Harness 执行命令后向模型发送的主要内容。通常我们在编程语言中学习各种print，其本质就是向标准输出输出了文本。&lt;/p&gt;
&lt;p&gt;大模型在调度命令行时，Harness 会捕获命令的&lt;em&gt;标准输出&lt;/em&gt;、&lt;em&gt;标准错误&lt;/em&gt;和&lt;em&gt;退出状态码&lt;/em&gt;并拼接到上下文中。模型通过阅读这些输出文本，能够判断命令是否执行成功，若执行成功，模型继续推进下一步任务。若报错（Exit Code $\neq$ 0），模型会读取错误日志（&lt;code&gt;stderr&lt;/code&gt;），在下一个回合中&lt;strong&gt;自主修改命令参数并重新尝试&lt;/strong&gt;，实现自我纠错与自动化控制。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;四、智能体 (Agent)&lt;/h2&gt;
&lt;p&gt;让模型自动地完成所有任务的模糊概念在2023年就有出现，但由于当时及其后的模型的智能和上下文不足、Harness 的概念不够完善导致模型出现无法有效进行工具调用、无法有效循环等问题。&lt;/p&gt;
&lt;p&gt;2026年2月5日，Mitchell Hashimoto 的博客&lt;a href=&quot;https://mitchellh.com/writing/my-ai-adoption-journey&quot;&gt;My AI Adoption Journey&lt;/a&gt;，正式提出了 “Harness Engineering” 这一术语。其核心理念是“每当 AI 犯错，就工程化一个方案让它不再犯同样错”，即通过&lt;strong&gt;构建外部系统&lt;/strong&gt;来引导和修正模型行为。这为后来“Harness”作为模型之外一切控制机制的总和奠定了概念基础。&lt;/p&gt;
&lt;p&gt;$\text{ Agent = Model + Harness }$将“Harness”定义为&lt;strong&gt;模型权重之外的一切&lt;/strong&gt;，包括系统提示词、工具调度、上下文管理、权限控制、错误恢复等所有工程化组件。&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;4.1 工作循环&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;智能体&lt;/em&gt;(&lt;em&gt;Agent&lt;/em&gt;)是由大语言模型与具备工具执行能力的 Harness 组合而成、能够在无需人工干预的情况下连续完成多步任务的系统。&lt;/p&gt;
&lt;p&gt;单次工具调用的具体过程已经在1.2节有所介绍：模型输出工具调用，Harness 执行该调用，执行结果被写入上下文，模型据此生成回答。智能体与这一过程的区别在于，&lt;strong&gt;目标未必是“回答用户的问题”，而是在修改、运行、测试的工具调用循环中得到一个目标完成的结果&lt;/strong&gt;，工具调用过程会被反复执行，直到满足终止条件为止。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;%%{init: {&quot;themeVariables&quot;:{&quot;actorBkg&quot;:&quot;#70DBFF&quot;,&quot;actorBorder&quot;:&quot;#33B5E5&quot;,&quot;actorTextColor&quot;:&quot;#000000&quot;}}}%%
sequenceDiagram
    actor U as 用户
    participant H as Harness
    participant M as 模型
    
    Note over H: 创建空上下文
    Note over H: 注入系统提示词
    U-&amp;gt;&amp;gt;H: 任务说明
    Note over H: 注入用户任务说明
    loop
        H-&amp;gt;&amp;gt;+M: 上下文
        Note over M: 模型决策输出
        M-&amp;gt;&amp;gt;-H: 输出文本或工具调用&amp;lt;br&amp;gt;包括阅读修改测试等
        alt 进行任务时&amp;lt;br&amp;gt;返回工具调用
            M-&amp;gt;&amp;gt;H: 工具名与参数
            Note over H: 执行工具调用
            Note over H: 注入工具调用结果
        else 完成任务时&amp;lt;br&amp;gt;输出文本
            M-&amp;gt;&amp;gt;H: 任务完成回答
            Note over H: 结束
        end
    end
    H-&amp;gt;&amp;gt;U: 任务完成回答
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;单个循环由三个环节构成：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;模型决策输出&lt;/em&gt;：模型读取 Harness 提供的上下文，模型运行，输出文本或工具调用。&lt;/li&gt;
&lt;li&gt;&lt;em&gt;执行工具调用&lt;/em&gt;：Harness 将工具调用格式识别为对文件系统、命令行或网络接口等的实际操作，运行并收集其输出。&lt;/li&gt;
&lt;li&gt;&lt;em&gt;注入工具调用结果&lt;/em&gt;：将执行结果作为新的上下文块(即&lt;em&gt;工具调用结果上下文&lt;/em&gt;)追加到消息历史中，成为下一次决策的输入。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;模型不保存状态&lt;/strong&gt;。每次续写都是一次独立的调用，输入为上下文，输出为文本或工具调用。所谓“聊天记录”，实际来源是 Harness 每一轮重新提交的完整历史。上下文是系统中唯一的状态载体。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;上下文长度是有限资源&lt;/strong&gt;。随着轮次增加，历史消息不断累积，接近最大上下文的同时每轮的费用均会上升。为提高长线任务时长，主流 Harness 会采取&lt;em&gt;窗口法&lt;/em&gt;或&lt;em&gt;压缩法&lt;/em&gt;保证上下文不超过上下文最大长度。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;窗口法&lt;/em&gt;：直接丢弃最早的若干轮消息，可能造成模型上下文行为的混乱。窗口法下任务循环不会暂停，开销较为稳定，适合连续简单机械任务的场景。在连续稳定结构的上下文示例下，模型也会产出更稳定的输出。&lt;/li&gt;
&lt;li&gt;&lt;em&gt;压缩法&lt;/em&gt;：将消息历史总结为&lt;strong&gt;摘要&lt;/strong&gt;。总结过程由一次模型请求完成。总结时，Harness 对上下文&lt;strong&gt;附加一个总结要求&lt;/strong&gt;，然后将当前的完整上下文和要求发给模型，获取模型对上下文的总结摘要，再挑选上下文中其余必要的部分，组成一个新的上下文作为新一轮的上下文。压缩法会产生一次额外的模型请求，但在有效的降低成本和流程接续效果下无疑是值得的。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;正常情况下，当&lt;strong&gt;模型不再输出工具调用&lt;/strong&gt;、&lt;strong&gt;用户主动中断&lt;/strong&gt;、&lt;strong&gt;循环达到 Harness 预设的步数或时间上限&lt;/strong&gt;时，循环将终止。但如模型 API 无响应这类可能导致工作运行异常，但有可能修复的问题，Harness 有责任进行处理（如限制重试次数地重试调用模型请求）。&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;4.2 能力边界&lt;/h3&gt;
&lt;p&gt;智能体的能力由模型、Harness 和工具条件共同决定，任何一方不足都会导致任务无法完成。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;模型能力不足&lt;/strong&gt;时，智能体可能：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;无法理解工具调用，完全无法做到有效的事件循环。&lt;/li&gt;
&lt;li&gt;进行基础的工作，但缺乏测试甚至陷入循环无法交付。&lt;/li&gt;
&lt;li&gt;在遇到问题时，无法给出有效的解决方案，错误将问题归因后结束循环&lt;/li&gt;
&lt;li&gt;能完成测试等循环逻辑，但循环极长导致大量循环消耗。&lt;/li&gt;
&lt;li&gt;使用较差的方法解决问题，可能产生各种额外问题需要解决。&lt;/li&gt;
&lt;li&gt;能完成任务，但无法充分理解任务隐含情境导致结果不佳。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Harness 或工具能力不足&lt;/strong&gt;时，智能体可能：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;没有有效的完成工作途径。目标在框架下未被提供转化为现实的充分根据和必要条件。&lt;/li&gt;
&lt;li&gt;因工具说明不足频繁导致问题，提供的工具被模型认为“不好用”。或花费大量时间测试 Harness 提供的工具是否有效。&lt;/li&gt;
&lt;li&gt;上下文管理不当导致模型遗忘初始任务、陷入死循环或超出 Token 限制。&lt;/li&gt;
&lt;li&gt;导致沙箱逃逸，向模型泄露隐私和不安全接口。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::caution
&lt;strong&gt;Agent 的可执行范围等同于其获得的权限&lt;/strong&gt;。获得 shell 权限的 Agent 可以删除文件系统中的文件；获得浏览器控制权的 Agent 可以使用当前已登录的账号执行操作；持有 APIKey 的 Agent 可以产生费用。&lt;/p&gt;
&lt;p&gt;Harness 通常会在系统提示词中写入限制性条款，但&lt;strong&gt;系统提示词属于文本约束，而非权限机制&lt;/strong&gt;。对危险操作的约束应由沙箱、路径白名单、执行前确认等工程手段实现。
:::&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;4.3 模型的接入&lt;/h3&gt;
&lt;p&gt;接入一个模型需要三类信息：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;接口地址（BaseUrl）&lt;/em&gt;：模型服务的请求地址。每个服务商的每种格式接口地址通常固定。&lt;/li&gt;
&lt;li&gt;&lt;em&gt;API 密钥（APIKey）&lt;/em&gt;：调用者的&lt;strong&gt;身份凭证&lt;/strong&gt;，通常为 &lt;code&gt;sk-&lt;/code&gt; 开头的一串字符。&lt;/li&gt;
&lt;li&gt;&lt;em&gt;模型标识（model id）&lt;/em&gt;：用于指定&lt;strong&gt;实际调用的模型&lt;/strong&gt;。同一平台通常提供多个模型，其能力与价格各不相同。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;模型接口目前主要有四种协议：&lt;strong&gt;Chat Completions API&lt;/strong&gt;, &lt;strong&gt;Anthropic Messages API&lt;/strong&gt;, &lt;strong&gt;Google API&lt;/strong&gt;, &lt;strong&gt;Responses API&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;协议&lt;/th&gt;
&lt;th&gt;提出方&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Chat Completions API&lt;/td&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;出现最早，为绝大多数平台默认提供&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anthropic Messages API&lt;/td&gt;
&lt;td&gt;Anthropic&lt;/td&gt;
&lt;td&gt;Claude 系列模型使用的协议，Claude Code 默认使用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google Gemini API&lt;/td&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;Gemini 系列模型使用的协议&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Responses API&lt;/td&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;较新的接口格式，Codex 默认使用&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;em&gt;接口地址&lt;/em&gt;通常随协议而异。以 Deepseek 为例，官方提供Chat Completions API, Anthropic Messages API 和 Responses API. 三种接口均在官方文档中说明，分别为&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://api.deepseek.com/chat/completions
https://api.deepseek.com/anthropic
https://api.deepseek.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://api-docs.deepseek.com/zh-cn/&quot;&gt;首次调用 API&lt;/a&gt;, &lt;a href=&quot;https://api-docs.deepseek.com/zh-cn/guides/anthropic_api&quot;&gt;使用 Anthropic API&lt;/a&gt;, &lt;a href=&quot;https://api-docs.deepseek.com/zh-cn/guides/responses_api&quot;&gt;使用 Responses API&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;API 密钥的价值等同于账户的支付权限&lt;/strong&gt;，不应写入公开的代码仓库、截图或聊天记录。密钥一旦泄露，应立即在服务方后台吊销并重新签发。&lt;/p&gt;
&lt;p&gt;模型的提供方可分为三类：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;官方直连&lt;/em&gt;：由模型所有者直接提供，稳定性最好，价格最高。&lt;/li&gt;
&lt;li&gt;&lt;em&gt;聚合与中转&lt;/em&gt;：转发请求或转售套餐额度。此类服务的价格可能高于或低于官方，使用前应确认其来源与计费方式。&lt;/li&gt;
&lt;li&gt;&lt;em&gt;来源不明的渠道&lt;/em&gt;：价格显著低于官方，存在额度来源不明、以低能力模型冒充高能力模型等风险，除非运营商可识别且可信，否则不建议在正式工作中使用。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;模型按 &lt;em&gt;token&lt;/em&gt; 计费，输入与输出分别定价，输出的单价通常高于输入。此外，&lt;strong&gt;上下文在每一轮循环中都会被重新提交&lt;/strong&gt;，其中的重复部分会被重复计费。多数平台对前缀完全相同的重复请求提供缓存折扣，Harness 因此通常将系统提示词固定在上下文开头。&lt;/p&gt;
&lt;p&gt;模型调用时，至少需要提供&lt;em&gt;模型标识&lt;/em&gt;以指明本次将调用的具体模型。对于 Harness 而言，也需要提供&lt;em&gt;上下文窗口&lt;/em&gt;和&lt;em&gt;单次最大输出 token&lt;/em&gt; 用以对上下文进行控制。部分支持&lt;em&gt;思考强度&lt;/em&gt;自定义的模型也可以选择输入此次回答的思考强度档位。&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;4.4 Harness&lt;/h3&gt;
&lt;p&gt;Harness 位于用户界面与模型之间，负责模型没有做、用户也不应亲自去做的事。网页版对话界面对应的也是一种 Harness，其区别在于&lt;strong&gt;未向模型提供任何工具&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;按交互形态，Harness 可分为三类：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;GUI（图形用户界面）&lt;/em&gt;：以网页或桌面应用的形式提供，使用门槛最低。&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CLI / TUI（终端用户界面）&lt;/em&gt;：在终端中运行，便于与命令行工具配合使用。&lt;/li&gt;
&lt;li&gt;&lt;em&gt;IDE（集成开发环境）&lt;/em&gt;：以编辑器插件的形式提供，面向代码相关工作。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;部分产品同时提供多种形态，支持 TUI 的产品通常也可以嵌入 VSCode 等编辑器。常见 Harness 见于下表。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;名称&lt;/th&gt;
&lt;th&gt;提供方&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cursor&lt;/td&gt;
&lt;td&gt;Anysphere&lt;/td&gt;
&lt;td&gt;IDE形态，面向编程任务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code&lt;/td&gt;
&lt;td&gt;Anthropic&lt;/td&gt;
&lt;td&gt;TUI为主要形态，面向编程任务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Codex&lt;/td&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;TUI与GUI，面向通用任务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cherry Studio&lt;/td&gt;
&lt;td&gt;上海千彗&lt;/td&gt;
&lt;td&gt;GUI，面向万能向的产品&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trae&lt;/td&gt;
&lt;td&gt;字节跳动&lt;/td&gt;
&lt;td&gt;IDE形态，国内较早期产品&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenCode&lt;/td&gt;
&lt;td&gt;开源社区&lt;/td&gt;
&lt;td&gt;TUI与GUI，开源，可接入多家模型供应商&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ZCode&lt;/td&gt;
&lt;td&gt;智谱&lt;/td&gt;
&lt;td&gt;GUI，国内较成熟产品&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DSH&lt;/td&gt;
&lt;td&gt;DeepSeek&lt;/td&gt;
&lt;td&gt;GUI，仍在测试阶段，提供插件扩展机制&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;该表仅列出较有代表性的产品，同类产品仍在不断增加。各模型厂商大多会自行开发一款 Harness，其原因之一是&lt;strong&gt;模型的 Agent 能力训练本身就需要一个稳定的 Harness 环境&lt;/strong&gt;。由于不同 Harness 在工具定义与上下文管理策略上存在差异，&lt;strong&gt;同一模型在不同 Harness 上的表现也会有所不同&lt;/strong&gt;，一般匹配模型的厂商的 Harness 效果更好。选择 Harness 时应以使用场景为依据，上述和本表未列出的其他常见 Harness 绝大多数都具备完善的命令行、循环等机制，在考虑所有模型的情况下效果不分伯仲。本节不对具体产品作优劣评价。&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;4.5 工具、MCP 与 SKILL&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;WIP...&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;:::note
&lt;strong&gt;命令行是最通用的工具接口&lt;/strong&gt;。绝大多数提供命令行调用方式的软件，模型都可以通过 shell 直接调用，无需专门适配，是“&lt;strong&gt;操作操作系统的工具&lt;/strong&gt;”。这也是第三章先行介绍命令行的原因。
:::&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;4.6 常见工作区约定&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;特殊文件：AGENTS.md 与 CLAUDE.md 会自动进入上下文。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;WIP...&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;结语&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;本文原稿由AI生成，由人类大幅修改(修改部分大于50%)。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;Pasted%20image%2020261002231221.png&quot; alt=&quot;展示工作量.jpg&quot; /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>【学习笔记】数学笔记其九 · 常微分方程</title><link>https://blog.emumu.xyz/posts/2026-08-18-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-08-18-00/</guid><description>大boss来了（意外地好打？）</description><pubDate>Tue, 18 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;如果你是首次进入我的新数学笔记系列, 请先&lt;a href=&quot;/posts/2026-07-09-00/&quot;&gt;点此阅读预告回&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;常微分方程这一章总体感觉就是，你一路上体验过了各种新玩法新机制，但这些新机制大多只能在任务点内部用。终于快把主线打通了，什么叫大boss场地里不仅有新机制，还要用到以前所有的机制？&lt;/p&gt;
&lt;p&gt;数二的本章新机制&lt;strong&gt;常微分方程&lt;/strong&gt;是最有模板感的。计算全是流水线。每一种能考的方程都配好了指定解法，认出即可机械动笔。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;概念&lt;/strong&gt;。什么是微分方程、阶、解、通解特解、线性与齐次。专供小题。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;解法&lt;/strong&gt;。数二范围内的每种方程都有一张身份证，认型套模板。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;超级拼装&lt;/strong&gt;。把一个微分方程和极限/积分/几何题生硬地上下连接在一起，这就是你数二最有魅力的样子。&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;数二范围:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一阶可分离变量的常微分方程&lt;/li&gt;
&lt;li&gt;N阶线性&amp;lt;u&amp;gt;线性齐次&amp;lt;/u&amp;gt;常微分方程&lt;/li&gt;
&lt;li&gt;一阶线性&amp;lt;u&amp;gt;线性齐次和线性非齐次&amp;lt;/u&amp;gt;常微分方程&lt;/li&gt;
&lt;li&gt;二阶&amp;lt;u&amp;gt;线性齐次&amp;lt;/u&amp;gt;常系数线性常微分方程&lt;/li&gt;
&lt;li&gt;二阶&amp;lt;u&amp;gt;有特定的线性非齐次项&amp;lt;/u&amp;gt;常系数线性常微分方程&lt;/li&gt;
&lt;li&gt;一阶&amp;lt;u&amp;gt;代数齐次&amp;lt;/u&amp;gt;可转化为线性的常微分方程&lt;/li&gt;
&lt;li&gt;可降阶的N阶常微分方程&lt;/li&gt;
&lt;li&gt;在提示的转换下，任意可换元转化为以上范围的常微分方程&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2&gt;微分方程&lt;/h2&gt;
&lt;p&gt;微分方程就是&lt;strong&gt;含有未知函数导数（或微分）的等式&lt;/strong&gt;，目标是求出那个函数。比如
$$
y&apos; = 2x, \quad y&apos;&apos; + y = 0, \quad (y&apos;)^2 + xy = e^x
$$
第一个的解是$y = x^2 + C$；第二个是$y = C_1\cos x + C_2\sin x$；第三个……第三个不是数二会考的东西，它不会出现在卷子上，&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;阶数&lt;/strong&gt;: 方程中最高阶导数的阶数。
&lt;ul&gt;
&lt;li&gt;$y&apos;&apos; + y = 0$是二阶&lt;/li&gt;
&lt;li&gt;$y^{(4)} - 5y&apos;&apos; + 10y&apos; - 6y = 0$是四阶。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;通解&lt;/strong&gt;: 含任意常数的解，表示一个函数集合。
&lt;ul&gt;
&lt;li&gt;$y = C_1\cos x + C_2\sin x$是一个通解&lt;/li&gt;
&lt;li&gt;任意常数的个数 = 方程的阶数。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;解&lt;/strong&gt;: 代入后使方程成立的一个函数。
&lt;ul&gt;
&lt;li&gt;$y = 0$是一个解&lt;/li&gt;
&lt;li&gt;$y = 666\cos x + 999\sin x$是一个解&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;特解&lt;/strong&gt;: 用初值条件把通解里的常数定死之后得到的解。
&lt;ul&gt;
&lt;li&gt;初值条件如$y(x_0) = y_0,\ y&apos;(x_0) = y_1$.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;初值问题&lt;/strong&gt;: 微分方程 + 初值条件，也叫柯西问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;常微分方程难在没有万能解法，但部分特定形态的函数古人们已经解出来了，其中一部分简单的进入了考纲。&lt;/p&gt;
&lt;p&gt;本章这个没意思的新机制就是&lt;strong&gt;认方程，套模板&lt;/strong&gt;。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;线性&lt;/th&gt;
&lt;th&gt;非线性&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;齐次&lt;/td&gt;
&lt;td&gt;特征方程（常系数）；一阶的直接分离&lt;/td&gt;
&lt;td&gt;分离变量、换元法&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;非齐次&lt;/td&gt;
&lt;td&gt;齐次通解 + 特解 + 叠加原理&lt;/td&gt;
&lt;td&gt;换元转换到齐次&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;线性性&lt;/h3&gt;
&lt;p&gt;$y$和它的各阶导数只以一次幂出现、没有互相相乘、没有复合。
$$
\textcolor{lime}{ y&apos;&apos; + p(x)y&apos; + q(x)y } = f(x)
$$
方程关于$y, y&apos;, y&apos;&apos;, \dots$是&lt;strong&gt;一次&lt;/strong&gt;的。左边是一个线性算子$L[y] = y&apos;&apos; + p y&apos; + q y$作用在$y$上。&lt;/p&gt;
&lt;p&gt;$(y&apos;)^2$, $yy&apos;$, $\sin y$都是非线性的。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;算子，即函数的函数，接受一个函数，表达一个函数。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;线性性是本章最重要的性质，它带来叠加原理和解空间的线性结构。后面单独开一节。&lt;/p&gt;
&lt;h3&gt;线性齐次性&lt;/h3&gt;
&lt;p&gt;线性方程里的&lt;strong&gt;齐次&lt;/strong&gt;指$L[y] \equiv 0$, 即&lt;strong&gt;右端为零&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$y&apos;&apos;+y\textcolor{lime}{ =0 }$&lt;/li&gt;
&lt;li&gt;$y^{(4)}-y&apos;&apos;&apos;+y&apos;&apos;-y\textcolor{lime}{ =0 }$&lt;/li&gt;
&lt;li&gt;$y&apos;&apos;-y\textcolor{red}{ =\sin x }$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;线性齐次性基于线性性。&lt;/p&gt;
&lt;h3&gt;代数齐次性&lt;/h3&gt;
&lt;p&gt;指一阶方程$y&apos; = \varphi\left(\frac{y}{x}\right)$, 其右端函数关于$x, y$是$0$次&lt;strong&gt;代数齐次函数&lt;/strong&gt;$f(tx, ty) = f(x, y)$&lt;/p&gt;
&lt;p&gt;说白了就是只能以 $y/x$ 的形式出现。通过换元$u = y/x$化为可分离变量求解。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;虽然这俩性质除了名字没有任何关系，但试卷上不会说。一般来说你也不会搞混。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;常系数性&lt;/h3&gt;
&lt;p&gt;线性方程里的&lt;strong&gt;常系数&lt;/strong&gt;指$y,y&apos;,y&apos;&apos;,\dots$的系数不含$x$.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$\textcolor{lime}{y&apos;&apos;+y}=0$&lt;/li&gt;
&lt;li&gt;$\textcolor{lime}{ y^{(4)}-6y&apos;&apos;&apos;+3y&apos;&apos;-ay }=0$&lt;/li&gt;
&lt;li&gt;$\textcolor{lime}{ y&apos;&apos;-k^2y} =\sin x$&lt;/li&gt;
&lt;li&gt;$y&apos;&apos;\textcolor{red}{ -\frac{1}{x}y} =\cos x$&lt;/li&gt;
&lt;li&gt;$y&apos;&apos;\textcolor{red}{ -e^{x}y&apos;}+2y =\cos x$&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;分离变量法&lt;/h2&gt;
&lt;h3&gt;分离变量法&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;适用范围:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;模式符合: $y&apos; = f(x)g(y)$.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;简单把$x$和$y$分到两边:
$$
\begin{align*}
\frac{dy}{dx}&amp;amp;=f(x)g(y) \
\frac{dy}{g(y)}&amp;amp;=f(x)dx \
\int\frac{dy}{g(y)}&amp;amp;=\int f(x)dx
\end{align*}
$$
两边各自积分即可。注意$g(y)\neq 0$, 这意味着对于$g(y)$可能$=0$的情况需要特殊处理:spoiler[处理完后你大概率会发现特殊点也在通解中]。&lt;/p&gt;
&lt;p&gt;例:
$$
\begin{align*}
y&apos;&amp;amp;=2xy&amp;amp;
y&apos;&amp;amp;=y^{2},y(0) = 1\&lt;/p&gt;
&lt;p&gt;\frac{dy}{dx} &amp;amp;= 2xy&amp;amp;
\frac{dy}{dx} &amp;amp;= y^2\&lt;/p&gt;
&lt;p&gt;\frac{dy}{y} &amp;amp;= 2x,dx&amp;amp;
\frac{dy}{y^2} &amp;amp;= dx \&lt;/p&gt;
&lt;p&gt;\ln|y| &amp;amp;= x^2 + C&amp;amp;
-\frac{1}{y} &amp;amp;= x+C \&lt;/p&gt;
&lt;p&gt;y &amp;amp;= Ce^{x^2}&amp;amp;
y &amp;amp;= \frac{1}{1-x}\
\end{align*}
$$
第二个例子中$x=1$显然不存在，求完要专门写$x$的定义域。&lt;/p&gt;
&lt;p&gt;:::note
分离变量是唯一一个“什么方程都可能用到”的底层方法。线性齐次、齐次方程换元后、可降阶换元后，最后全都会落到它头上。它是本章的万能终点。
:::&lt;/p&gt;
&lt;h3&gt;齐次方程&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;适用于齐次方程 $y&apos; = \varphi\left(\frac{y}{x}\right)$&lt;/p&gt;
&lt;p&gt;齐次方程中, $x, y$同时放大$t$倍，方程不变。由此可以判断齐次方程。
$$
\dfrac{x^2 + y^2}{xy} = \dfrac{(kx)^2 + (ky)^2}{(kx)(ky)} = \dfrac{y}{x} + \dfrac{x}{y}
$$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;对于$y&apos; = \varphi\left(\frac{y}{x}\right)$, 令$u = y/x$, 即$y = ux$:
$$
\begin{align*}
y&apos;&amp;amp;=\varphi\left( \frac{y}{x} \right),\quad \begin{cases}
u=\frac{y}{x} \
y=ux
\end{cases} \
(ux)&apos;&amp;amp;=\varphi(u) \
u+u&apos;x&amp;amp;=\varphi(u) \
u+x;\frac{du}{dx}&amp;amp;=\varphi(u) \
\frac{du}{\varphi(u)-u}&amp;amp;=\frac{dx}{x}
\end{align*}
$$
回归到&lt;a href=&quot;#%E5%88%86%E7%A6%BB%E5%8F%98%E9%87%8F%E6%B3%95&quot;&gt;分离变量法&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;例: $y&apos; = \dfrac{y}{x} + \tan\dfrac{y}{x}$, 令$u = y/x$:
$$
\begin{align*}
xu&apos; &amp;amp;= \tan u \
\frac{\cos u}{\sin u},du &amp;amp;= \frac{dx}{x} \
\ln|\sin u| &amp;amp;= \ln|x| + C \
\sin\frac{y}{x} &amp;amp;= Cx
\end{align*}
$$&lt;/p&gt;
&lt;h3&gt;线性变换&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;适用于 $y&apos; = f(ax + by + c)$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;对于$y&apos; = f(ax + by + c)$, 令$u = ax + by + c$, 则$u&apos; = a + by&apos;$:
$$
\begin{align*}
y&apos; &amp;amp;= f(ax+by+c),\quad \begin{cases}
u = ax+by+c \
u&apos; = a + b y&apos;
\end{cases} \
u&apos; &amp;amp;= a + b f(u) \
\frac{du}{dx} &amp;amp;= a + b f(u) \
\frac{du}{a + b f(u)} &amp;amp;= dx
\end{align*}
$$
回归到&lt;a href=&quot;#%E5%88%86%E7%A6%BB%E5%8F%98%E9%87%8F%E6%B3%95&quot;&gt;分离变量法&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;例: $y&apos; = (x + y)^2$, 令$u = x + y$:
$$
\begin{align*}
y&apos; &amp;amp;= (x+y)^2,\quad \begin{cases}
u = x+y \
u&apos; = 1 + y&apos;
\end{cases} \
u&apos; &amp;amp;= 1 + u^2 \
\frac{du}{dx} &amp;amp;= 1 + u^2 \
\frac{du}{1+u^2} &amp;amp;= dx \
\arctan u &amp;amp;= x + C \
u &amp;amp;= \tan(x+C) \
x+y &amp;amp;= \tan(x+C)
\end{align*}
$$&lt;/p&gt;
&lt;h3&gt;第一类可降阶的二阶方程&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;适用于 $y&apos;&apos; = f(x, y&apos;)$&lt;/p&gt;
&lt;p&gt;即缺少$y$者&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;对于$y&apos;&apos; = f(x, y&apos;)$, 令$p(x) = y&apos;$, 则$p&apos; = f(x, p)$. 回归到关于$p$和$x$的&lt;a href=&quot;#%E4%B8%80%E9%98%B6%E7%BA%BF%E6%80%A7%E9%9D%9E%E9%BD%90%E6%AC%A1%E7%89%B9%E8%A7%A3&quot;&gt;一阶常微分方程&lt;/a&gt;（后文）。&lt;/p&gt;
&lt;p&gt;此方法的本质是将一阶导视为函数，比较好理解。&lt;/p&gt;
&lt;p&gt;例: $y&apos;&apos; = y&apos; + x$, 令$p = y&apos;$:
$$
\begin{align*}
y&apos;&apos; &amp;amp;= y&apos; + x,\quad \begin{cases}
p = y&apos; \
p&apos; = y&apos;&apos;
\end{cases} \
p&apos; &amp;amp;= p + x \
p&apos; - p &amp;amp;= x \
(p e^{-x})&apos; &amp;amp;= x e^{-x} \
p e^{-x} &amp;amp;= \int x e^{-x} , dx = -(x+1)e^{-x} + C \
p &amp;amp;= y&apos; = -x - 1 + C e^x \
y &amp;amp;= \int (-x - 1 + C e^x) , dx \
&amp;amp;= -\frac{x^2}{2} - x + C e^x + D
\end{align*}
$$&lt;/p&gt;
&lt;h3&gt;第二类可降阶的二阶方程&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;适用于 $y&apos;&apos; = f(y, y&apos;)$&lt;/p&gt;
&lt;p&gt;即缺少$x$者。此时我们将$y$视作自变量&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;对于$y&apos;&apos; = f(y, y&apos;)$, 令$p(\textcolor{orange}{y})=y&apos;$, 则$y&apos;&apos; = \frac{dp}{dx} = \frac{dy}{dx}\cdot\frac{dp}{dy} = p,\frac{dp}{dy}$:
$$
\begin{align*}
y&apos;&apos; &amp;amp;= f(y, y&apos;),\quad \begin{cases}
p = y&apos; \
p = p(y)
\end{cases} \
y&apos;&apos; &amp;amp;= \frac{dp}{dx} = \frac{dy}{dx}\frac{dp}{dy} = p\frac{dp}{dy} \
p\frac{dp}{dy} &amp;amp;= f(y,p) \
\frac{dp}{dy} &amp;amp;= \frac{f(y,p)}{p} \
\end{align*}
$$
回归到关于$p$和$y$的&lt;a href=&quot;#%E4%B8%80%E9%98%B6%E7%BA%BF%E6%80%A7%E9%9D%9E%E9%BD%90%E6%AC%A1%E7%89%B9%E8%A7%A3&quot;&gt;一阶常微分方程&lt;/a&gt;（后文）。&lt;/p&gt;
&lt;p&gt;例: $yy&apos;&apos; + (y&apos;)^2 = 0$, 令$p(y)=y&apos;$:
$$
\begin{align*}
yy&apos;&apos; + (y&apos;)^2 &amp;amp;= 0,\quad \begin{cases}
p = y&apos; \
y&apos;&apos; = p\frac{dp}{dy}
\end{cases} \
y p\frac{dp}{dy} + p^2 &amp;amp;= 0 \
p\left(y\frac{dp}{dy} + p\right) &amp;amp;= 0 \
y\frac{dp}{dy} + p &amp;amp;= 0 \quad (p\neq 0) \
\frac{dp}{p} &amp;amp;= -\frac{dy}{y} \
\ln|p| &amp;amp;= -\ln|y| + C_1 \
p &amp;amp;= \frac{C_1}{y} \quad \text{ include }, p\equiv 0 \
\frac{dy}{dx} &amp;amp;= \frac{C_1}{y} \
y,dy &amp;amp;= C_1,dx \
\frac{y^2}{2} &amp;amp;= C_1 x + C_2
\end{align*}
$$&lt;/p&gt;
&lt;h3&gt;齐次线性&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;适用于 $y&apos; = f\left(\dfrac{ax + by + c}{a&apos;x + b&apos;y + c&apos;}\right)$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;设$y&apos;=f\left( \frac{L_{1}(x,y)}{L_{2}(x,y)} \right)$. $L_{1}$, $L_{2}$均为直线。当&lt;strong&gt;两条直线相交&lt;/strong&gt;时，解方程组${ L_{1}=L_{2}=0 }$, 解得$(x_{0},y_{0})$作为交点。然后作重要变换:
$$
\begin{cases}
X = x - x_0 \
Y = y - y_0
\end{cases}
$$
此变换下有
$$
\begin{align*}
\frac{dy}{dx}&amp;amp;=f\left( \frac{L_{1}(x,y)}{L_{2}(x,y)} \right)\quad\begin{cases}
X = x - x_0 \
Y = y - y_0
\end{cases} \
\frac{dY}{dX}&amp;amp;=f\left( \frac{L_{1}(X+x_{0},Y+y_{0})}{L_{2}(X+x_{0},Y+y_{0})} \right) \
\frac{dY}{dX}&amp;amp;=f\left( \frac{aX+bY}{a&apos;X+b&apos;Y} \right)\quad \begin{cases}
u=Y/X\
Y=uX
\end{cases} \
u+X\cdot\frac{du}{dX}&amp;amp;=f\left( \frac{a+bu}{a&apos;+b&apos;u} \right) \
\frac{du}{dX}&amp;amp;=\frac{1}{X}\left[ f\left( \frac{a+bu}{a&apos;+b&apos;u} \right) -u\right] \
\frac{du}{\left[ f\left( \frac{a+bu}{a&apos;+b&apos;u} \right) -u\right]}&amp;amp;=\frac{dX}{X} \
\end{align*}
$$
回归到&lt;a href=&quot;#%E5%88%86%E7%A6%BB%E5%8F%98%E9%87%8F%E6%B3%95&quot;&gt;分离变量法&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;例: $y&apos; = \dfrac{x + y - 1}{x - y + 1}$, 两直线$x + y = 1$与$x - y = -1$交于$(0, 1)$, 令$X = x,\ Y = y - 1$:
$$
\begin{align*}
y&apos; &amp;amp;= \frac{x+y-1}{x-y+1},\quad \begin{cases}
X = x \
Y = y-1
\end{cases} \
\frac{dY}{dX} &amp;amp;= \frac{X+Y}{X-Y},\quad \begin{cases}
u = \frac{Y}{X} \
Y = uX
\end{cases} \
u + X\frac{du}{dX} &amp;amp;= \frac{1+u}{1-u} \
X\frac{du}{dX} &amp;amp;= \frac{1+u^2}{1-u} \
\frac{1-u}{1+u^2},du &amp;amp;= \frac{dX}{X} \
\arctan u - \frac{1}{2}\ln(1+u^2) &amp;amp;= \ln|X| + C \
\arctan\dfrac{Y}{X} &amp;amp;= \ln\sqrt{X^2 + Y^2} + C
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;两条直线平行&lt;/strong&gt;时没有交点可平移，但此时$ax + by$是同一个东西，令$u=ax + by + c$即可消掉一个变量。&lt;/p&gt;
&lt;p&gt;例: $y&apos; = \dfrac{x + y + 2}{x + y - 1}$, 令$u = x + y + 2$:
$$
\begin{align*}
y&apos; &amp;amp;= \frac{x+y+2}{x+y-1},\quad \begin{cases}
u = x+y+2 \
u&apos; = 1 + y&apos;
\end{cases} \
u&apos; &amp;amp;= 1 + \frac{u}{u-3} = \frac{2u-3}{u-3} \
\frac{u-3}{2u-3},du &amp;amp;= dx \
\int \frac{u-3}{2u-3},du &amp;amp;= \int dx \
\frac{1}{4}(2u-3 - 3\ln|2u-3|) &amp;amp;= x + C
\end{align*}
$$&lt;/p&gt;
&lt;h2&gt;特征方程法&lt;/h2&gt;
&lt;h3&gt;特征方程&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;适用范围:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;常系数&lt;/strong&gt;线性齐次方程&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;常系数&lt;/strong&gt;线性非齐次方程&lt;strong&gt;的齐次解部分&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;先说做法。举例来说，对于一个线性方程
$$
y&apos;&apos; + ay&apos; + by = 0
$$
我们对左端做以下映射:
$$
\begin{align*}
y&apos;&apos;&amp;amp;\implies \lambda^{2} \
y&apos;&amp;amp;\implies \lambda \
y&amp;amp;\implies 1 \
\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;实际上以上代入是基于右端为$0$时代入$y=e^{ \lambda x }$后化简的结果&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;可得特征方程
$$
\lambda^2 + a\lambda + b = 0
$$
解得特征根$\lambda_{1},\lambda_{2}$. 然后是最重要的一步:&lt;/p&gt;
&lt;p&gt;对于任意特征根$\textcolor{aqua}{ \lambda_{i} }$作为$\textcolor{yellow}{ n_{i} }$重根, 有
$$
y=\sum_{\textcolor{aqua}{ \lambda_{i} }} e^{\textcolor{aqua}{ \lambda_{i} } x} \sum_{\textcolor{yellow}{ k=1 }}^{\textcolor{yellow}{ n_{i} }} C_{i,k}; x^{\textcolor{yellow}{ k-1 }}
$$
举例来说，有$\begin{cases}\lambda_{1}=1\\lambda_{2}=1,\\textcolor{lime}{ \lambda_{3}=3+i}\\textcolor{lime}{\lambda_{4}=3-i }\end{cases}$, 就有
$$
\begin{align*}
y&amp;amp;=C_{1}e^{ x }+C_{2}xe^{x}+\textcolor{lime}{ C_{3}e^{ (3+i)x }+C_{4}e^{ (3-i)x } } \
&amp;amp;=C_{1}e^{ x }+C_{2}xe^{x}+\textcolor{lime}{ e^{3x}(A\cos x+B\sin x) }
\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;不重的根会被指数次数隔开，重的根会被额外的$x$次数隔开。所有根的项被全部隔离，因此次数=常数个数。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;欧拉公式转换&lt;/h4&gt;
&lt;p&gt;多数教材会将复数根时的结论特化为三角函数形式，但我认为这样不够大一统而优雅，实际上求导也很麻烦。由欧拉公式:
$$
e^{ i\theta }=\cos \theta+i \sin \theta
$$
可得
$$
\begin{align*}
e^{(3+i)x}&amp;amp;=e^{3x}(\cos x+i\sin x) \
e^{(3-i)x}&amp;amp;=e^{3x}(\cos x-i\sin x)
\end{align*}
$$
所以
$$
\begin{aligned}
&amp;amp;C_3e^{(3+i)x}+C_4e^{(3-i)x} \
=&amp;amp;C_3e^{3x}(\cos x+i\sin x)+C_4e^{3x}(\cos x-i\sin x)\
=&amp;amp;e^{3x}\left[\textcolor{yellow}{ (C_3+C_4) }\cos x+\textcolor{yellow}{ i(C_3-C_4) }\sin x\right].
\end{aligned}
$$
令
$$
A=\textcolor{yellow}{ C_3+C_4 },\quad B=\textcolor{yellow}{ i(C_3-C_4) },
$$
也可写成
$$
\boxed{e^{3x}(A\cos x+B\sin x)}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;故此处的$A,B$是在$\mathbb{C}$上的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;实际记忆建议&lt;/h4&gt;
&lt;p&gt;实际上对于实系数多项式，&lt;strong&gt;只要一个复根不是实数，它就一定以共轭对的形式出现。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这意味着只要它不出$y&apos;&apos; + iy&apos; -iy = 0$这样的雷霆式子(不会出的)，你所见到的所有复根就&lt;strong&gt;全部都是共轭&lt;/strong&gt;的。也就是对于所有考点内的共轭根$\alpha \pm i\beta$, 通过如上转换，全部可以写成共通的格式:
$$
e^{\alpha x}[A\cos (\beta x)+B\sin (\beta x)]
$$
大部分教材将这个式子作为一个脱离于实根情况的背诵式，但确实不怎么好背，尤其是搞不清楚怎么来的的情况下。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特征根&lt;/th&gt;
&lt;th&gt;通解&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;两个不等实根$\lambda_1 \neq \lambda_2$&lt;/td&gt;
&lt;td&gt;$y = C_1 e^{\lambda_1 x} + C_2 e^{\lambda_2 x}$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;重根$\lambda$&lt;/td&gt;
&lt;td&gt;$y = (C_1 + C_2 x) e^{\lambda x}$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;共轭复根$\alpha \pm i\beta$&lt;/td&gt;
&lt;td&gt;$y = e^{\alpha x}\left(C_1\cos\beta x + C_2\sin\beta x\right)$&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;27330:198/&amp;lt;u&amp;gt;90&amp;lt;/u&amp;gt;/★★★★☆&lt;/h3&gt;
&lt;p&gt;求齐次线性微分方程$y^{(4)} - 5y&apos;&apos; + 10y&apos; - 6y = 0$满足初值条件$y(0) = 1,\ y&apos;(0) = 0,\ y&apos;&apos;(0) = 6,\ y&apos;&apos;&apos;(0) = -14$的特解$y(x)$, 并求极限&lt;/p&gt;
&lt;p&gt;$$
\lim_{x\to 0}\frac{y(x) - 1 - 3x^2}{e^{\sin^3 x} - 1}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我们特色数二题就这么出。&lt;/p&gt;
&lt;p&gt;前边是模板化微分方程(特征方程)，求出一个带未知数的，往后代变成极限题。生硬。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;解&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;特征方程
$$
\lambda^4 - 5\lambda^2 + 10\lambda - 6 = 0
$$
试根$\lambda = 1$、$\lambda = -3$:spoiler[有理根定理，其实瞪眼就行]，多项式长除法:
$$
\lambda^4 - 5\lambda^2 + 10\lambda - 6 = (\lambda - 1)(\lambda + 3)(\lambda^2 - 2\lambda + 2)
$$
故根为$1,\ -3,\ 1 \pm i$, 通解
$$
y = C_1 e^x + C_2 e^{-3x} + e^x\left(C_3\cos x + C_4\sin x\right)
$$
代入四个初值条件:
$$
\begin{align*}
&amp;amp;\begin{cases}
y(0) &amp;amp;= C_1 + C_2 + C_3 &amp;amp;= 1 \
y&apos;(0) &amp;amp;= C_1 - 3C_2 + C_3 + C_4 &amp;amp;= 0 \
y&apos;&apos;(0) &amp;amp;= C_1 + 9C_2 + 2C_4 &amp;amp;= 6 \
y&apos;&apos;&apos;(0) &amp;amp;= C_1 - 27C_2 - 2C_3 + 2C_4 &amp;amp;= -14
\end{cases} \
\Longrightarrow\quad
&amp;amp;\begin{cases}
C_1 = -\frac12 \
C_2 = \frac12 \
C_3 = 1 \
C_4 = 1
\end{cases} \
\Longrightarrow\quad
&amp;amp;y(x) = -\frac12 e^x + \frac12 e^{-3x} + e^x\left(\cos x + \sin x\right)
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;第二问: 初值条件已经给出$y$在$0$处的各阶导数，直接泰勒:
$$
\begin{align*}
&amp;amp;\begin{cases}
y(0) &amp;amp;= \textcolor{lime}{ 1 } \
y&apos;(0)  &amp;amp;= \textcolor{lime}{ 0 } \
y&apos;&apos;(0) &amp;amp;= \textcolor{lime}{ 6 } \
y&apos;&apos;&apos;(0)  &amp;amp;= \textcolor{lime}{ -14 }
\end{cases} \&lt;/p&gt;
&lt;p&gt;y(x)= &amp;amp;\textcolor{lime}{ 1 } + \textcolor{lime}{ 0 }\cdot x + \textcolor{lime}{ 6 }\cdot\frac{x^2}{2} + \textcolor{lime}{ -14 }\cdot\frac{x^3}{6} + o(x^3) \
= &amp;amp;1 + 3x^2 - \frac{7}{3}x^3 + o(x^3)&lt;/p&gt;
&lt;p&gt;\end{align*}
$$
分子 $y(x) - 1 - 3x^2 = -\dfrac{7}{3}x^3 + o(x^3)$.&lt;/p&gt;
&lt;p&gt;分母路边小式直接等价$e^{\sin^3 x} - 1 \sim x^3$.
$$
\lim_{x\to 0}\frac{y(x) - 1 - 3x^2}{e^{\sin^3 x} - 1} = -\frac{7}{3}
$$&lt;/p&gt;
&lt;h3&gt;一阶线性非齐次特解&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;适用范围:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一阶&lt;strong&gt;变系数&lt;/strong&gt;线性齐次/非齐次方程&lt;/li&gt;
&lt;li&gt;即$y&apos; + p(x)y = q(x)$, 和可化为此式形式的方程
$$
y&apos; + p(x)y = q(x)
$$
对于这类方程，解是
$$
y = e^{-\int p,dx}\left(\int q,e^{\int p,dx},dx + C\right)
$$&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;其实我不会背这个公式。我草纸上一般这么写:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;555fcee4d9f815f911490c291d53890a.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;推导:&lt;/p&gt;
&lt;p&gt;对于微分方程$y&apos;+p(x)y=q(x)$, 设$\mu(x)=e^{\int p,dx}$, 注意以下$y,p,q,\mu$全部都是$x$的函数，导和积也都关于$x$:
$$
\begin{align*}
y&apos;+py&amp;amp;=q \
(y&apos;+py)\cdot \mu&amp;amp;=q\cdot \mu \
\left(y,\mu\right)&apos;&amp;amp;=q\cdot \mu \
y\mu&amp;amp;=\int\left[ q\cdot \mu \right]dx \
y&amp;amp;=\frac{1}{\mu}\int\left[ q\cdot \mu \right]dx \
\end{align*}
$$
若$q \equiv 0$退化为齐次，公式可以照用。实际上流程会退化为简单分离变量。&lt;/p&gt;
&lt;p&gt;:::tip
还有一种等价做法叫&lt;strong&gt;常数变易法&lt;/strong&gt;: 先解齐次得$y = Ce^{-\int p,dx}$, 再把$C$变成函数$C(x)$代回原方程定它。
:::&lt;/p&gt;
&lt;h3&gt;二阶线性非齐次特解&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;适用范围:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;二阶常系数&lt;strong&gt;线性非齐次&lt;/strong&gt;方程&lt;/li&gt;
&lt;li&gt;即$y&apos;&apos; + ay&apos; + by = f(x)$, 和可化为此式形式的方程&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;对于任意一个二阶常系数线性非齐次方程$y&apos;&apos; + ay&apos; + by = f(x)$, 其通解满足:
$$
y=y_{h}+y^*
$$
其中:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$y_{h}$是二阶常系数线性&lt;strong&gt;齐次&lt;/strong&gt;方程$y&apos;&apos; + ay&apos; + by=0$的通解，此处称为&lt;strong&gt;齐次通解&lt;/strong&gt;。先求其次通解是必须的，下文视为已知。&lt;/li&gt;
&lt;li&gt;$y*$是本节要得到的特解。
&lt;ul&gt;
&lt;li&gt;对于齐次方程, $y_{h}=0$一定是一个解。&lt;/li&gt;
&lt;li&gt;由此又有对于非齐次方程, $y=y^*$一定是一个解。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;注意，&lt;strong&gt;特解&lt;/strong&gt;可能不是唯一的，因为齐次通解含有两个任意常数，所以特解可能会在齐次通解构成的空间中加上特定的$C$倍通解。&lt;/p&gt;
&lt;p&gt;那么特解怎么找？&lt;strong&gt;待定系数法&lt;/strong&gt;，数二只考一种形状:
$$
f(x) = P_n(x),e^{\lambda x}
$$
其中$P_n$是$n$次多项式（$\sin/\cos$先用欧拉公式写成$e^{i\omega x}$归入此类）。设特解
$$
y^* = x^k,Q_n(x),e^{\lambda x}
$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$Q_n$是与$P_n$同次的多项式，系数待定；&lt;/li&gt;
&lt;li&gt;$k$是$\lambda$作为&lt;strong&gt;特征根&lt;/strong&gt;的重数: 不是特征根取$0$, 单根取$1$, 重根取$2$。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;举例来说:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$y&apos;&apos; - 3y&apos; + 2y = e^x$, $r=1, 2$, $\lambda = 1$, 是单根
&lt;ul&gt;
&lt;li&gt;$P_{n}(x)=1$, $Q_{n}(x)=A$.&lt;/li&gt;
&lt;li&gt;设 $y^*=x\cdot A e^x$. 代入得&lt;/li&gt;
&lt;li&gt;${y^&lt;em&gt;}&apos;&apos; - 3{y^&lt;/em&gt;}&apos; + 2y^* =Ae^x\big[(2 + x) - 3(1 + x) + 2x\big] = -Ae^x = e^x$.&lt;/li&gt;
&lt;li&gt;解得 $A = -1$, $y^*=-xe^x$.
&lt;ul&gt;
&lt;li&gt;又有$y_{h}=C_1 e^x + C_2 e^{2x}$,&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;$y = C_1 e^x + C_2 e^{2x} - x e^x$.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;$y&apos;&apos;+y=(12x^2+4x)\sin x$, $r=\pm i$, $\lambda=i$, 是单根
&lt;ul&gt;
&lt;li&gt;$P_{n}(x)=12x^2+4x$, $Q_{n}(x)=Ax^2+Bx+C$.&lt;/li&gt;
&lt;li&gt;设 $z^*=x(Ax^2+Bx+C)(e^{ix})=x(Ax^2+Bx+C)(\cos x+i\sin x)$. 代入得&lt;/li&gt;
&lt;li&gt;${z^&lt;em&gt;}&apos;&apos;+z^&lt;/em&gt; = [(6iA)x^2+(6A+4iB)x+(2B+2iC)]e^{ix} = (12x^2+4x)e^{ix}$&lt;/li&gt;
&lt;li&gt;解得 $A=-2i,\ B=3-i,\ C=1+3i$.
&lt;ul&gt;
&lt;li&gt;又有$y_h=C_1\cos x+C_2\sin x$,&lt;/li&gt;
&lt;li&gt;由于$e^{ ix }=\cos x+i\sin x$, 原式为$\sin x$, 取$z$虚部作为$y^*$, 有&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;$y=C_1\cos x+C_2\sin x+(3x^2+x)\sin x+(-2x^3-x^2+3x)\cos x$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;$y&apos;&apos; + y = \sin x$。$r=\pm i$, $\lambda = i$, 是单根
&lt;ul&gt;
&lt;li&gt;$P_{n}(x)=1$, $Q_{n}(x)=A$.&lt;/li&gt;
&lt;li&gt;设 $y^* = x(A\cos x + B\sin x)$. 代入得&lt;/li&gt;
&lt;li&gt;${y^&lt;em&gt;}&apos;&apos;+y^&lt;/em&gt; = -2A\sin x + 2B\cos x = \sin x$.&lt;/li&gt;
&lt;li&gt;解得 $A = -\frac12,\ B = 0$.
&lt;ul&gt;
&lt;li&gt;又有$y_{h}=C_1\cos x + C_2\sin x$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;$y = C_1\cos x + C_2\sin x - \frac{x}{2}\cos x$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;叠加原理&lt;/h3&gt;
&lt;p&gt;设$L[y] = y&apos;&apos; + p(x)y&apos; + q(x)y$。线性性带来三条推导:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;齐次解的线性组合仍是齐次解&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;$L[y_1] = L[y_2] = 0 \Rightarrow L[c_1 y_1 + c_2 y_2] = 0$。齐次解集是一个线性空间。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;非齐次特解可叠加&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;$L[y_1] = f_1,\ L[y_2] = f_2 \Rightarrow L[y_1 + y_2] = f_1 + f_2$&lt;/li&gt;
&lt;li&gt;所以$f = f_1 + f_2$时，两个特解相加就是整体特解。&lt;/li&gt;
&lt;li&gt;待定系数法对每一项分别设、分别算。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;反向应用&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;$y_1, y_2$是$L[y] = f$的两个特解 $\Rightarrow$ $L[y_1 - y_2] = 0$&lt;/li&gt;
&lt;li&gt;即两个特解之差是齐次解。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;再次强调: &lt;strong&gt;非齐次通解=齐次通解+一个特解&lt;/strong&gt;。$y=y_{h}+y^*$.&lt;/p&gt;
&lt;h3&gt;27330:196/&amp;lt;u&amp;gt;90&amp;lt;/u&amp;gt;/★★★★☆&lt;/h3&gt;
&lt;p&gt;设$y_1 = 2x^4 + x^2$、$y_2 = 2x^4 - x^2$是微分方程$y&apos; + p(x)y = \dfrac{q(x)}{p(x)}$的两个特解。&lt;/p&gt;
&lt;p&gt;(1) 求$p(x), q(x)$；
(2) 求此方程满足初值条件$y(1) = 5$的特解；
(3) 若$y(x)$是(2)中的解，且$\lim\limits_{x\to\infty}\dfrac{y(x)}{ax^4 + bx} = 2$, 求$a, b$的值。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;全程没给$p, q$的表达式，但是给了两个特解，等于给了通解。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;解&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;(1).&lt;/p&gt;
&lt;p&gt;两特解相减所得的齐次解$y_1 - y_2 = 2x^2$是原方程的齐次方程$y&apos; + p(x)y = 0$解. 代入得:
$$
(2x^2)&apos; + p(x)\cdot 2x^2 = 0 \quad\Longrightarrow\quad p(x) = -\frac{2}{x}
$$
$y_1$是原方程的解:
$$
y_1&apos; + p(x)y_1 = 8x^3 + 2x - \frac{2}{x}\left(2x^4 + x^2\right) = 4x^3 = \frac{q(x)}{p(x)}
$$
故有:
$$
\boxed{p(x) = -\frac{2}{x},\qquad q(x) = p(x)\cdot 4x^3 = -8x^2}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;问题二回归到普通的微分方程初值环节，而且是从已经求出齐次解和特解开始的&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(2).&lt;/p&gt;
&lt;p&gt;$y=y_{h}+y^&lt;em&gt;$, 即:
$$
\begin{align&lt;/em&gt;}
y(1)&amp;amp;=5&amp;amp;\quad y&amp;amp;=y_1+C\cdot2x^2\
2+1+2C&amp;amp;=5&amp;amp;&amp;amp;=2x^4+x^2+2Cx^2\
C&amp;amp;=1&amp;amp;&amp;amp;=2x^4+3x^2\
\end{align*}
$$
(3) $y = 2x^4 + 3x^2 \sim 2x^4$ ($x \to \infty$). 为使$\dfrac{y}{ax^4 + bx} \to 2$, 分母必须与分子同阶，故$a = 1$；而分子没有一次项，$b$的取值不影响极限。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$a = 1,\quad b\ \text{为任意常数}$&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;*这里的$b$确实取不出来。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;超级拼装微积分混合大方程&lt;/h2&gt;
&lt;p&gt;你也看过上面那道题了，除了求微分方程通解和初值特解，它还做了的一件事是生硬地把这个解放到极限里形成一个条件让你求未知数。&lt;/p&gt;
&lt;p&gt;真正的boss题长得不像微分方程。方程里有积分号（变限积分方程）、求完函数还要算极限、或者条件全是几何语言。上面的微分方程只是boss的一个独有机制，真正要做到这里需要百法皆通。那么接下来就是我们最喜欢的:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;方法论&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;含初始&lt;strong&gt;变限积分&lt;/strong&gt;条件的方程一般比求导后的微分方程更丰富，主要丰富在初值条件上。比如题目出现$\int_{1}^x f(t),dt$或者$(x-1)f&apos;&apos;(x)$这种送上门的肥肉, 那你就应该分别做两件事:
&lt;ul&gt;
&lt;li&gt;把$x=1$带进方程去试试，&lt;strong&gt;发现隐藏初值关系&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;求导，&lt;strong&gt;发现可解的微分方程&lt;/strong&gt;。莱布尼茨法则见&lt;a href=&quot;/posts/2026-07-23-00/&quot;&gt;积分学其五&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;我说开始雷霆大推导之前，一定要&lt;strong&gt;整理好初始条件&lt;/strong&gt;，任何时候卡壳了就要去看初始条件。我上这么多色就是为了看清每个初始条件和派生条件的使用位置的。
&lt;ul&gt;
&lt;li&gt;同样要有在微积分方程化成纯微分方程之前每个初值条件都要榨干的意识。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这是针对大微积分方程的方法论。那有没有针对其他的呢？很遗憾没有，因为其他的组合要么生硬得简单，要么神秘诡异到怀疑人生不适合举为方法论。&lt;/p&gt;
&lt;h3&gt;27330:201/&amp;lt;u&amp;gt;90&amp;lt;/u&amp;gt;/★★★★☆&lt;/h3&gt;
&lt;p&gt;设当$x \geqslant 0$时$f(x)$有一阶连续导数，并且满足
$$
f(x) = -1 + x + 2\int_0^x (x - t)f(t)f&apos;(t),dt
$$
求当$x \geqslant 0$时的$f(x)$。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;变限积分方程。$(x - t)$这个核求一次导变成$\int_0^x ff&apos;$, 还没消干净——所以要求两次导。初值$f(0)$直接代原方程，$f&apos;(0)$代一阶导后的式子。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;解&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;代$x = 0$可得$\textcolor{pink}{ f(0) = -1 }$.&lt;/p&gt;
&lt;p&gt;两边求导代$x=0$可得$f&apos;(x) = 1 + 2\int_0^x f(t)f&apos;(t),dt$.&lt;/p&gt;
&lt;p&gt;代$x=0$可得$\textcolor{aqua}{ f&apos;(0) = 1 }$.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我们希望对$f&apos;(x)$再次求导。注意到$f&apos;(x)$右侧积分式中是连续的，且积分内包括$f&apos;(x)$的整体是连续的，故$f&apos;(x)$是可导的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;再求导可得$\textcolor{lime}{ f&apos;&apos;(x) = 2f(x)f&apos;(x) }$. 则有:
$$
\begin{align*}
\textcolor{lime}{ f&apos;&apos;} &amp;amp;\textcolor{lime}{= 2ff&apos; } \&lt;/p&gt;
&lt;p&gt;f&apos;&apos; &amp;amp;= (f&apos;^2)&apos; \
f&apos; &amp;amp;= f^2+C\quad\begin{cases}
\textcolor{aqua}{ f&apos;(0)=1 } \
\textcolor{pink}{ f(0)=-1 } \
\implies C=0
\end{cases} \
f&apos;&amp;amp;=f^2 \
-\frac{1}{f}=&amp;amp;x+C_{2}\quad\begin{cases}
\textcolor{pink}{ f(0)=-1 } \
\implies C_{2}=1
\end{cases} \
f(x) = -\frac{1}{x + 1}
\end{align*}
$$&lt;/p&gt;
&lt;h3&gt;27330:195/&amp;lt;u&amp;gt;90&amp;lt;/u&amp;gt;/★★★★☆&lt;/h3&gt;
&lt;p&gt;设函数$f(x)$在$(0, +\infty)$上可导，$f(1) = 0$, 且满足&lt;/p&gt;
&lt;p&gt;$$
\textcolor{yellow}{ x(x+1)f&apos;(x) - (x+1)f(x) + \int_1^x f(t),dt = x - 1 }
$$&lt;/p&gt;
&lt;p&gt;求$\textcolor{aqua}{ \displaystyle\int_1^2 f(x),dx - 3f(2) } + \textcolor{lime}{ \lim_{x\to 1}\frac{\displaystyle\int_1^x \frac{\sin(t-1)^2}{t-1},dt}{f(x)} }$。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我们敏锐地注意到要的东西中, $\textcolor{aqua}{ \int_1^2 f - 3f(2) }$恰好是原方程在$x = 2$处的左边&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;代$x = 1$可得$\textcolor{pink}{ f&apos;(1) = 0 }$&lt;/p&gt;
&lt;p&gt;两边求导可得$x(x+1)f&apos;&apos; + xf&apos; = 1$, 令$u = f&apos;$, 解微分方程得$(x+1)u = \ln x + C$, 代入$\textcolor{pink}{ u(1) = f&apos;(1) = 0 }$得$C = 0$.&lt;/p&gt;
&lt;p&gt;整理即: $u=\textcolor{salmon}{ f&apos;(x) = \dfrac{\ln x}{x + 1} }$.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;注意该式不可初等积，因此我们会开始考虑使用其他方法凑出我们需要的$\textcolor{aqua}{ \int_1^2 f - 3f(2) }$.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;原式代$x=2$得:
$$
\begin{align*}
\textcolor{yellow}{ x(x+1)f&apos;(x) - (x+1)f(x) + \int_1^x f(t),dt  }&amp;amp;\textcolor{yellow}{ = x - 1 } \
6f&apos;(2) - 3f(2) + \int_1^2 f(t),dt &amp;amp;= 1 \
\textcolor{aqua}{ \displaystyle\int_1^2 f(x),dx - 3f(2) } &amp;amp;= 1-6\textcolor{salmon}{ f&apos;(2) } \
&amp;amp;=1-6\cdot\frac{\ln 2}{2+1} \
&amp;amp;=1-2\ln 2
\end{align*}
$$
又有极限:
$$
\begin{align*}
\textcolor{lime}{ \lim_{x\to 1}\frac{\displaystyle\int_1^x \frac{\sin(t-1)^2}{t-1},dt}{f(x)} }&amp;amp;\stackrel{\textcolor{dodgerblue}{ L&apos; }}{=}\lim_{x\to1}\frac{\dfrac{\sin(x-1)^2}{x-1}}{\textcolor{salmon}{ f&apos;(x) }} \
&amp;amp;=\lim_{x\to 1}\frac{\dfrac{\sin(x-1)^2}{x-1}}{\textcolor{salmon}{ \dfrac{\ln x}{x + 1} }} \
&amp;amp;=\lim_{x\to 1},(x+1) \
&amp;amp;=2 \
\end{align*}
$$
最终有:
$$
\textcolor{aqua}{ \int_1^2 f(x),dx - 3f(2) } + \textcolor{lime}{ \lim_{x\to 1}\frac{\int_1^x \frac{\sin(t-1)^2}{t-1},dt}{f(x)} } = 1 - 2\ln 2 + 2 = 3 - 2\ln 2
$$&lt;/p&gt;
&lt;h3&gt;27330:217/&amp;lt;u&amp;gt;90&amp;lt;/u&amp;gt;/★★★★☆&lt;/h3&gt;
&lt;p&gt;设在$xOy$平面的第一象限中有曲线$\Gamma: y = y(x)$, 过点$\textcolor{aqua}{ A(0, \sqrt{2} - 1) }$, $\textcolor{yellow}{ y&apos;(x) &amp;gt; 0 }$。$M(x, y)$为$\Gamma$上任意一点，满足&quot;弧段$AM$的长&quot;与&quot;$\Gamma$在点$M$处的切线在$x$轴上的截距&quot;之差为$\sqrt{2} - 1$, 求此曲线。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我们要构造的是$y=y(x)$在$x\geq0$,$y\geq0$, 且:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;弧段$AM$的长 (记为$\textcolor{dodgerblue}{ A(x) }$) 与&lt;/li&gt;
&lt;li&gt;$\Gamma$在点$M$处的切线在$x$轴上的截距 (记为$\textcolor{springgreen}{ B(x) }$)&lt;/li&gt;
&lt;li&gt;之差为$\sqrt{2} - 1$.&lt;/li&gt;
&lt;li&gt;$\textcolor{dodgerblue}{ A(x) }-\textcolor{springgreen}{ B(x) }=\sqrt{ 2 }-1$.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;显然$\textcolor{aqua}{ A(0)=0 }$, $\textcolor{yellow}{ y&apos;(x) &amp;gt; 0 }$, 函数向上, 截距$B(0)=1-\sqrt{2}$.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;弧段$AM$的长: $\textcolor{dodgerblue}{ A(x)  = \int_0^x \sqrt{1 + \left(y&apos;(t)\right)^2},dt}$.&lt;/p&gt;
&lt;p&gt;$M$处切线写作$Y - y = y&apos;(X - x)$, 令$Y = 0$得$x$轴截距$\textcolor{springgreen}{ B(x)  = x - \frac{y}{y&apos;}}$.&lt;/p&gt;
&lt;p&gt;则有:
$$
\begin{align*}
\textcolor{dodgerblue}{  \int_0^x \sqrt{1 + \left(y&apos;(t)\right)^2},dt}-\textcolor{springgreen}{ x - \frac{y}{y&apos;}}&amp;amp;=\sqrt{ 2 }-1 \quad \begin{cases}
\implies\textcolor{salmon}{ y&apos;(0)=1 }
\end{cases} \tag{1}\
\sqrt{1 + y&apos;^2} - \frac{yy&apos;&apos;}{y&apos;^2}&amp;amp;=0\quad \begin{cases}
p(y)=y&apos; \
y&apos;&apos; = \frac{dp}{dx} = \frac{dy}{dx}\frac{dp}{dy} = p\frac{dp}{dy}
\end{cases}  \tag{2}\
\sqrt{1 + p^2} - \frac{y,p&apos;}{p^2} &amp;amp;= 0 \
\int\frac{dp}{p\sqrt{1 + p^2}} &amp;amp;= \int\frac{dy}{y}  \tag{3}\
\ln\frac{\sqrt{1 + p^2} - 1}{p}&amp;amp;=\ln y+C  \tag{4}\
\frac{\sqrt{1 + p^2} - 1}{p} &amp;amp;= Cy\quad \begin{cases}
\textcolor{aqua}{ y(0)= \sqrt{ 2 }-1 }  \tag{5}\
\textcolor{salmon}{ y&apos;(0)=1 } \
\implies C=1
\end{cases} \
\frac{\sqrt{1 + p^2} - 1}{p} &amp;amp;= y \
p &amp;amp;= \frac{2y}{1 - y^2} \qquad\text{(恩这个确实能求出来)}  \tag{6}\
\int\frac{1 - y^2}{2y},dy &amp;amp;= \int dx  \tag{7}\
\frac12\ln y - \frac{y^2}{4} + C_{2} &amp;amp;= x\quad\begin{cases}
\textcolor{aqua}{ y(0)= \sqrt{ 2 }-1 } \
\implies C_{2}=\frac{1}{2}\ln(\sqrt{2} + 1) + \frac{3 - 2\sqrt{2}}{4}
\end{cases}  \tag{8}\
x &amp;amp;= \frac{1}{2}\ln\bigl(y\cdot(\sqrt{2}+1)\bigr) - \frac{y^2}{4} + \frac{3-2\sqrt{2}}{4}
\end{align*}
$$
由于$\textcolor{yellow}{ y&apos;(x)&amp;gt;0 }$, 原式在定义域上必定有反函数。$\sqrt{2}-1 \leqslant y &amp;lt; 1$.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;虽然过程看起来很epic，但实际上没多少卡壳点。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;原式的列出。用到&lt;a href=&quot;/posts/2026-08-01-00/#%E5%BC%A7%E9%95%BF&quot;&gt;积分的应用&lt;/a&gt;和基本求切线。&lt;/li&gt;
&lt;li&gt;纯微分方程。遵循&lt;a href=&quot;http://localhost:21080/posts/2026-08-18-00/#%E7%AC%AC%E4%BA%8C%E7%B1%BB%E5%8F%AF%E9%99%8D%E9%98%B6%E7%9A%84%E4%BA%8C%E9%98%B6%E6%96%B9%E7%A8%8B&quot;&gt;本章基础套路套换元&lt;/a&gt;即可，没理由不会。&lt;/li&gt;
&lt;li&gt;简单的式子整理。要注意$p&apos;=\frac{dp}{dy}$, 知道自己在做什么就不会错。&lt;/li&gt;
&lt;li&gt;用到一个有点难度的基本的积分。这个积分我其实记过，三角换元和倒代换都可以殺。&lt;a href=&quot;/posts/2026-02-17-01/&quot;&gt;点击前往第一篇笔记: 常见的积分&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;带未知数的微分方程。要看初始条件。&lt;/li&gt;
&lt;li&gt;这个不敢笑我也卡壳了。因为一定要把$p$提取出来才能进行下一步，但是这个东西长得实在太恐怖了，没想到真的能拆出来。&lt;/li&gt;
&lt;li&gt;简单的式子整理。要注意$p=y=\frac{dy}{dx}$, 知道自己在做什么就不会错。&lt;/li&gt;
&lt;li&gt;最后这个$C_{2}$确实很折磨人，估计是出题没配好数字，但也不至于算不出来。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;总的来说，没有诡异的注意到，全都是基础知识的组合。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;尾声&lt;/h2&gt;
&lt;p&gt;数二高数到此完结，撒花。&lt;/p&gt;
&lt;p&gt;（方法论的坑还妹填。会记得的。。。）&lt;/p&gt;
&lt;p&gt;之后进入九月开始刷真题，我会继续丰富这些笔记的案例，方法论成熟后自会发出来的&lt;/p&gt;
</content:encoded></item><item><title>【学习笔记】数学笔记其八 · 二重积分</title><link>https://blog.emumu.xyz/posts/2026-08-16-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-08-16-00/</guid><description>最简单的一集</description><pubDate>Mon, 17 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;如果你是首次进入我的新数学笔记系列, 请先&lt;a href=&quot;/posts/2026-07-09-00/&quot;&gt;点此阅读预告回&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;二重积分这块整体都非常好搞。公式化、流水线化。虽然多重积分内核丰富，但数二范围内花样十分贫瘠。高数界最矮的山。&lt;/p&gt;
&lt;p&gt;不过它也不是好搞的。它依赖于一个重要的前置: 一元积分。这也使得它凭借计算量成为了卷子上最体力活的题。当然前提是你面对大部分积分时&lt;strong&gt;笔不能停&lt;/strong&gt;。&lt;/p&gt;
&lt;h2&gt;定积分的极限求和定义2&lt;/h2&gt;
&lt;p&gt;二重积分的极限求和定义不需要新东西。我们先把一元的方法抄过来:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;一般来说, 对于一个看起来可以改成积分的&lt;strong&gt;极限求和&lt;/strong&gt;题, 有步骤:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;将原式写成$\lim_{ n \to \infty }\frac{1}{n}\sum_{k=0}^n \cdot f\left(\frac{k}{n}, \frac{1}{n}\right)$, 即提取一个$\frac{1}{n}$因子, 其余部分用$\frac{k}{n}$和$\frac{1}{n}$表示.
其中, $\frac{1}{n}$用于定积分本身定义, $\frac{k}{n}$视为$x$, 且剩余的$\frac{1}{n}$可以直接极限求得$0$.&lt;/li&gt;
&lt;li&gt;令$x = \lim_{n\to\infty} \frac{k}{n}$（即$k/n \to x$），同时令$\frac{1}{n} \to 0$, 得到$f(x,0)$.&lt;/li&gt;
&lt;li&gt;于是极限为$\int_0^1 f(x,0),dx$.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;简单来说，就是&lt;/p&gt;
&lt;p&gt;$$
\lim_{ n \to \infty } \textcolor{magenta}{ \frac{1}{n} }\textcolor{aqua}{ \sum_{i=1}^n }\textcolor{yellow}{ f\left( \frac{i}{n}, \frac{1}{n} \right) } = \textcolor{aqua}{ \int_{0}^1 }\textcolor{yellow}{ f(x,0) }\textcolor{magenta}{ ;dx }
$$&lt;/p&gt;
&lt;p&gt;但我这里为了下文，需要细展开一个上下限:&lt;/p&gt;
&lt;p&gt;$$
\lim_{ n \to \infty } \textcolor{magenta}{ \frac{1}{n} }\textcolor{aqua}{ \sum_{\textcolor{salmon}{ i=1 }}^{\textcolor{lime}{ n }} }\textcolor{yellow}{ f\left( \frac{i}{n}, \frac{1}{n} \right) } = \textcolor{aqua}{ \int_{\textcolor{salmon}{ \frac1n }}^{\textcolor{lime}{ \frac nn }} }\textcolor{yellow}{ f(x,0) }\textcolor{magenta}{ ;dx }
$$&lt;/p&gt;
&lt;p&gt;把一维方法用两次。双和比单和只多一层和号，于是先对&lt;strong&gt;内层&lt;/strong&gt;和用一次一维方法（外层变量此时是常数，但要特别注意$\frac{i}{n}$不能看做$\frac{1}{n}$那样直接趋于$0$），得到一个只含外层变量的单和，再对外层用一次一维方法:&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
&amp;amp;\lim_{n\to\infty}\frac{1}{n^2}\sum_{i=1}^{n}\sum_{j=1}^{\varphi(i,n)}f\left(\frac{i}{n},\frac{j}{n}\right) \&lt;/p&gt;
&lt;p&gt;=&amp;amp;\textcolor{gray}{ \lim_{n\to\infty} }
\textcolor{magenta}{\frac{1}{n}}
\textcolor{aqua}{\sum
_{\textcolor{salmon}{ i=1 }}
^{\textcolor{lime}{ n }}
}
\textcolor{pink}{ \left[
\textcolor{magenta}{\frac{1}{n}}
\textcolor{aqua}{\sum
_{\textcolor{salmon}{ j=1 }}
^{\textcolor{lime}{ \varphi(i,n) }}}
\textcolor{yellow}{f\left(\frac{i}{n},\frac{j}{n}\right)}
\right] } \&lt;/p&gt;
&lt;p&gt;=&amp;amp;\textcolor{gray}{ \lim_{n\to\infty} }
\textcolor{magenta}{\frac{1}{n}}
\textcolor{aqua}{\sum
_{\textcolor{salmon}{ i=1 }}
^{\textcolor{lime}{ n }}
}
\textcolor{pink}{ \left[
\textcolor{aqua}{ \int
_{\textcolor{salmon}{ 1/n }}
^{\textcolor{lime}{ \varphi/n }
} }
\textcolor{yellow}{f\left(\frac{i}{n},x\right) \textcolor{magenta}{ dx }}
\right] },,\quad \textcolor{lime}{ \psi\left( \frac{i}{n} \right)=\frac{\varphi(i,n)}{n} } \textcolor{gray}{ +o(1) } \&lt;/p&gt;
&lt;p&gt;=&amp;amp;\textcolor{gray}{ \lim_{n\to\infty} }
\textcolor{magenta}{\frac{1}{n}}
\textcolor{aqua}{\sum
_{\textcolor{salmon}{ i=1 }}
^{\textcolor{lime}{ n }}
}
\textcolor{pink}{ \left[
\textcolor{aqua}{ \int
_{0}
^{\textcolor{lime}{ \psi(i/n) }
} }
\textcolor{yellow}{f\left(\frac{i}{n},x\right) \textcolor{magenta}{ dx }}
\textcolor{salmon}{+ o(1)}
\right] } \&lt;/p&gt;
&lt;p&gt;=&amp;amp;\textcolor{gray}{ \lim_{n\to\infty} }
\textcolor{magenta}{\frac{1}{n}}
\textcolor{aqua}{\sum
_{\textcolor{salmon}{ i=1 }}
^{\textcolor{lime}{ n }}
}
\textcolor{pink}{ F\left(\frac{i}{n}\right) } \&lt;/p&gt;
&lt;p&gt;=&amp;amp;\textcolor{aqua}{\int
_{\textcolor{salmon}{0}}
^{\textcolor{lime}{1}}
}
\textcolor{pink}{ F(y) }
\textcolor{magenta}{;dy}\&lt;/p&gt;
&lt;p&gt;=&amp;amp;\textcolor{aqua}{\int
_{\textcolor{salmon}{0}}
^{\textcolor{lime}{1}}
}
\textcolor{pink}{
\textcolor{aqua}{ \int
_{\textcolor{salmon}{ 0 }}
^{\textcolor{lime}{ \psi(y) }
} }
\textcolor{yellow}{f\left(y,x\right); \textcolor{magenta}{ dx }}
}
\textcolor{magenta}{;dy}\
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;这就是二重积分的定积分极限求和定义，不难推导。&lt;/p&gt;
&lt;h3&gt;27330:173/&amp;lt;u&amp;gt;120&amp;lt;/u&amp;gt;/★★★★★&lt;/h3&gt;
&lt;p&gt;求极限
$$
\lim_{n\to\infty}\sum_{i=1}^{n}\left[\frac{1}{(n+i+1)^2}+\frac{1}{(n+i+2)^2}+\cdots+\frac{1}{(n+i+i)^2}\right]
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;括号里是$j$从$1$到$i$的和。先按一维方法把$n$提干净，再对$j$、对$i$各用一次一维方法。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;先把每一项里的$n$提出来:
$$
\frac{1}{(n+i+j)^2}=\frac{1}{n^2}\cdot\frac{1}{\left(1+\frac{i}{n}+\frac{j}{n}\right)^2}
$$
原式写成极限求和:
$$
\lim_{n\to\infty}\frac{1}{n}\sum_{i=1}^{n}\underbrace{\left[\frac{1}{n}\sum_{j=1}^{i}\frac{1}{\left(1+\frac{i}{n}+\frac{j}{n}\right)^2}\right]}&lt;em&gt;{\text{第一次: 对 }j}
$$
故有:
$$
\begin{align*}
&amp;amp;\lim&lt;/em&gt;{n\to\infty}\frac{1}{n^2}\sum_{i=1}^{n}\sum_{j=1}^{i} \frac{1}{\left(1+\frac{i}{n}+\frac{j}{n}\right)^2} \
&amp;amp;= \lim_{n\to\infty}\frac{1}{n}\sum_{i=1}^{n} \left[ \frac{1}{n}\sum_{j=1}^{i} \frac{1}{\left(1+\frac{i}{n}+\frac{j}{n}\right)^2} \right], \begin{cases}
x=\frac{j}{n} \
y=\frac{i}{n}
\end{cases} \
&amp;amp;= \lim_{n\to\infty}\frac{1}{n}\sum_{i=1}^{n} \left[ \int_0^y \frac{1}{\left(1+y+x\right)^2},dx + o(1) \right] \
&amp;amp;= \lim_{n\to\infty}\frac{1}{n}\sum_{i=1}^{n} \left[ \left( \frac{1}{1+y} - \frac{1}{1+2y} \right) + o(1) \right] \
&amp;amp;= \int_0^1 \left( \frac{1}{1+y} - \frac{1}{1+2y} \right) dy \
&amp;amp;= \left[ \ln(1+y) - \frac{1}{2}\ln(1+2y) \right]_{0}^{1} \
&amp;amp;= \ln 2 - \frac{1}{2}\ln 3 = \ln\frac{2}{\sqrt{3}}.
\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;优雅的复杂本质是递归和重复。&lt;/p&gt;
&lt;p&gt;内层求和的上限$i$经$\frac{i}{n}\to y$变成内层积分的上限$y$（即$j\le i$对应$x\le y$, 区域是三角形$0\le x\le y\le1$）。内层上限是其他$i$的函数时同理。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;:::note
连续函数在闭区域上必可积，和一维完全平行，这条不用背。另外顺带记一个后面有大用的&quot;废话&quot;: $\iint_D1,d\sigma=D$的面积，面积差法全靠它。
:::&lt;/p&gt;
&lt;h2&gt;二重计算方法&lt;/h2&gt;
&lt;p&gt;方法总览: 对于二重积分$\iint_{D}f(x,y),dxdy$, 流程固定得枯燥:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$f$可以明显分为$g+h$: 分解函数&lt;/li&gt;
&lt;li&gt;区域对称&amp;amp;函数某一部分有奇偶性: 对称消除/翻倍&lt;/li&gt;
&lt;li&gt;$f$在区域内有不可微: 分解区域&lt;/li&gt;
&lt;li&gt;区域很怪,但可以分成两个简单区域之和差: 分解区域&lt;/li&gt;
&lt;li&gt;$f(x,y)$含有$\sqrt{ x^{2}+y^{2} }$要素: 转极坐标&lt;/li&gt;
&lt;li&gt;区域$D$含圆(扇形、圆环等): 转极坐标&lt;/li&gt;
&lt;li&gt;先积的那个积不出来: 交换积分次序&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;方程结构基础&lt;/h3&gt;
&lt;p&gt;先搞清楚一个二重积分&quot;长什么样&quot;，不然后面全是空中楼阁。三个问题:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题一&lt;/strong&gt;: $dx$的位置？&lt;/p&gt;
&lt;p&gt;看累次积分的写法:
$$
\textcolor{lime}{ \int_a^b dx }\textcolor{magenta}{ \int_{\varphi_1(x)}^{\varphi_2(x)} } f(x,y),\textcolor{magenta}{ dy }
$$
这里$\textcolor{lime}{ dx }$夹在两个积分号中间,第二个积分号前面。这是一个约定。本质上$\textcolor{lime}{ dx }$是一个乘上去的量，写在哪都可以，一元积分里约定写在最后。实际上写成
$$
\textcolor{lime}{ \int_a^b }\left[ \textcolor{magenta}{ \int_{\varphi_1(x)}^{\varphi_2(x)} } f(x,y),\textcolor{magenta}{ dy } \right], \textcolor{lime}{ dx }
$$
是一样的。约定写法主要强调计算顺序的先内后外和变量匹配，先算第二个积分号（对$y$积，$x$当参数），得到一个只含$x$的函数，再算第一个积分号（对$x$积）。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;$\iint_D f,dx,dy$里的$dx,dy$只是一个整体面积微元的记号，毕竟同一块面积怎么积出来都是一个值。但你将上下限写出来用作计算之时，你就已经定义了上下限是从哪个轴开始积的了。&lt;/p&gt;
&lt;p&gt;非矩形区域上，内层的上下限会依赖外层变量，故次序不能随便换。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;问题二&lt;/strong&gt;: 能乘积分离的二重积分会变成一次积分的乘积？&lt;/p&gt;
&lt;p&gt;如果被积函数能分离成$f(x,y)=g(x)h(y)$, 且区域是矩形$[a,b]\times[c,d]$:
$$
\begin{align*}
\iint_D g(x)h(y),dx,dy
&amp;amp;=\int_a^b\left[\int_c^d g(x)h(y),dy\right]dx \
&amp;amp;=\int_a^b g(x)\left[\int_c^d h(y),dy\right]dx \
&amp;amp;=\int_c^d h(y),dy\cdot\int_a^b g(x),dx
\end{align*}
$$
这个结果虽然反直觉，但其实完全可以用一元积分的知识点解释。上面的推导即是一种。实际例子是:
$$
\iint_{[0,1]\times[0,2]} x^2y,dx,dy
=\left(\int_0^1 x^2,dx\right)\left(\int_0^2 y,dy\right)
=\frac13\cdot2=\frac23
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题三&lt;/strong&gt;: 只给区域定义怎么写出上下限？&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这个概念很简单 但感觉要解答这个问题要画很多图。这里就不写了，初学网上有很多方法，会一次就会一百次了。&lt;/p&gt;
&lt;p&gt;最大问题在于有多种写法怎么写更好。这个东西还是看脑内草稿缓存容量利用率。虽然脑内Cache容量是固定的，但推导时存储的意象更小可以让你探查到更远的步骤，从而知道哪些路走得通走不通。&lt;/p&gt;
&lt;p&gt;说白了就是多做。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;交换次序法&lt;/h3&gt;
&lt;p&gt;一般来说，一个普通的函数+面积二重积分展开之后只有四种情况，分别是:
$$
\begin{align*}
\begin{cases}
\int dy\int f; dx \
\int dx\int f; dy \
\end{cases} \[6pt]
\begin{cases}
\int d\theta\int f; dr \
\int dr\int f; d\theta
\end{cases}
\end{align*}
$$
换序实质上就是在这些东西之间两两交换。所以只要会所有写出上下限的方法基本就可以了。换序求得的积分值是不变的。&lt;/p&gt;
&lt;p&gt;什么时候需要换序？先积的那个变量积不出来的时候。典型如$e^{x^2}$、$\dfrac{\sin x}{x}$这种没有初等原函数的，换。例:
$$
I=\int_0^1 dx\int_x^1 e^{y^2},dy
$$&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;Pasted%20image%2020260817043759.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;内层$\int e^{y^2}dy$没有初等原函数。画区域: $0\le x\le1$, $x\le y\le1$, 等价于$0\le y\le1$, $0\le x\le y$。换序:
$$
I=\int_0^1 dy\int_0^y e^{y^2},dx
=\int_0^1 y,e^{y^2},dy
=\frac12\left(e^{y^2}\right)\Big|_0^1
=\frac{e-1}{2}
$$&lt;/p&gt;
&lt;h3&gt;变量代换法&lt;/h3&gt;
&lt;p&gt;极坐标是它的特例，先讲一般形式，后面才好理解极坐标为什么多个$r$。&lt;/p&gt;
&lt;p&gt;一般换元步骤:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;有$\iint_D f(x,y),dx,dy$&lt;/li&gt;
&lt;li&gt;我们判断将其映射到$u(x,y)$,$v(x,y)$上会更方便计算&lt;/li&gt;
&lt;li&gt;设根据以上映射, $f(x,y)=g(u,v)$&lt;/li&gt;
&lt;li&gt;$xy$平面区域$D$&lt;strong&gt;被映射到&lt;/strong&gt;$uv$平面区域$D&apos;$
$$
\iint_D f(x,y),dx,dy
=\iint_{D&apos;} g(u,v),|J|,du,dv
$$
其中，使用$x=x(u,v),,y=y(u,v)$, 则有:
$$
J=\frac{\partial(x,y)}{\partial(u,v)}=\begin{vmatrix}
x_u &amp;amp; x_v\
y_u &amp;amp; y_v
\end{vmatrix}=x_uy_v-x_vy_u
$$
$|J|$是什么？换元把$uv$平面上一个小矩形变成$xy$平面上一个小平行四边形，面积伸缩的倍数就是$|J|$。它替我们回答&quot;变完之后面积还对不对&quot;的问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当然数二只需要知道两个特例:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;一、平移换元&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;面积不伸缩($J=1$)，只要记得&lt;strong&gt;弄明白被积区域&lt;/strong&gt;即可。&lt;/p&gt;
&lt;p&gt;改圆心例题如求
$$
\begin{align*}
\iint_D\big[(x-1)^2+(y-2)^2\big],dx,dy \
D={(x,y) | (x-1)^2+(y-2)^2\le4}
\end{align*}
$$
区域是以$(1,2)$为中心的圆域，直接极坐标的话圆心不对。先平移换元&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
&amp;amp;\begin{cases}
u=x-1 \
v=y-2 \
\end{cases} \[6pt]
&amp;amp;\begin{cases}
(x-1)^2+(y-2)^2=u^{2}+v^{2} \
{(x,y) | (x-1)^2+(y-2)^2\le4}={(u,v) | u^2+v^2\le4}
\end{cases} \[6pt]&lt;/p&gt;
&lt;p&gt;&amp;amp;\iint_{(x-1)^2+(y-2)^2\le4}\big[(x-1)^2+(y-2)^2\big],dx,dy \
=&amp;amp;\iint_{u^2+v^2\le4}(u^2+v^2),du,dv&lt;/p&gt;
&lt;p&gt;\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;一般的线性变换下$J$是常数，也不难算。&lt;/p&gt;
&lt;p&gt;不过有个细节是公式里是$|J|$, 不会出现负数。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;:::tip
这个$J$我们一般管它叫&lt;strong&gt;雅可比行列式&lt;/strong&gt;。没错，就是那个最近被fable 5证伪的雅可比猜想里，为常数的那个雅可比行列式。&lt;/p&gt;
&lt;p&gt;至于$\frac{\partial(x,y)}{\partial(u,v)}=\begin{vmatrix}x_u &amp;amp; x_v\y_u &amp;amp; y_v\end{vmatrix}$是怎么来的，虽然数二里是超纲内容，但我这里还是推荐个视频简单理解一下: &lt;a href=&quot;https://www.bilibili.com/video/BV1nZ3b6jErG&quot;&gt;什么函数导出来是个矩阵? 雅可比矩阵科普&lt;/a&gt;
:::&lt;/p&gt;
&lt;h3&gt;极坐标法&lt;/h3&gt;
&lt;p&gt;本质就是变量代换
$$
\begin{align*}
&amp;amp;\begin{cases}
x=r\cos\theta \
y=r\sin\theta
\end{cases} \[6pt]&lt;/p&gt;
&lt;p&gt;J&amp;amp;=\begin{vmatrix}\cos\theta&amp;amp;-r\sin\theta\ \sin\theta&amp;amp;r\cos\theta\end{vmatrix}=r(\cos ^{2}\theta+\sin ^{2}\theta)=r \[6pt]&lt;/p&gt;
&lt;p&gt;dx,dy&amp;amp;=r,dr,d\theta
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;多出来的$r$就是这么来的。&lt;/p&gt;
&lt;p&gt;当区域是圆、环、扇形，或被积函数里有$x^2+y^2$、$\dfrac{y}{x}$、$xy$这类团块时，推荐用极坐标。如上个例子中结尾留的:&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
&amp;amp;\iint_{x^2+y^2\le4}(x^2+y^2),dx,dy \
=&amp;amp;\int_0^{2\pi}d\theta\int_0^2 r^2\cdot r,dr \
=&amp;amp;2\pi\cdot4 \
=&amp;amp;8\pi
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;其中$\theta$的$[0,2\pi]$是一个圆的全方位，而$r$的$[0,2]$是指圆是实心的（从内圈r=0到外圈，即半径$r=2$）写出上下限与换序的方法同直角坐标，此处不再重复:spoiler[不过基本都是先半径再角度]。&lt;/p&gt;
&lt;p&gt;常用直角坐标方程改极坐标:&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
y&amp;amp;=a \
r\sin \theta&amp;amp;=a \
r&amp;amp;=\frac{a}{\sin \theta}
\end{align*}
$$
$$
\begin{align*}
x&amp;amp;=a \
r\cos \theta&amp;amp;=a \
r&amp;amp;=\frac{a}{\cos \theta}
\end{align*}
$$
$$&lt;/p&gt;
&lt;p&gt;\begin{align*}
x^2+y^2&amp;amp;=2ax \
r^{2}&amp;amp;=2a r \cos \theta \
r&amp;amp;=2a \cos \theta
\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;圆心不在原点的圆也能用极坐标，只是$\theta$范围会变成半个圆周。比如$x^2+y^2=2x$即$r\le2\cos\theta$, 此时$\theta\in\left[-\frac\pi2,\frac\pi2\right]$——过原点的圆，$\theta$扫半圈。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;分解法&lt;/h3&gt;
&lt;p&gt;二重积分可以从两个方向拆，和一元积分是对应的。拆完之后&lt;strong&gt;各算各的&lt;/strong&gt;，甚至可以一项用直角一项用极坐标，完全互不干扰。哪项好算，就给它配哪种方法。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 按被积函数拆(式和):&lt;/strong&gt;
$$
\iint_D(\textcolor{aqua}{ f_1+f_2 }),dx,dy
=\iint_D \textcolor{aqua}{ f_1 },dx,dy
+\iint_D \textcolor{aqua}{ f_2 },dx,dy
$$
这种方法在一元积分上是完全一样的&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. 按区域拆(限的分解):&lt;/strong&gt;&lt;br /&gt;
$$
\iint_{\textcolor{lime}{ D }} f,dx,dy
=\iint_{\textcolor{lime}{ D_1 }}f,dx,dy
+\iint_{\textcolor{lime}{ D_2 }}f,dx,dy
,\quad \textcolor{lime}{ D=D_1\cup D_2 }
$$
区域长得歪七扭八时，先拆成几块规整的。你应该已经知道这种方法对应一元积分的什么了。&lt;/p&gt;
&lt;p&gt;没错, $\int_{a}^\xi+\int_{\xi}^b$.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. 构造差法:&lt;/strong&gt; 复杂区域的面积可以大块减挖空:
$$
\iint_{\textcolor{lime}{ D_1 }}f,dx,dy
=\iint_{\textcolor{lime}{ D }}f,dx,dy
-\iint_{\textcolor{lime}{ D_2 }}f,dx,dy
,\quad \textcolor{lime}{ D=D_1\cup D_2 }
$$&lt;/p&gt;
&lt;p&gt;这不小学割补算面积题吗。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. 奇点(奇线)必须剪开:&lt;/strong&gt; 被积函数在某点/某线上无定义或不可微，直接积分绝对积不动。唯一指定方法是按区域拆分，具体来说是&lt;strong&gt;沿奇线把区域剪开&lt;/strong&gt;，每一块内函数都可积，分别积分再加。有例:
$$
\iint_{[-2,2]\times[0,4]}|x^2-y|,dx,dy
$$
$|x^2-y|$在$y=x^2$这条抛物线上“折”了一下(绝对值变号)，这就是奇线。沿$y=x^2$把矩形剪成两块:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;下方$R_1={x\in[-2,2],\ 0\le y\le x^2}$, 此时$|x^2-y|=x^2-y$:
$$
I_1=\int_{-2}^{2}dx\int_0^{x^2}(x^2-y),dy
=\int_{-2}^{2}\frac{x^4}{2},dx=\frac{32}{5}
$$&lt;/li&gt;
&lt;li&gt;上方$R_2={x\in[-2,2],\ x^2\le y\le4}$, 此时$|x^2-y|=y-x^2$:
$$
I_2=\int_{-2}^{2}dx\int_{x^2}^{4}(y-x^2),dy
=\int_{-2}^{2}\left(8-4x^2+\frac{x^4}{2}\right)dx=\frac{256}{15}
$$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;相加:
$$
\iint_{[-2,2]\times[0,4]}|x^2-y|,dx,dy=\frac{32}{5}+\frac{256}{15}=\frac{352}{15}
$$&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;Pasted%20image%2020260816055603.png&quot; alt=&quot;f=|x^2-y|的形态&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;剪开的线就是&lt;strong&gt;绝对值变号线&lt;/strong&gt;（或分母为零的线）。先找线，再分块，最后各积各的——顺序不能乱。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;对称性&lt;/h3&gt;
&lt;p&gt;一元版本的对称性已经很强了，二元版本更是机制怪。&lt;/p&gt;
&lt;p&gt;这里利用对称性一般都是轴对称。要利用对称性，要判断(或构造)两个条件:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 区域对称&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;区域对称一般都很好看出来。画图肯定会吧，画完图还不难看出吗。&lt;/p&gt;
&lt;p&gt;在二维对称上，也能判断关于斜线如$y=x$对称。&lt;/p&gt;
&lt;p&gt;如果难以判断后续函数的奇偶性，我们要记住此次完成的区域对称映射，如&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;沿$x$轴对称: $(x,y)\to(x,-y)$&lt;/li&gt;
&lt;li&gt;沿$y=x$对称: $(x,y)\to(y,x)$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;要严谨定义的话，沿$y=x$对称表述为: $(x,y)\in D\implies(y,x)\in D$ .&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. 函数值对称&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;函数值对称没那么容易看出来。至少在非轴向的对称轴上没那么容易。&lt;/p&gt;
&lt;p&gt;对于轴向的区间对称，和一元函数判断完全一样。在已有区域对称的基础上，举例来说:&lt;/p&gt;
&lt;p&gt;设区域$D$关于$y$轴($x=0$)对称, 即$(x,y)\in D\Rightarrow(-x,y)\in D$.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$f$关于$x=0$为&lt;strong&gt;奇&lt;/strong&gt;, $f(-x,y)=-f(x,y)$
&lt;ul&gt;
&lt;li&gt;$\iint_D f=0$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;$f$关于$x=0$为&lt;strong&gt;偶&lt;/strong&gt;, $f(-x,y)=f(x,y)$
&lt;ul&gt;
&lt;li&gt;$\iint_D f=2\iint_{D\cap{x\ge0}}f$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对于非轴向轴对称的情况下如$y=x$时, 即$(x,y)\in D\Rightarrow(y, x)\in D$.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$f$关于$y=x$为&lt;strong&gt;奇&lt;/strong&gt;, $f(x,y)=-f(y,x)$
&lt;ul&gt;
&lt;li&gt;$\iint_D f=0$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;$f$关于$y=x$为&lt;strong&gt;偶&lt;/strong&gt;, $f(x,y)=f(y,x)$
&lt;ul&gt;
&lt;li&gt;$\iint_D f=2\iint_{D\cap{y\geq x}}f$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::tip
任何函数都能分解成奇偶两部分。比如关于$y$轴有:
$$
f(x)=\underbrace{\frac{f(x)+f(-x)}{2}}&lt;em&gt;{\text{关于}x\text{偶}}+\underbrace{\frac{f(x)-f(-x)}{2}}&lt;/em&gt;{\text{关于}x\text{奇}}
$$
有时候这对于有对称性但积不出来的积分是很有效的。
:::&lt;/p&gt;
&lt;h3&gt;27330:180/&amp;lt;u&amp;gt;90&amp;lt;/u&amp;gt;/★★★★★&lt;/h3&gt;
&lt;p&gt;设$D$为$y=x^5$、$y=1$、$x=-1$所围成的平面区域，$f$连续。求积分
$$
I=\iint_D x\left[1+\sin\big(y^3 f(x^4+y^4)\big)\right],dx,dy
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;$x^4+y^4$是&quot;换元不变&quot;的护身符（$x$、$y$变号都不变），$y^3$负责给$\sin$里配一个关于$y$奇的东西。剩下就是把区域劈成两半，把$\sin$项按对称区间积掉——全程用不到$f$的任何信息。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;三条曲线两两交于$(-1,-1)$、$(-1,1)$、$(1,1)$三点，故
$$
D={(x,y):-1\le x\le1,\ x^5\le y\le1}
$$&lt;/p&gt;
&lt;p&gt;把积分拆成两项:
$$
\begin{align*}
I&amp;amp;=I_{1}+I_{2} \
I_{1}&amp;amp;=\iint_D x,dx,dy \
I_{2}&amp;amp;=\iint_D x\sin\big(y^3f(x^4+y^4)\big),dx,dy
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第一项:&lt;/strong&gt;
$$
\begin{align*}
&amp;amp;\iint_D x,dx,dy=\int_{-1}^{1}x,dx\int_{x^5}^{1}dy \
=&amp;amp;\int_{-1}^{1}x(1-x^5),dx \
=&amp;amp;\int_{-1}^{1}(x-x^6),dx \
=&amp;amp;\left[\frac{x^2}{2}-\frac{x^7}{7}\right]_{-1}^{1} \
=&amp;amp;-\frac{2}{7}
\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;不难注意到，第二项函数是关于x、y都奇对称的&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;第二项:&lt;/strong&gt; 记$g(x,y)=x\sin\big(y^3f(x^4+y^4)\big)$, 则有
$$
\begin{align*}
g(x,-y)&amp;amp;=x\sin\big((-y)^3f(x^4+y^4)\big)=-g(x,y) \
g(-x,y)&amp;amp;=-x\sin\big(y^3f((-x)^4+y^4)\big)=-g(x,y)
\end{align*}
$$
即第二项关于两轴均为奇函数。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;但积分区域也不对称啊，怎么办呢&lt;/p&gt;
&lt;p&gt;这时候我们有第一种做法: 分区间&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;Pasted%20image%2020260817091049.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
&amp;amp;\begin{cases}
D&amp;amp;= {(x,y):-1\le x\le1,\ x^5\le y\le1} \
D_{1}&amp;amp;= {(x,y):-1\le x\le1,\ |x^{5}|\le y\le1} \
D_{2}&amp;amp;= {(x,y):-1\le x\le0,\ x^{5}\le y\le -x^{5}} \
D&amp;amp;=D_{1}+D_{2}
\end{cases} \[6pt]
&amp;amp;\begin{cases}
I_{2}&amp;amp;=\iint_D x\sin\big(y^3f(x^4+y^4)\big),dx,dy \
I_{21}&amp;amp;=\iint_{D_{1}} x\sin\big(y^3f(x^4+y^4)\big),dx,dy \
I_{22}&amp;amp;=\iint_{D_{2}} x\sin\big(y^3f(x^4+y^4)\big),dx,dy \
I_{2}&amp;amp;=I_{21}+I_{22}
\end{cases}
\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这里的区间完全是通过画图并观察的方式分割的，纯代数分割不太可行。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;显然，$I_{21}$关于$x=0$对称，$I_{22}$关于$y=0$对称，原函数关于x,y均为奇函数。&lt;/p&gt;
&lt;p&gt;故有$I_{2}=I_{21}+I_{22}=0$&lt;/p&gt;
&lt;p&gt;于是
$$
\boxed{I=-\frac{2}{7}}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;世界线二:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;第二项:&lt;/strong&gt; 记$g(x,y)=x\sin\big(y^3f(x^4+y^4)\big)$, 则有
$$
\begin{align*}
g(x,-y)&amp;amp;=x\sin\big((-y)^3f(x^4+y^4)\big)=-g(x,y) \
g(-x,y)&amp;amp;=-x\sin\big(y^3f((-x)^4+y^4)\big)=-g(x,y)
\end{align*}
$$
由$g(x,-y)=g(-x,y)$, 函数是关于原点的偶函数。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;既然注意到了这样诡异的对称，那么这次我们用点更诡异的:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;Pasted%20image%2020260817094056.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
&amp;amp;\begin{cases}
D&amp;amp;= {(x,y):-1\le x\le1,\ x^5\le y\le1} \
D_{1}&amp;amp;= {(x,y):-1\le x\le1,\ x\le y\le1} \
D_{2}&amp;amp;= {(x,y):0\le x\le1,\ x^{5}\le y\le x} \
D_{3}&amp;amp;= {(x,y):-1\le x\le0,\ x\le y\le x^{5}} \
D&amp;amp;=D_{1}+D_{2}-D_{3}
\end{cases} \[6pt]
&amp;amp;\begin{cases}
f&amp;amp;=x\sin\big(y^3f(x^4+y^4)\big) \
I_{2}&amp;amp;=\iint_D f ,dx,dy \
I_{21}&amp;amp;=\iint_{D_{1}} f ,dx,dy \
I_{22}&amp;amp;=\iint_{D_{2}} f ,dx,dy \
I_{23}&amp;amp;=\iint_{D_{3}} f ,dx,dy \
I_{2}&amp;amp;=I_{21}+I_{22}-I_{23}
\end{cases}
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;注意到$g(x,-y)=g(-x,y)$, 即函数是&lt;strong&gt;关于原点&lt;/strong&gt;对称的&lt;strong&gt;偶函数&lt;/strong&gt;, 同时$D_{2}$和$D_{3}$关于原点中心对称, 即有$I_{22}=I_{23}$.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;之后证$I_{21}=0$, 读者自证不难。&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>一次扑朔迷离的线上 404：MPA 应用集体失踪事件</title><link>https://blog.emumu.xyz/posts/2026-08-15-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-08-15-00/</guid><description>少写一个_blank，三个页面变成404。cyberchef诡异幸存，示例应用不示例。真凶是预渲染爬虫顺着直链爬进了静态资源。</description><pubDate>Sat, 15 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;实验室主页上，除了cyberchef，所有MPA应用（Mikutap、散点绘制、魔法阵工坊）一夜之间点进去全变成了项目的404页面。&lt;/p&gt;
&lt;p&gt;而一天之前，这一切完全正常。 我确信自己没改掉什么重要的东西，只是觉得&lt;strong&gt;在主页新增一个直链&lt;/strong&gt;这种小事，不可能造成这种影响。&lt;/p&gt;
&lt;p&gt;症状很规整，规整到让人以为找到了规律：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;五个静态&lt;code&gt;.html&lt;/code&gt;入口里，三个&lt;code&gt;index.html&lt;/code&gt;全部404&lt;/li&gt;
&lt;li&gt;同时，SPA的正常路由也出现404&lt;/li&gt;
&lt;li&gt;只有cyberchef幸免&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;一&lt;/h2&gt;
&lt;p&gt;项目中一共有五个在静态资源中的页面。其中三个都显示了&lt;strong&gt;SPA 404&lt;/strong&gt;页面。我猜，&amp;lt;u&amp;gt;EdgeOne改了404路由行为&amp;lt;/u&amp;gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;## 404
- [ ] https://lab.emumu.xyz/appx/mikutap/index.html
- [ ] https://lab.emumu.xyz/appx/scatter/index.html
- [ ] https://lab.emumu.xyz/appx/magicring/index.html
      
## 正常访问
- [x] https://lab.emumu.xyz/appx/cyberchef/CyberChef_v10.22.1.html
- [x] https://lab.emumu.xyz/appx/magicring/rulebook.html
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;需要注意的是，在这之前项目的404一直是EO默认404样式。我没去修的原因是在我发现这个问题不久后更新了对&lt;code&gt;edgeone.json&lt;/code&gt;文件的支持，我想到可能还要去看文档，不如算了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;Pasted%20image%2020260815043402.png&quot; alt=&quot;EO默认404页面&quot; /&gt;&lt;/p&gt;
&lt;p&gt;而我自己的404页面在我本地&lt;code&gt;dev&lt;/code&gt;时总是合情合理地在它该出现的位置出现。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;Pasted%20image%2020260815043325.png&quot; alt=&quot;我的SPA 404页面。甚至还残留了css问题&quot; /&gt;&lt;/p&gt;
&lt;p&gt;看起来就是平台把没命中静态文件的请求都回退到了SPA的&lt;code&gt;index.html&lt;/code&gt;，客户端路由一看路径不认识，渲染了项目404页。合情合理，简直无懈可击。&lt;/p&gt;
&lt;p&gt;而且更重要的是，现在我加载不动我收藏夹里的&lt;a href=&quot;https://console.cloud.tencent.com&quot;&gt;官网控制台&lt;/a&gt;，而其他网站一切正常。六六六，腾讯云跑路了。&lt;s&gt;现在想来大概率是我改代理规则改坏了&lt;/s&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;二&lt;/h2&gt;
&lt;p&gt;症状很显然，其余三个全是&lt;code&gt;index.html&lt;/code&gt;。我猜，&amp;lt;u&amp;gt;文件名带&amp;lt;code&amp;gt;index.html&amp;lt;/code&amp;gt;的被强制闪避了&amp;lt;/u&amp;gt;。&lt;/p&gt;
&lt;p&gt;于是我把三个MPA各复制出一份非index命名的入口文件，改配置、推送、部署。&lt;/p&gt;
&lt;p&gt;新文件如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/appx/mikutap/index.html   -&amp;gt; /appx/mikutap/mikutap.html
/appx/scatter/index.html   -&amp;gt; /appx/scatter/scatter.html
/appx/magicring/index.html -&amp;gt; /appx/magicring/magicring.html
+ /appx/example/index.html
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;新文件&lt;code&gt;scatter.html&lt;/code&gt;, &lt;code&gt;magicring.html&lt;/code&gt;依然404。&lt;/p&gt;
&lt;p&gt;新探针文件&lt;code&gt;/appx/example/index.html&lt;/code&gt;&lt;strong&gt;可正常访问&lt;/strong&gt;。这个新的example甚至就是我一天前删掉的。&lt;/p&gt;
&lt;p&gt;无比诡异的实验结果正对着上一次的明显症状扇了一巴掌。&lt;/p&gt;
&lt;p&gt;Deepseek思考良久，问我测试一下&lt;code&gt;/appx/magicring/index.html?t=1&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;我靠，通了？我靠，我靠。难道真是缓存的问题？那这一致性不一致得有点严重了。&lt;/p&gt;
&lt;p&gt;我本能地测了一下&lt;code&gt;/appx/magicring/index.html&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;我靠，怎么也通了？&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;三&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;## 404
- [ ] https://lab.emumu.xyz/appx/mikutap/mikutap.html
- [ ] https://lab.emumu.xyz/appx/scatter/scatter.html
- [ ] https://lab.emumu.xyz/appx/magicring/magicring.html

## 正常访问
- [x] https://lab.emumu.xyz/appx/mikutap/index.html
- [x] https://lab.emumu.xyz/appx/scatter/index.html
- [x] https://lab.emumu.xyz/appx/magicring/rulebook.html
- [x] https://lab.emumu.xyz/appx/magicring/index.html
- [x] https://lab.emumu.xyz/appx/example/index.html
- [x] https://lab.emumu.xyz/appx/cyberchef/CyberChef_v10.22.1.html
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;debug到这里，目前以我的能力唯一能看出来的是，新传上去的东西没了，旧的活了。&lt;/p&gt;
&lt;p&gt;简直扑朔迷离。&lt;/p&gt;
&lt;p&gt;这时候D老师问我真是404吗？&lt;/p&gt;
&lt;p&gt;D老师的harness是我正在测试的DSH，Deepseek推出的官方harness。各家的harness或多或少在shell上都有点问题出现，DSH亦是如此，D老师不止一次地向我强调HTTPS不可用，它最终使用HTTP直接访问是可以访问的。我仔细看它的工具调用想找出为什么，它访问页面判断404的方法是&lt;strong&gt;检查响应体长度&lt;/strong&gt;。预渲染的长度是一样的。&lt;/p&gt;
&lt;p&gt;等会，你检查响应体干什么，你不会看&lt;code&gt;status_code&lt;/code&gt;吗？&lt;/p&gt;
&lt;p&gt;我靠，这不是404，这tm不是200吗？&lt;/p&gt;
&lt;p&gt;所有URL现在都是&lt;strong&gt;HTTP 200&lt;/strong&gt;。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;四&lt;/h2&gt;
&lt;p&gt;首先，我的项目使用&lt;code&gt;@preact/preset-vite&lt;/code&gt;+&lt;code&gt;vite-prerender-plugin&lt;/code&gt;做SSR预渲染。这个插件的&lt;code&gt;generateBundle&lt;/code&gt;干的事情是:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;从&lt;code&gt;/&lt;/code&gt;和&lt;code&gt;/404&lt;/code&gt;开始渲染&lt;/li&gt;
&lt;li&gt;每次渲染结果里的&lt;code&gt;result.links&lt;/code&gt;递归入队继续预渲染
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;result.links&lt;/code&gt;来自&lt;code&gt;preact-iso&lt;/code&gt;收集的所有&lt;code&gt;&amp;lt;a href&amp;gt;&lt;/code&gt;链接&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;每个链接以&lt;code&gt;emitFile&lt;/code&gt;写盘到dist的对应路径&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;其次，我的404页面有一个“猜你想去”。它检查你的路由，对比应用里所有的路由，计算编辑距离(具体来说是osa距离)，然后列出其中最小的&lt;strong&gt;三条&lt;/strong&gt;，摆成美味的anchor。&lt;/p&gt;
&lt;p&gt;最后，我昨晚对主页进行了大改。引人注目的一项改动是添加了“新应用体验快链”，快链中有&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;a href=&quot;/appx/magicring/index.html&quot; target=&quot;_self&quot; class=&quot;...&quot;&amp;gt;
  &amp;lt;span class=&quot;...&quot;&amp;gt;新&amp;lt;/span&amp;gt;
  &amp;lt;span class=&quot;...&quot;&amp;gt;魔法阵工坊&amp;lt;/span&amp;gt;
  &amp;lt;span class=&quot;...&quot;&amp;gt;魔法阵编译器，一段代码生成一个魔法阵
  &amp;lt;/span&amp;gt;
  &amp;lt;svg.../svg&amp;gt;
&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;/appx/magicring/index.html&lt;/code&gt;就这样出现在了文档里。于是预渲染爬虫顺着它爬进了静态资源目录。&lt;/p&gt;
&lt;p&gt;爬虫渲染这个路径时，SPA路由匹配不到，渲染出一个「起始404」页&lt;/p&gt;
&lt;p&gt;而我的404页面实现了osa距离推荐，会把距离最近的前三条路径当建议链接列出来&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这三条正好就是Mikutap、散点绘制、魔法阵工坊的&lt;code&gt;index.html&lt;/code&gt;。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;爬虫又顺着这些建议链接继续爬，把三个入口全预渲染成了404页，&lt;code&gt;emitFile&lt;/code&gt;写盘，覆盖了vite从&lt;code&gt;public/&lt;/code&gt;拷过来的真实文件。&lt;/p&gt;
&lt;p&gt;出于无向全连接图的某种性质，这三个页面的前三个相似路径还是这三个路径&lt;/p&gt;
&lt;p&gt;于是，一个假的静态404页在&lt;code&gt;dist/appx/mikutap/index.html&lt;/code&gt;生成了。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;五&lt;/h2&gt;
&lt;p&gt;我唯一可预见的做错了的，是对SPA外的链接少写一个&lt;code&gt;_blank&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;对，触发点就是首页快链缺blank。它是唯一能把爬虫带进&lt;code&gt;/appx/&lt;/code&gt;的入口。&lt;code&gt;/all&lt;/code&gt;中有所有应用的链接，但它们都不会把爬虫带进去，因为&lt;code&gt;_blank&lt;/code&gt;是安全词。&lt;/p&gt;
&lt;p&gt;在应用的&lt;code&gt;prerender&lt;/code&gt;函数里把&lt;code&gt;/appx/&lt;/code&gt;链接过滤掉，爬虫就永远不会触碰这些路径：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export async function prerender(_: unknown) {
  const result = await ssr(&amp;lt;App /&amp;gt;);
  // 过滤掉 /appx/* 链接：vite-prerender-plugin 会沿着 result.links 递归预渲染并写盘，
  // 若包含 MPA 静态页路径，预渲染出的 SPA 页面会覆盖 public/appx 下的真实文件。
  const links = [...(result.links ?? [])].filter(
    (url) =&amp;gt; !url.startsWith(&quot;/appx/&quot;),
  );
  // ...SEO 处理...
  return { ...result, links, html };
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>【学习笔记】数学笔记其七 · 多元函数微分学</title><link>https://blog.emumu.xyz/posts/2026-08-08-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-08-08-00/</guid><description>高数终于看到头了，后三期都比较简单</description><pubDate>Mon, 10 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;如果你是首次进入我的新数学笔记系列, 请先&lt;a href=&quot;/posts/2026-07-09-00/&quot;&gt;点此阅读预告回&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;多元函数微分学延续了微分学的调性，概念多，计算简单。但比一元微分学还温和一点，这篇不考大证明题，也没有什么诡异的中值。题型主要分成三种:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;概念&lt;/strong&gt;。主要考小题，大题也有涉及。量不少、不难、不杂。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;“证明$z=f(x,y)\cdot g(x,y)$在$(0,0)$处可微”&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;“$f(x,y)$在$(0,0)$处可微的充分条件是……”&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;计算&lt;/strong&gt;。大小题均有，包括复合函数求导和偏微分的积分。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;*“设$f(x,y)=$……则$df(x,y)|_{(0,1)}=$……”&lt;/li&gt;
&lt;li&gt;&lt;em&gt;“$F(x,y,z)$确定隐函数……$z&apos;_{x}(1,1)=$……”&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;极值&lt;/strong&gt;。主要考大题，高度模板化，送分大头。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;“求函数$f(x,y)$的最小值”&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;“证明函数在……上有最大值”&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;概念题&lt;/h2&gt;
&lt;h3&gt;重极限&lt;/h3&gt;
&lt;p&gt;事情要从极限底下变成两个符号那天说起。&lt;/p&gt;
&lt;p&gt;我们说一元极限$x\to x_0$, 它只有&lt;strong&gt;左&lt;/strong&gt;、&lt;strong&gt;右&lt;/strong&gt;两条路，再怎么走也只需要&lt;strong&gt;左右&lt;/strong&gt;极限相等即可。&lt;/p&gt;
&lt;p&gt;二元极限要求$P(x,y)$在平面上以&lt;strong&gt;任意方式&lt;/strong&gt;趋近$P_0(x_0,y_0)$时函数值都趋于同一个数$L$:&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
&amp;amp;\lim_{(x,y)\to(x_0,y_0)} f(x,y) = L \iff \
&amp;amp;\forall\varepsilon&amp;gt;0,\ \exists\delta&amp;gt;0,\ 0&amp;lt;\sqrt{(x-x_0)^2+(y-y_0)^2}&amp;lt;\delta \Rightarrow |f(x,y)-L|&amp;lt;\varepsilon&lt;/p&gt;
&lt;p&gt;\end{align*}
$$&lt;/p&gt;
&lt;p&gt;路有&lt;strong&gt;无限多条&lt;/strong&gt;。任有一条走不通，或者两条的极限不一样，最终极限就不存在。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;Pasted%20image%2020260808024403.png&quot; alt=&quot;重极限要求沿任意路径结果一致，图中抛物线逼近曲线时极限不存在&quot; /&gt;&lt;/p&gt;
&lt;p&gt;图中函数为:&lt;/p&gt;
&lt;p&gt;$$
f(x,y)=\frac{x^2y}{x^4+y^2}
$$&lt;/p&gt;
&lt;p&gt;我们要判定它在$(0,0)$&lt;strong&gt;不存在&lt;/strong&gt;非常简单，只要代入一条抛物线$y=kx^{2}$就能立刻证明:&lt;/p&gt;
&lt;p&gt;$$
f(x, kx^{2})=\frac{x^{2}kx^{2}}{x^4+k^{2}x^4}=\frac{k}{1+k^{2}}
$$&lt;/p&gt;
&lt;p&gt;显然，极限随$k$变化，故$(0,0)$处极限不存在。&lt;/p&gt;
&lt;p&gt;这里$y=kx^{2}$不是瞎找的，实际上$y=kx$和$y=kx^{2}$就足够判断绝大多数函数极限不存在了。如果真有判不出来的那大概率得现场分析了。&lt;/p&gt;
&lt;p&gt;判定&lt;strong&gt;存在&lt;/strong&gt;则麻烦得多。一种常用的方法是换极坐标，&lt;strong&gt;简单来说，“趋近”这一行为本质上是$\textcolor{pink}{ r=\sqrt{ x^{2}+y^{2} } }$的下降&lt;/strong&gt;，因此令$x-x_0=r\cos\theta$、$y-y_0=r\sin\theta$, 若能找到一个&lt;strong&gt;与$\textcolor{pink}{ \theta }$无关&lt;/strong&gt;、随$r\to 0$而趋于零的量控制住$|f-L|$, 则极限存在。&lt;/p&gt;
&lt;p&gt;同理，如果能找到上下两个$r\to 0$、能把$f$值夹逼到同一个点的两个函数，也可以证明极限存在。&lt;/p&gt;
&lt;h3&gt;累次极限&lt;/h3&gt;
&lt;p&gt;$$
\lim\limits_{x\to x_0}\lim\limits_{y\to y_0}f(x,y)
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意它和重极限完全不一样&lt;/strong&gt;，它们就是简单地、从内到外依次&lt;strong&gt;互不干扰地&lt;/strong&gt;求极限。先固定里面的变量简单取$y\to y_{0}$的一元极限、再对外面的取，顺序不能颠倒。&lt;strong&gt;顺序不同可能导致结果不同&lt;/strong&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;可惜的是重极限与累次极限&lt;strong&gt;互不蕴含&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;$\dfrac{xy}{x^2+y^2}$重极限不存在，但两个累次极限都存在且为0&lt;/p&gt;
&lt;p&gt;$x\sin\frac1y$（$y=0$处补0）的重极限为0，但先对$y$取极限时内层极限不存在，累次极限也不存在。&lt;/p&gt;
&lt;p&gt;唯一可用的结论是: &lt;strong&gt;若重极限与某顺序的累次极限都存在，则二者相等&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;:::tip
狄利克雷函数$D(x)$的一种常见构造就基于累次极限。
$$
D(x)=\lim_{k\to\infty}\lim_{j\to\infty}\left[\cos(k!\pi x)\right]^{2j}
$$
交换$k,j$的取极限次序后,表达式在有理数点取值为1，在无理数点是发散/无定义的。
:::&lt;/p&gt;
&lt;h3&gt;连续&lt;/h3&gt;
&lt;p&gt;二元函数在$(x_0,y_0)$连续的定义与一元完全一致，即极限存在&lt;strong&gt;且等于函数值&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;$$
\lim_{(x,y)\to(x_0,y_0)} f(x,y) = f(x_0,y_0)
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我曾在极限篇将极限存在记为$L=V=R$. 那时是因为还只有左右两边。&lt;/p&gt;
&lt;p&gt;现在我们可以记为$\forall Q=V$, 意为所有方向上的极限都等于该点函数值。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;偏导数&lt;/h3&gt;
&lt;p&gt;直接对$x$求导数，把$y$当常数，这就是对$x$求偏导。&lt;/p&gt;
&lt;p&gt;在$(x_0,y_0)$处对$x$的偏导数定义为&lt;/p&gt;
&lt;p&gt;$$
f_x(x_0,y_0) = \lim_{\Delta x\to0} \frac{f(x_0+\Delta x, y_0)-f(x_0,y_0)}{\Delta x}
$$&lt;/p&gt;
&lt;p&gt;也是能明显地看出来为什么偏导就是把$y$当常数。它和一元导数不能说是完全一致，也只能说是同根同源了。所以偏导本质是一维问题，一元求导的一切技巧（定义式、公式、&lt;strong&gt;分段点用定义&lt;/strong&gt;）原样搬过来即可。&lt;/p&gt;
&lt;p&gt;曲面$z=f(x,y)$被平面$y=y_0$截出交线，$f_x(x_0,y_0)$就是这条交线在$(x_0,y_0)$处关于$x$轴方向的变化率；$f_y$同理对应平面$x=x_0$的截线。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;Pasted%20image%2020260808022859.png&quot; alt=&quot;切线斜率即为偏导&quot; /&gt;&lt;/p&gt;
&lt;p&gt;偏导的概念不会考的像一元微分那么精细:spoiler[连续可导链体操吓哭了]，但也要明确一些二维上的新东西:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题一&lt;/strong&gt;: 导数存在$\implies$连续，偏导数存在$\implies?$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一元函数中: $f&apos;(x)$在$x_0$处存在$\implies f(x)$在$x_0$处连续&lt;/li&gt;
&lt;li&gt;二元函数中: $f&apos;&lt;em&gt;{x}(x,y)$在$(x_0,y&lt;/em&gt;{0})$处存在$\implies g(x)=f(x,y_{0})$在$x_0$处连续
&lt;ul&gt;
&lt;li&gt;本质上是在$y=y_{0}$这条线上连续，因为偏导只保证一个方向&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不能推导出&lt;/strong&gt;$f(x,y)$连续。
&lt;ul&gt;
&lt;li&gt;二元函数的连续要求&lt;strong&gt;所有方向都连续&lt;/strong&gt;，偏导存在&lt;strong&gt;最多保证两个方向&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;问题二&lt;/strong&gt;: $f(x^{2})$可以换成$f(u),u=x^{2}$, $f&apos;_{x}(x,y)$这个记号如何换呢&lt;/p&gt;
&lt;p&gt;二元函数中，对一个参数的导数并非针对$x$这个记号，而是&lt;strong&gt;第一个位置的参数&lt;/strong&gt;这个概念。偏导有三种常见记号。分别是:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;偏导符号法
&lt;ul&gt;
&lt;li&gt;最麻烦，最常见。&lt;/li&gt;
&lt;li&gt;$\frac{\partial}{\partial x}f(x,y)=\frac{\partial}{\partial u}f(u,v)$&lt;/li&gt;
&lt;li&gt;$\frac{\partial^{2}}{\partial x\partial y}f(x,y)=\frac{\partial}{\partial x} (\frac{\partial}{\partial y}f(x,y))$, $\frac{\partial^{2}}{\partial x^{2}}f(x,y)$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;符号法
&lt;ul&gt;
&lt;li&gt;最方便，最易混。&lt;/li&gt;
&lt;li&gt;$f&apos;&lt;em&gt;{x}(x,y)=f&apos;&lt;/em&gt;{u}(u,v)$&lt;/li&gt;
&lt;li&gt;$f&apos;&apos;&lt;em&gt;{xy}(x,y)=\frac{\partial}{\partial y} (\frac{\partial}{\partial x}f(x,y))$, $f&apos;&apos;&lt;/em&gt;{xx}(x,y)$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;位置法
&lt;ul&gt;
&lt;li&gt;最精确，最少见。&lt;/li&gt;
&lt;li&gt;$f&apos;&lt;em&gt;{1}(x,y)=f&apos;&lt;/em&gt;{1}(u,v)$&lt;/li&gt;
&lt;li&gt;$f&apos;&apos;&lt;em&gt;{12}(x,y)=\frac{\partial}{\partial y} (\frac{\partial}{\partial x}f(x,y))$, $f&apos;&apos;&lt;/em&gt;{11}(x,y)$&lt;/li&gt;
&lt;li&gt;它可以用于这种场景而不混淆: $f&apos;&apos;_{12}(\sin x-y,x+y^{2})$.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;对于后两种，也有写作$f&apos;&lt;em&gt;{xy}(x,y)$的 (只有一个$&apos;$), 并不会造成歧义，甚至不写撇($f&lt;/em&gt;{xy}$), 也不会造成歧义。&lt;/p&gt;
&lt;p&gt;另有: $z_{xy}&apos;&apos;$, $z_{xx}&apos;&apos;$, $z_{12}&apos;&apos;$ 等记法用于记号的表示。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题三&lt;/strong&gt;: $f&apos;&apos;&lt;em&gt;{12}(x,y)$和$f&apos;&apos;&lt;/em&gt;{21}(x,y)$有区别吗？&lt;/p&gt;
&lt;p&gt;简单来说，若$f&apos;&apos;&lt;em&gt;{12}(x,y)$与$f&apos;&apos;&lt;/em&gt;{21}(x,y)$在区域内连续$\implies$二者相等（即$f$的求导次序可交换）。实际计算题中这个条件通常默认满足，但概念题会特意挖一点简单小坑，题目只说&quot;偏导数存在&quot;时是不能交换求导次序的。&lt;/p&gt;
&lt;h3&gt;可微&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;定义:&lt;/strong&gt; 若增量$\Delta z = f(x_0+\Delta x, y_0+\Delta y)-f(x_0,y_0)$能写成&lt;/p&gt;
&lt;p&gt;$$
\Delta z = A\Delta x + B\Delta y + o(\rho), \quad \rho=\sqrt{\Delta x^2+\Delta y^2}
$$&lt;/p&gt;
&lt;p&gt;其中$A,B$是与$\Delta x,\Delta y$无关的常数，则称$f$在$(x_0,y_0)$&lt;strong&gt;可微&lt;/strong&gt;。可微是二元函数真正的“可导”。其性质包括:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;此时必有$A=f&apos;_x(x_0, y_0)$, $B=f&apos;_y(x_0, y_0)$&lt;/li&gt;
&lt;li&gt;此时全微分存在，记作$dz=f&apos;_x,dx+f&apos;_y,dy$&lt;/li&gt;
&lt;li&gt;这个函数在此处有一个唯一的切平面，几何方面不难想象，这个点处是“平”的。
&lt;ul&gt;
&lt;li&gt;这个平面方程就是$z - z_0 = A(x - x_0) + B(y - y_0)$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;:::note
为什么公式里会出现一个$\rho=\sqrt{ x^{2}+y^{2} }$呢？&lt;/p&gt;
&lt;p&gt;$\sqrt{ x^{2}+y^{2} }$是二元邻域的$dx$, 它的意义在于无论在二维平面上从什么曲线逼近$(0,0)$, 都有$\begin{cases}x\to 0\y\to 0\end{cases}\implies \rho\to 0$. “逼近”是指距离减小，$\rho$&lt;strong&gt;就是距离本身&lt;/strong&gt;。
:::&lt;/p&gt;
&lt;p&gt;可微性的判定有两种方法。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;充分条件法&lt;/strong&gt;: 算出偏导，如果偏导连续则一定可微，偏导不连续时什么也断言不了。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;定义法&lt;/strong&gt;: 直接验证&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;$$
\lim_{\rho\to0} \frac{\Delta z - f_x(x_0,y_0)\Delta x - f_y(x_0,y_0)\Delta y}{\rho} = 0
$$&lt;/p&gt;
&lt;p&gt;真题里“判断$f$在原点是否可微”的选择题全是为此设计的，先按定义算两个偏导，如果有不连续的再代进这个极限，再仔细观察分子有没有脏东西如$\sqrt{\Delta x^2+\Delta y^2}$这种项，可能它就不为零了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;graph TD
    PC[&quot;偏导连续&quot;] --&amp;gt; D[&quot;可微&quot;]
    I[&quot;定义式&quot;] --&amp;gt; D[&quot;可微&quot;]
    D --&amp;gt; C[&quot;连续&quot;]
    D --&amp;gt; P[&quot;偏导存在&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意$\rho$可能参与计算，要么按照正常的$\sqrt{ x^{2}+y^{2} }$计算，要么使用极坐标转换$\begin{cases}x=\rho \cos \theta\y=\rho \sin \theta\end{cases}$. 比方来说，$z(x,y)$处处满足增量方程$\Delta z=A\Delta x+B\Delta y+\Delta x\Delta y$, 则:&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
\Delta z&amp;amp;=A\Delta x+B\Delta y+\Delta x\Delta y \
\Delta z-A\Delta x-B\Delta y&amp;amp;=\Delta x\Delta y \
\lim_{ \rho \to 0 } \frac{\Delta z-A\Delta x-B\Delta y}{\rho}&amp;amp;=\lim_{ \rho \to 0 } \frac{\Delta x\Delta y}{\rho} \
&amp;amp;=\lim_{ \rho \to 0 }\frac{\rho^{2}\cos \theta\sin\theta}{\rho} \
&amp;amp;=\lim_{ \rho \to 0 }\rho\cos \theta\sin\theta \
&amp;amp;=0
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;则$z$处处可微。&lt;/p&gt;
&lt;p&gt;:::tip
考定义的时候很多题目有条件$(x_{0},y_{0})=(0,0)$, 少数有保持变量状态的，但基本没有$(x_{0},y_{0})=(1,2)$这种的。&lt;/p&gt;
&lt;p&gt;$(0,0)$这个点对于可微性本身来说虽然不特殊，但各种条件带入后的各式确是真题非常常见的式子。&lt;/p&gt;
&lt;p&gt;举例来说，可微性的原式在$(0,0)$会变成:
$$
f(x, y)-f(0,0) = Ax + By + o(\rho)
$$
上式省略了$\Delta$, 因为没有纯$x$之后不再需要区分了，而且真题确实也经常这么干，非常混淆视听。&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;graph TD
    A[&quot;判断f(0,0)是否可微&amp;lt;br/&amp;gt;按定义算f&apos;x,f&apos;y(0,0)&quot;]
    A --&amp;gt; B{&quot;偏导&amp;lt;br/&amp;gt;连续&quot;}
    B --&amp;gt;|&quot;是&quot;| OK[&quot;可微&quot;]
    B --&amp;gt;|&quot;否/不确定&quot;| D[&quot;代入上述判别式&quot;]
    D --&amp;gt;|&quot;极限为0&quot;| OK
    D --&amp;gt;|&quot;非0/不存在&quot;| NO[&quot;不可微&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;07302:7/&amp;lt;u&amp;gt;90&amp;lt;/u&amp;gt;/★★★☆☆&lt;/h3&gt;
&lt;p&gt;二元函数$f(x, y)$在点$(0,0)$处可微的一个充分条件是（  ）
A.$\lim\limits_{(x,y)\to(0,0)} \left[ f(x, y) - f(0,0) \right] = 0$
B.$\lim\limits_{x\to0} \frac{f(x,0) - f(0,0)}{x} = 0$且$\lim\limits_{y\to0} \frac{f(0,y) - f(0,0)}{y} = 0$
C.$\lim\limits_{(x,y)\to(0,0)} \frac{f(x, y) - f(0,0)}{\sqrt{x^2 + y^2}} = 0$
D.$\lim\limits_{x\to0} \left[ f&apos;_x(x,0) - f&apos;&lt;em&gt;x(0,0) \right] = 0$且$\lim\limits&lt;/em&gt;{y\to0} \left[ f&apos;_y(0,y) - f&apos;_y(0,0) \right] = 0$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我说这种小题考可微的各种条件考的最勤了。&lt;/p&gt;
&lt;p&gt;像这种题，考的命题的类型其实就那么几个，无非是&lt;strong&gt;原函数、X偏导、Y偏导&lt;/strong&gt;在&lt;strong&gt;邻域上、在去心邻域上、在线邻域上、在点上&lt;/strong&gt;的&lt;strong&gt;存在性、连续性&lt;/strong&gt;。一元微分学上我们可以掰扯清楚谁能推出谁，二元微分学就大可不必了，但我们也还是得记住哪些条件能推出&lt;strong&gt;可微&lt;/strong&gt;。可微是出题的绝对中心。&lt;/p&gt;
&lt;p&gt;注意，以上的排列组合中并没有与可微的充要条件，但有不少充分条件。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;A. 函数&lt;/strong&gt;-&lt;strong&gt;在点上&lt;/strong&gt;-&lt;strong&gt;连续&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;原式变形为$\lim\limits_{(x,y)\to(0,0)}f(x,y)=f(0,0)$. 只是一个简单的连续，与可微还差得远。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;B. 偏导数&lt;/strong&gt;-&lt;strong&gt;在点上&lt;/strong&gt;-&lt;strong&gt;存在&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;原式变形为$f&apos;_x(0,0)=f&apos;_y(0,0)=0$. 一个很知名的可微充分条件是偏导连续。这里并不连续。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C.&lt;/strong&gt; 这个条件不能用上述枚举表示，因为这个极限表达式内部也是关于$\rho$的。&lt;/p&gt;
&lt;p&gt;设$A=0,B=0$, 对$f(x, y)-f(0,0) = Ax + By + o(\rho)$求极限:&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
f(x, y)-f(0,0) &amp;amp;= o(\rho) \
\lim_{ \rho \to 0 } \frac{f(x, y)-f(0,0)}{\rho} &amp;amp;= \lim_{ \rho \to 0 } \frac{o(\rho)}{\rho}=0 \
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;导出原式满足可微条件，而且还给了额外的$A=0,B=0$, 是充分条件。&lt;/p&gt;
&lt;p&gt;再仔细看看这个极限，有没有觉得很熟悉
$$
\lim\limits_{\rho \to 0} \frac{f - f|&lt;em&gt;{\rho=0}}{\rho} = 0\qquad
\textcolor{gray}{ \lim\limits&lt;/em&gt;{x \to 0} \frac{f(x) - f(0)}{x} = 0 }
$$
我看这可微判定式和导数定义也有异曲同工之妙啊&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;D. X偏导数&lt;/strong&gt;-&lt;strong&gt;在y=0上&lt;/strong&gt;-&lt;strong&gt;连续&lt;/strong&gt; &amp;amp; &lt;strong&gt;Y偏导数&lt;/strong&gt;-&lt;strong&gt;在x=0上&lt;/strong&gt;-&lt;strong&gt;连续&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;$\lim\limits_{x\to0} f&apos;_x(x,0)  = f&apos;&lt;em&gt;x(0,0)$, $\lim\limits&lt;/em&gt;{y\to0} f&apos;_y(0,y)  = f&apos;_y(0,0)$&lt;/p&gt;
&lt;p&gt;这里的条件其实是很窄的。两个偏导数都各只在一条轴上连续，根本不是真正的”偏导数连续“. 我们做题的时候可以“&lt;strong&gt;偏导数&lt;/strong&gt;-&lt;strong&gt;在邻域内&lt;/strong&gt;-&lt;strong&gt;连续&lt;/strong&gt;”为充分标准即可。&lt;/p&gt;
&lt;p&gt;反例$f=\dfrac{x^2y}{x^2+y^2}$(原点补$0$), $f&apos;_x(x,0)\equiv0$, $f&apos;_y(0,y)\equiv0$,
$$
\frac{\Delta z}{\rho}=\frac{x^2y}{(x^2+y^2)^{3/2}}=\cos^{2}\theta\sin\theta
$$
随$\theta$变化而不趋于$0$, 不可微。&lt;/p&gt;
&lt;p&gt;:::note[“偏导数连续”真正的最弱范围是什么？]&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;其中一个偏导数在点$(x_0, y_0)$的某邻域内存在且在该点连续，另一个偏导数在点$(x_0, y_0)$处存在。&lt;/strong&gt; 也就是:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;偏导1&lt;/strong&gt;-&lt;strong&gt;在邻域&lt;/strong&gt;-&lt;strong&gt;存在&lt;/strong&gt; &amp;amp;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;偏导1&lt;/strong&gt;-&lt;strong&gt;在点处&lt;/strong&gt;-&lt;strong&gt;连续&lt;/strong&gt; &amp;amp;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;偏导2&lt;/strong&gt;-&lt;strong&gt;在点处&lt;/strong&gt;-&lt;strong&gt;存在&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当然，即使已经最弱了，这依然不是充要条件。从“偏导连续”中榨出来的条件总会多一点水分。至于充分在哪，提示: $(x^2 + y^2) \sin \frac{1}{\sqrt{x^2 + y^2}}$
:::&lt;/p&gt;
&lt;h3&gt;27660:422/&amp;lt;u&amp;gt;90&amp;lt;/u&amp;gt;/★★★☆☆&lt;/h3&gt;
&lt;p&gt;设$f(x,y) = \begin{cases} \dfrac{x^4 - y^4}{x^2 + y^2}, &amp;amp; x^2 + y^2 \neq 0, \ 0, &amp;amp; x^2 + y^2 = 0, \end{cases}$, 则$f(x,y)$在点$(0,0)$处&lt;/p&gt;
&lt;p&gt;(A) 连续，但偏导数$f&apos;_x(0,0)$和$f&apos;_y(0,0)$不存在.
(B) 连续且偏导数$f&apos;_x(0,0)$和$f&apos;_y(0,0)$都存在，但不可微.
(C) 可微但$f&apos;_x$和$f&apos;_y$不连续.
(D) 可微且$f&apos;_x$和$f&apos;_y$连续.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;四个选项正好是&quot;连续/偏导存在/可微/偏导连续&quot;的四种组合，逐个验。核心武器是一条估计: ——分子是分母的高次无穷小，连续和可微都直接由它推出。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;先验连续: $|f(x,y)|\le\rho^2\to0=f(0,0)$, 连续。&lt;/p&gt;
&lt;p&gt;偏导: 沿$x$轴$f(x,0)=x^2$, 故$f&apos;&lt;em&gt;x(0,0)=\lim&lt;/em&gt;{x\to0}\dfrac{x^2-0}{x}=0$, 同理$f&apos;_y(0,0)=0$, 都存在。&lt;/p&gt;
&lt;p&gt;可微: $A=B=0$, 代入定义式:
$$
\begin{align*}
\frac{\Delta z-0}{\rho} &amp;amp;=\frac{\Delta x^4-\Delta y^4}{\rho^3} \
&amp;amp;=\frac{\rho^4(\cos^{4}\theta-\sin^{4}\theta)}{\rho^3} \
&amp;amp;=\rho(\cos^{4}\theta-\sin^{4}\theta)\to0
\end{align*}
$$
可微。&lt;/p&gt;
&lt;p&gt;最后验$f&apos;_x$连续（$f&apos;_y$同理）: $(x,y)\neq(0,0)$时
$$
f&apos;_x=\frac{4x^3(x^2+y^2)-2x(x^4-y^4)}{(x^2+y^2)^2}
$$
换极坐标$x=\rho\cos\theta,\ y=\rho\sin\theta$化简得$f&apos;_x=2\rho\cos\theta$, 被$2\rho$一致控制地趋于0，故$f&apos;_x$在原点连续。选(D)。&lt;/p&gt;
&lt;h3&gt;27660:431/&amp;lt;u&amp;gt;135&amp;lt;/u&amp;gt;/★★★★☆&lt;/h3&gt;
&lt;p&gt;设$f(u, v)$有连续偏导数且$f(0, 0) = 0$, 则下列等式中成立的是&lt;/p&gt;
&lt;p&gt;(A)$f(x, y) = x \int_{0}^{1} \frac{\partial f(tx, y)}{\partial u} \mathrm{d}t.$
(B)$f(x, y) = y \int_{0}^{1} \frac{\partial f(x, ty)}{\partial v} \mathrm{d}t.$
(C)$f(x, y) = x \int_{0}^{1} \frac{\partial f(tx, ty)}{\partial u} \mathrm{d}t + y \int_{0}^{1} \frac{\partial f(tx, ty)}{\partial v} \mathrm{d}t.$
(D)$f(x, y) = x \int_{0}^{1} \frac{\partial f(tx, y)}{\partial u} \mathrm{d}t + y \int_{0}^{1} \frac{\partial f(x, ty)}{\partial v} \mathrm{d}t.$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;令$F(t)=f(tx,ty)$, 则$F(0)=f(0,0)=0$, $F(1)=f(x,y)$, 由链式法则
$$
F&apos;(t)=x,f&apos;_u(tx,ty)+y,f&apos;_v(tx,ty)
$$
于是由微积分基本定理
$$
\begin{align*}
f(x,y)&amp;amp;=f(x,y)-f(0,0)=\int_0^1F&apos;(t),dt \
&amp;amp;=x\int_0^1 f&apos;_u(tx,ty),dt+y\int_0^1 f&apos;_v(tx,ty),dt
\end{align*}
$$
即(C)成立。&lt;/p&gt;
&lt;h2&gt;计算题&lt;/h2&gt;
&lt;h3&gt;转极坐标法&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;转极坐标是多元函数尤其常用的技巧。本节内容同样适用二重积分&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;$$
\begin{cases}
x=r\cos \theta \
y=r\sin \theta
\end{cases};,\quad\begin{cases}
r=\sqrt{ x^{2}+y^{2} } \
\theta=\operatorname{atan2}(y,x)
\end{cases}
$$&lt;/p&gt;
&lt;p&gt;$$
\operatorname{atan2}(y,x)=\begin{cases}
\arctan(y/x), &amp;amp; x &amp;gt; 0 \
\arctan(y/x) + \pi, &amp;amp; x &amp;lt; 0,\ y \ge 0 \
\arctan(y/x) - \pi, &amp;amp; x &amp;lt; 0,\ y &amp;lt; 0 \
\pi/2, &amp;amp; x = 0,\ y &amp;gt; 0 \
-\pi/2, &amp;amp; x = 0,\ y &amp;lt; 0 \
\end{cases}
$$&lt;/p&gt;
&lt;p&gt;如果原点行为被保证，极坐标其实和直角坐标在局部的表现差不多，更重要的是题式形式的变化。&lt;/p&gt;
&lt;p&gt;转极坐标本质上是把趋近$(0,0)$翻译成$r\to0$, 方向、路径、奇异性全被塞进$\theta$。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;什么时候该转&lt;/strong&gt;: 看到$\sqrt{x^2+y^2}$, $x^2+y^2$这类团块，且原式满足其中一个:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;并不在乎或者要求原点什么性质。&lt;/li&gt;
&lt;li&gt;保证了原点的性质。比如方程显然在原点为0.&lt;/li&gt;
&lt;li&gt;需要深度研究原点的性质以至于无法绕开极坐标。比如需要转可微形式。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;什么时候别转&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;方程和$r=\sqrt{ x^{2}+y^{2} }$占不起一点关系&lt;/li&gt;
&lt;li&gt;区域与圆、扇形完全不沾边&lt;/li&gt;
&lt;li&gt;转完凭空多出讨厌的$\frac1r$。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;全微分&lt;/h3&gt;
&lt;p&gt;由可微的定义直接得到公式&lt;/p&gt;
&lt;p&gt;$$
dz=f&apos;_x(x,y),dx+f&apos;_y(x,y),dy
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;求$df(x,y)$在$(0,1)$处的值&lt;/strong&gt;这类题就是先算偏导、再代点，机械得不能再机械。比如&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
z&amp;amp;=x^2y+e^x\sin y \
z&apos;_x&amp;amp;=2xy+e^x\sin y \
z&apos;_y&amp;amp;=x^2+e^x\cos y \[6pt]&lt;/p&gt;
&lt;p&gt;dz&amp;amp;=(2xy+e^x\sin y),dx+(x^2+e^x\cos y),dy \
dz|_{(0,1)}&amp;amp;=\sin 1,dx+\cos 1,dy
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;注意，这种题有时候会反过来给你全微分去让你积分求原式，那种有点技术含量，后面就讲。&lt;/p&gt;
&lt;p&gt;另一件事是&lt;strong&gt;一阶微分形式的不变性&lt;/strong&gt;: 无论$u,v$是自变量还是中间变量，全微分都长一个样&lt;/p&gt;
&lt;p&gt;$$
dz=f&apos;_u,du+f&apos;_v,dv
$$&lt;/p&gt;
&lt;p&gt;所以复合函数求全微分可以不背链式法则，先写出$dz=f&apos;_u,du+f&apos;_v,dv$, 再逐层代入$du=u&apos;_x,dx+u&apos;_y,dy$、$dv=v&apos;_x,dx+v&apos;_y,dy$, 展开整理。&lt;/p&gt;
&lt;p&gt;:::warning
形式不变性&lt;strong&gt;只对一阶微分成立&lt;/strong&gt;: 二阶微分$d^2z$没有这个性质（中间变量不是自变量时$d^2u\neq u&apos;&apos;&lt;em&gt;{xx},dx^2+u&apos;&apos;&lt;/em&gt;{yy},dy^2$），概念题偶尔在这里挖坑。
:::&lt;/p&gt;
&lt;h3&gt;复合函数求导/链式法则&lt;/h3&gt;
&lt;p&gt;设$z=f(u,v)$, $u=u(x,y)$, $v=v(x,y)$, 则&lt;/p&gt;
&lt;p&gt;$$
\frac{\partial z}{\partial x} = \frac{\partial f}{\partial u}\frac{\partial u}{\partial x} + \frac{\partial f}{\partial v}\frac{\partial v}{\partial x}
$$&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;graph TD
    Z[&quot;z = f(u,v)&quot;] --&amp;gt;|&quot;∂f/∂1&quot;| U[&quot;u = u(x,y)&quot;]
    Z --&amp;gt;|&quot;∂f/∂2&quot;| V[&quot;v = v(x,y)&quot;]
    U --&amp;gt;|&quot;∂u/∂x&quot;| X1[&quot;x&quot;]
    U --&amp;gt;|&quot;∂u/∂y&quot;| Y1[&quot;y&quot;]
    V --&amp;gt;|&quot;∂v/∂x&quot;| X2[&quot;x&quot;]
    V --&amp;gt;|&quot;∂v/∂y&quot;| Y2[&quot;y&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;从$z$到$x$有两条路径: $z\to u\to x$（$\frac{\partial f}{\partial u}\frac{\partial u}{\partial x}$）和$z\to v\to x$（$\frac{\partial f}{\partial v}\frac{\partial v}{\partial x}$）.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;中间变量只有一元（$u=u(t)$、$v=v(t)$）时退化为全导数&lt;/p&gt;
&lt;p&gt;$$
\frac{dz}{dt} = f_u\cdot u&apos;(t) + f_v\cdot v&apos;(t)
$$&lt;/p&gt;
&lt;h3&gt;27330:153/&amp;lt;u&amp;gt;90&amp;lt;/u&amp;gt;/★★★☆☆&lt;/h3&gt;
&lt;p&gt;(1). 设$z = f(2x - y) + g(x, xy)$, 其中$f(t)$二阶可导，$g(u, v)$具有二阶连续偏导数，求$\frac{\partial^2 z}{\partial x \partial y}$。&lt;/p&gt;
&lt;p&gt;(2). 设$u = f(x, y, z)$, 其中$z = \int_{0}^{xy} e^{t^2} \mathrm{d}t$, $f$有二阶连续偏导数，求$\frac{\partial u}{\partial x}, \frac{\partial^2 u}{\partial x \partial y}$。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
z &amp;amp;= f(2x - y) + g(x, xy) \[9pt]&lt;/p&gt;
&lt;p&gt;\frac{\partial z}{\partial x}
&amp;amp;= \textcolor{aqua}{f&apos;(2x-y)\cdot\frac{\partial}{\partial x}(2x-y)}&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;\textcolor{yellow}{g&apos;_1 \cdot \frac{\partial}{\partial x}x}&lt;/li&gt;
&lt;li&gt;\textcolor{lime}{ g&apos;_2 \cdot \frac{\partial}{\partial x}xy } \
&amp;amp;= \textcolor{aqua}{f&apos;(2x - y)\cdot 2}&lt;/li&gt;
&lt;li&gt;\textcolor{yellow}{g&apos;_1 \cdot 1}&lt;/li&gt;
&lt;li&gt;\textcolor{lime}{ g&apos;_2 \cdot y } \
&amp;amp;= \textcolor{aqua}{2f&apos;(2x-y)}&lt;/li&gt;
&lt;li&gt;\textcolor{yellow}{g&apos;_1(x,xy)}&lt;/li&gt;
&lt;li&gt;\textcolor{lime}{ y,g&apos;_2(x,xy) }. \[9pt]&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;\frac{\partial^2 z}{\partial x \partial y}
&amp;amp;= \frac{\partial}{\partial y}\left[
\textcolor{aqua}{2f&apos;(t)}&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;\textcolor{yellow}{g&apos;_1}&lt;/li&gt;
&lt;li&gt;\textcolor{lime}{ y,g&apos;_2 }
\right] \
&amp;amp;= \textcolor{aqua}{2\frac{\partial}{\partial y}f&apos;(t)}&lt;/li&gt;
&lt;li&gt;\textcolor{yellow}{\frac{\partial}{\partial y}g&apos;_1}&lt;/li&gt;
&lt;li&gt;\textcolor{lime}{ \frac{\partial}{\partial y}(y,g&apos;_2) }. \[6pt]&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;amp;\begin{cases}&lt;/p&gt;
&lt;p&gt;\textcolor{aqua}{ 2\frac{\partial}{\partial y}f&apos;(t) }
&amp;amp;\textcolor{aqua}{= 2 f&apos;&apos;(t)\cdot \frac{\partial t}{\partial y}}
\textcolor{aqua}{= 2 f&apos;&apos;(2x-y)\cdot(-1)}
\textcolor{aqua}{= -2 f&apos;&apos;(2x-y)}. \
\textcolor{yellow}{ \frac{\partial}{\partial y}g&apos;&lt;em&gt;1 }
&amp;amp;\textcolor{yellow}{= g&apos;&apos;&lt;/em&gt;{11}\cdot 0 + g&apos;&apos;&lt;em&gt;{12}\cdot x}
\textcolor{yellow}{= x,g&apos;&apos;&lt;/em&gt;{12}(x,xy)}. \
\textcolor{lime}{ \frac{\partial}{\partial y}(y,g&apos;_2) }
&amp;amp;\textcolor{lime}{= g&apos;_2 + y,\frac{\partial }{\partial y}g&apos;&lt;em&gt;2} \
&amp;amp;\textcolor{lime}{= g&apos;&lt;em&gt;2 + y\left( g&apos;&apos;&lt;/em&gt;{21}\cdot 0 + g&apos;&apos;&lt;/em&gt;{22}\cdot x \right)}
\textcolor{lime}{= g&apos;&lt;em&gt;2(x,xy) + xy,g&apos;&apos;&lt;/em&gt;{22}(x,xy)}. \ \&lt;/p&gt;
&lt;p&gt;\end{cases} \&lt;/p&gt;
&lt;p&gt;\frac{\partial^2 z}{\partial x \partial y}
&amp;amp;= \textcolor{aqua}{ -2 f&apos;&apos;(2x-y) }&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;\textcolor{yellow}{ x,g&apos;&apos;_{12}(x,xy)}&lt;/li&gt;
&lt;li&gt;\textcolor{lime}{ g&apos;&lt;em&gt;2(x,xy) + xy,g&apos;&apos;&lt;/em&gt;{22}(x,xy)  }
\end{align*}
$$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;(2)&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
\quad u &amp;amp;= f(x, y, z),\quad z = \int_{0}^{xy} e^{t^2} dt \
z_x &amp;amp;= \frac{\partial z}{\partial x} = e^{(xy)^2}\cdot y = y e^{x^2 y^2} \
z_y &amp;amp;= \frac{\partial z}{\partial y} = e^{(xy)^2}\cdot x = x e^{x^2 y^2} \[9pt]
\frac{\partial u}{\partial x}
&amp;amp;= \textcolor{aqua}{ f_x(x,y,z)\cdot \frac{\partial x}{\partial x} }&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;\textcolor{yellow}{ f_y(x,y,z)\cdot \frac{\partial y}{\partial x} }&lt;/li&gt;
&lt;li&gt;\textcolor{lime}{ f_z(x,y,z)\cdot \frac{\partial z}{\partial x} } \
&amp;amp;= \textcolor{aqua}{ f_x(x,y,z)\cdot 1 }&lt;/li&gt;
&lt;li&gt;\textcolor{yellow}{ f_y(x,y,z)\cdot 0 }&lt;/li&gt;
&lt;li&gt;\textcolor{lime}{ f_z(x,y,z)\cdot z_x } \
&amp;amp;= \textcolor{aqua}{ f_1(x,y,z) }&lt;/li&gt;
&lt;li&gt;\textcolor{lime}{ y e^{x^2 y^2} f_3(x,y,z) } \[9pt]&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;\frac{\partial^2 u}{\partial x \partial y}
&amp;amp;= \frac{\partial}{\partial y}\left[
\textcolor{aqua}{ f_1(x,y,z) }&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;\textcolor{lime}{ y e^{x^2 y^2} f_3(x,y,z) }
\right] \
&amp;amp;= \textcolor{aqua}{ \frac{\partial}{\partial y} f_1(x,y,z) }&lt;/li&gt;
&lt;li&gt;\textcolor{lime}{ \frac{\partial}{\partial y}\bigl( y e^{x^2 y^2} f_3(x,y,z) \bigr) } \[9pt]
&amp;amp;\begin{cases}&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;amp;\textcolor{aqua}{\frac{\partial}{\partial y} f_1(x,y,z)} \
&amp;amp;\textcolor{aqua}{= f_{11}\cdot 0 + f_{12}\cdot 1 + f_{13}\cdot z_y} \
&amp;amp;\textcolor{aqua}{= f_{12}(x,y,z) + x e^{x^2 y^2} f_{13}(x,y,z)} \ \&lt;/p&gt;
&lt;p&gt;&amp;amp;\textcolor{lime}{
\frac{\partial}{\partial y}\bigl( y e^{x^2 y^2} f_3(x,y,z) \bigr)
} \
&amp;amp;\textcolor{lime}{
= \frac{\partial}{\partial y}(y e^{x^2 y^2})\cdot f_3&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;y e^{x^2 y^2} \cdot \frac{\partial}{\partial y} f_3
} \
&amp;amp;\textcolor{lime}{
= e^{x^2 y^2}(1 + 2x^2 y^2) f_3&lt;/li&gt;
&lt;li&gt;y e^{x^2 y^2} \bigl( f_{31}\cdot 0 + f_{32}\cdot 1 + f_{33}\cdot z_y \bigr)
} \
&amp;amp;\textcolor{lime}{
= e^{x^2 y^2}(1 + 2x^2 y^2) f_3&lt;/li&gt;
&lt;li&gt;y e^{x^2 y^2} \bigl( f_{32}(x,y,z) + x e^{x^2 y^2} f_{33}(x,y,z) \bigr)
} \
&amp;amp;\textcolor{lime}{
= e^{x^2 y^2}(1 + 2x^2 y^2) f_3&lt;/li&gt;
&lt;li&gt;y e^{x^2 y^2} f_{32}&lt;/li&gt;
&lt;li&gt;xy e^{2x^2 y^2} f_{33}
}
\end{cases} \[9pt]&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;\frac{\partial^2 u}{\partial x \partial y}
&amp;amp;= \textcolor{aqua}{ f_{12}(x,y,z) + xe^{x^2 y^2} f_{13}(x,y,z)} \
&amp;amp;+\textcolor{lime}{ e^{x^2 y^2}(1 + 2x^2 y^2) f_3(x,y,z)} \
&amp;amp;+\textcolor{lime}{ y e^{x^2 y^2} f_{32}(x,y,z) } \
&amp;amp;+\textcolor{lime}{ xy e^{2x^2 y^2} f_{33}(x,y,z) }
\end{align*}
$$&lt;/p&gt;
&lt;h3&gt;隐函数求导&lt;/h3&gt;
&lt;p&gt;方程$F(x,y)=0$在满足$F_y(x_0,y_0)\neq0$的点附近确定隐函数$y=y(x)$（隐函数存在定理），此时&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
F(x,y)&amp;amp;=0 \
F_{x};dx+F_{y};dy&amp;amp;=0 \
F_{y};dy&amp;amp;=-F_{x};dx \
\frac{dy}{dx} &amp;amp;= -\frac{F_x}{F_y}
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;方程$F(x,y,z)=0$在$F_z(x_0,y_0,z_0)\neq0$处确定$z=z(x,y)$, 则&lt;/p&gt;
&lt;p&gt;$$
\frac{\partial z}{\partial x} = -\frac{F_x}{F_z}, \quad \frac{\partial z}{\partial y} = -\frac{F_y}{F_z}
$$&lt;/p&gt;
&lt;p&gt;以上小公式结合更主要的链式法则和一元微分学的隐函数求导就是完整的多元隐函数求导了。东西不多。&lt;/p&gt;
&lt;h3&gt;27330:154/&amp;lt;u&amp;gt;90&amp;lt;/u&amp;gt;/★★★☆☆&lt;/h3&gt;
&lt;p&gt;设二元函数$z = z(x, y)$是由方程$x e^{xy} + y z^2 = y z \sin x + z$所确定，求二阶偏导数$\frac{\partial^2 z}{\partial x^2} \Big|_{(x,y)=(0,0)}$.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
&amp;amp; F(x,y,z)=x e^{xy}+y z^2 - y z \sin x - z=0 \[6pt]
&amp;amp; F_x = e^{xy}+xy e^{xy} - y z \cos x,\quad F_z = 2yz - y\sin x -1 \[6pt]
&amp;amp; \left. F_x \right|&lt;em&gt;{(0,0,0)}=1,\quad \left. F_z \right|&lt;/em&gt;{(0,0,0)}=-1
;\Longrightarrow; \left. z_x \right|&lt;em&gt;{(0,0)}= -\frac{F_x}{F_z}=1 \[12pt]
&amp;amp; \textcolor{magenta}{ e^{xy}+xy e^{xy}+2y z z_x = y z_x \sin x + y z \cos x + z_x } \tag{1} \[12pt]
&amp;amp; \frac{\partial}{\partial x}\left( \textcolor{magenta}{ e^{xy}+xy e^{xy}+2y z z_x } \right)
= \frac{\partial}{\partial x}\left( \textcolor{magenta}{ y z_x \sin x + y z \cos x + z_x } \right) \[6pt]
&amp;amp; \textcolor{aqua}{ y e^{xy} + \left(y e^{xy}+xy^2 e^{xy}\right) + 2y\left(z_x^2 + z z&lt;/em&gt;{xx}\right) }
= \textcolor{lime}{ y\left(z_{xx}\sin x + z_x\cos x\right) + y\left(z_x\cos x - z\sin x\right) + z_{xx} } \[12pt]
&amp;amp; \text{代入 }x=0,; y=0,; z=0,; z_x=1: \[6pt]
&amp;amp; \textcolor{aqua}{ 0+0+0 } = \textcolor{lime}{ 0+0+z_{xx} } \[6pt]
&amp;amp; \therefore ; 0 = z_{xx} \quad\Longrightarrow\quad \boxed{ \frac{\partial^2 z}{\partial x^2}\Big|_{(0,0)} = 0 }
\end{align*}
$$&lt;/p&gt;
&lt;h3&gt;偏微分方程&lt;/h3&gt;
&lt;p&gt;&lt;s&gt;不是让你真的去解PDE&lt;/s&gt; 这类题主要是如何将PDE化为ODE来解。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;已知偏导求原函数&lt;/strong&gt;: 已知$f&apos;_x=P(x,y)$、$f&apos;_y=Q(x,y)$（等价于已知全微分$df=P,dx+Q,dy$）&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这是直戳了当的一类题。逆运算，我们直接把$y$当常数对$x$积分:&lt;/p&gt;
&lt;p&gt;$$
f(x,y)=\int P(x,y),dx+\varphi(y)
$$&lt;/p&gt;
&lt;p&gt;再对$y$求偏导、与$Q(x,y)$对照定出$\varphi(y)$。&lt;/p&gt;
&lt;p&gt;注意能反推的前提是$P&apos;_y=Q&apos;_x$, 即混合偏导必须相等（混合偏导可交换），&lt;strong&gt;否则函数不存在&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;结构降维成微分方程&lt;/strong&gt;: 题目给一个含偏导的方程求原函数时，先瞪眼找结构。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例如径向对称$u=u(\sqrt{x^2+y^2})$, 由$\frac{\partial^2 u}{\partial x^2}=u&apos;&apos;(r)\frac{x^2}{r^2}+u&apos;(r)\frac{y^2}{r^3}$可以推出&lt;/p&gt;
&lt;p&gt;$$
\frac{\partial^2 u}{\partial x^2}+\frac{\partial^2 u}{\partial y^2}=u&apos;&apos;(r)+\frac1r u&apos;(r)
$$&lt;/p&gt;
&lt;p&gt;化为二阶常微分方程。我知道这是一个特例，theta项恰好被消掉。但考试嘛，考的就是注意力。方法论是看到$\sqrt{ x^{2}+y^{2} }$就条件反射地开极坐标。关于方法论，这是一个很好的消解“注意到”的方式，之后可能会专门更新一篇注意力篇。&lt;/p&gt;
&lt;p&gt;另外极坐标下，$r&amp;gt;0$时，还有几个好看的推论:&lt;/p&gt;
&lt;p&gt;$$
\begin{cases}
\dfrac{\partial r}{\partial x}=\dfrac{x}{r},\quad
\dfrac{\partial r}{\partial y}=\dfrac{y}{r} \
\dfrac{\partial^{2}r}{\partial x^{2}}=\dfrac{y^{2}}{r^{3}},\quad
\dfrac{\partial^{2}r}{\partial y^{2}}=\dfrac{x^{2}}{r^{3}} \
\dfrac{\partial^{2}r}{\partial x\partial y}=-\dfrac{xy}{r^{3}}
\end{cases}
$$&lt;/p&gt;
&lt;h3&gt;27330:156/&amp;lt;u&amp;gt;90&amp;lt;/u&amp;gt;/★★★☆☆&lt;/h3&gt;
&lt;p&gt;$\dfrac{\partial^2 z}{\partial x \partial y} = 0$, 且$z(x, y) = \begin{cases} \sin y, &amp;amp; x = 0, \ \sin x, &amp;amp; y = 0, \end{cases}$ 求$z(x, y)$。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;$z_{xy}=0$意味着$z_x$与$y$无关，于是$z$能拆成两个一元函数之和$F(x)+G(y)$, 两条边界线正好各自定出一个。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;由$z_{xy}=0$, 即
$$
\frac{\partial}{\partial y}\left(\frac{\partial z}{\partial x}\right)=0
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;先做一个简单而重要的积分步骤推演。&lt;/p&gt;
&lt;p&gt;一个函数对$y$的偏导恒为$0$, 说明它与$y$无关，但仍可能有$x$. 这点在多元函数积分上能直接体现出来，规则和一元积分是一样的，&lt;strong&gt;在对一个变量操作时将其他变量看做常数。&lt;/strong&gt; 对$y$积分时，$x$便也是常数，出现在常数$C$的位置上。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;$$
\begin{align*}
\frac{\partial}{\partial y}\left( \textcolor{aqua}{ \frac{\partial}{\partial x}z(x,y) } \right)&amp;amp;=0 \
\textcolor{gray}{ \int\frac{\partial}{\partial y} }\left( \textcolor{aqua}{ \frac{\partial}{\partial x}z(x,y) } \right)\textcolor{gray}{ dy }&amp;amp;=\int 0,dy \
\frac{\partial}{\partial x}\textcolor{yellow}{ z(x,y) }&amp;amp;=f(x) \
\textcolor{gray}{ \int\frac{\partial}{\partial x} }\textcolor{yellow}{ z(x,y) }\textcolor{gray}{ dx }&amp;amp;=\int f(x),dx \
z(x,y)&amp;amp;=F(x)+G(y)
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;代入两条边界线:&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
z(0,0)&amp;amp;=0 \
z(x,0)&amp;amp;=F(0)+G(y)=\sin x \
z(0,y)&amp;amp;=F(x)+G(0)=\sin y \[6pt]
(F(x)+G(y))+(F(0)+G(0))&amp;amp;=\sin x+\sin y \
z(x,y)+z(0,0)&amp;amp;=\sin x+\sin y \
z(x,y)&amp;amp;=\sin x+\sin y
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;得解。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这是我能找到最标准的多元微分方程的积分题。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;27330:160/&amp;lt;u&amp;gt;90&amp;lt;/u&amp;gt;/★★★★☆&lt;/h3&gt;
&lt;p&gt;设$u = u(\sqrt{x^2 + y^2})$具有连续二阶偏导数，且满足&lt;/p&gt;
&lt;p&gt;$$
\frac{\partial^2 u}{\partial x^2} + \frac{\partial^2 u}{\partial y^2} - \frac{1}{x} \frac{\partial u}{\partial x} + 4u = 4(x^2 + y^2)
$$&lt;/p&gt;
&lt;p&gt;试求函数$u$的表达式。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;看到$u=u(\sqrt{x^2+y^2})$, 无理由直接上极坐标，一切$u$改写为$r=\sqrt{x^2+y^2}$有关。把$\frac{\partial}{\partial x}$写成$\frac{x}{r}\frac{d}{dr}$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;令$r=\sqrt{x^2+y^2}$, 则
$$
\frac{\partial u}{\partial x}=u&apos;(r)\frac{x}{r},\qquad
\frac{\partial^2 u}{\partial x^2}=u&apos;&apos;(r)\frac{x^2}{r^2}+u&apos;(r)\frac{y^2}{r^3}
$$
对$y$同理，相加得
$$
\frac{\partial^2 u}{\partial x^2}+\frac{\partial^2 u}{\partial y^2}=u&apos;&apos;(r)+\frac{u&apos;(r)}{r}
$$
又$\dfrac1x\dfrac{\partial u}{\partial x}=\dfrac{u&apos;(r)}{r}$, 代入原方程:
$$
u&apos;&apos;(r)+4u(r)=4r^2
$$
解一元ODE，此处简略过，齐次通解为$C_1\cos 2r+C_2\sin 2r$, 设特解$u_p=ar^2+b$, 代入得$a=1$, $b=-\frac12$。故
$$
u(x,y)=C_1\cos\left(2\sqrt{x^2+y^2}\right)+C_2\sin\left(2\sqrt{x^2+y^2}\right)+x^2+y^2-\frac12
$$&lt;/p&gt;
&lt;h2&gt;极值与最值&lt;/h2&gt;
&lt;p&gt;在一维上求极值最值要考虑&lt;strong&gt;中间导数=0的部分&lt;/strong&gt;和&lt;strong&gt;左右端点值&lt;/strong&gt;。二维上同理，要考虑形状S面积内的&lt;strong&gt;xy偏导均=0的部分&lt;/strong&gt;和S&lt;strong&gt;整个周长上的值&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;鉴于这一节基本上围绕可微的方程出题，我们接下来假设$f(x,y)$在$\mathbb{R}^{2}$上可微。&lt;/p&gt;
&lt;h3&gt;无条件极值&lt;/h3&gt;
&lt;p&gt;找极值点既要查驻点，也要查偏导不存在的点。不存在的特殊点现场发挥分析不难，此处主要说可微的那些点&lt;/p&gt;
&lt;p&gt;1. $f$在$(x_0,y_0)$取极值的&lt;strong&gt;必要&lt;/strong&gt;条件:&lt;/p&gt;
&lt;p&gt;$$
f_x(x_0,y_0)=f_y(x_0,y_0)=0
$$&lt;/p&gt;
&lt;p&gt;这样的点叫驻点。没错，与一元函数中的$f&apos;(x)=0$的驻点是等位的。&lt;/p&gt;
&lt;p&gt;注意这是必要不充分条件，&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;驻点可能是鞍点，如$f(x,y)=x^2-y^2$在原点&lt;/li&gt;
&lt;li&gt;偏导不存在的点也可能取极值，如$f(x,y)=\sqrt{x^2+y^2}$在$(0,0)$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2. $f$在$(x_0,y_0)$取极值的&lt;strong&gt;充分&lt;/strong&gt;条件: 设有&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
A=&amp;amp;f_{xx}(x_0,y_0) \
B=&amp;amp;f_{xy}(x_0,y_0) \
C=&amp;amp;f_{yy}(x_0,y_0)
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;则有&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
AC-B^2&amp;amp;&amp;gt;0\implies\text{ 极值 }\begin{cases}
A&amp;lt;0\implies \text{ 极大值 } \
A&amp;gt;0\implies \text{ 极小值 } \
\end{cases} \
AC-B^2&amp;amp;&amp;lt;0\implies\text{ 鞍点 } \
AC-B^2&amp;amp;=0\implies\text{ 无法判断 } \
\end{align*}&lt;/p&gt;
&lt;p&gt;$$&lt;/p&gt;
&lt;p&gt;一元里$f&apos;&apos;=0$在这里升级成了$AC-B^2=0$, 只能回定义或另想办法。不过真题里极少出现，最多概念题挖点坑。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;Pasted%20image%2020260808030159.png&quot; alt=&quot;三种典型可判曲面，左至右分别准确判定为最小值、鞍点、最大值&quot; /&gt;&lt;/p&gt;
&lt;p&gt;:::note
实际做题中，我们一般做:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;计算一阶偏导，解等于0方程组，使用&lt;strong&gt;必要&lt;/strong&gt;条件(偏导数为0)筛选出所有驻点；&lt;/li&gt;
&lt;li&gt;计算二阶偏导，代入前面求得的几个驻点逐个解算筛选$AC-B^2&amp;gt;0$者
:::&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;另外，一般来说，函数在区域的边界上的极值大多数情形是非常好算的，只要简单代入即可了。&lt;/p&gt;
&lt;h3&gt;拉格朗日乘数法&lt;/h3&gt;
&lt;p&gt;有时，题目要求$f(x,y)$在某一约束$\varphi(x,y)=0$下的极值。&lt;/p&gt;
&lt;p&gt;约束把变量困在一条曲线上，极值点当然不是自由驻点，直接套无条件极值会失效。正确做法是构造&lt;strong&gt;拉格朗日函数&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;$$
L(x,y,\lambda) = f(x,y) + \lambda,\varphi(x,y)
$$&lt;/p&gt;
&lt;p&gt;然后解方程组$L_x=0,\ L_y=0,\ L_\lambda=0$（$L_\lambda=0$就是约束本身），得到的解就是可能的条件极值点。&lt;/p&gt;
&lt;h3&gt;27330:165/&amp;lt;u&amp;gt;90&amp;lt;/u&amp;gt;/★★★★☆&lt;/h3&gt;
&lt;p&gt;过椭圆$\textcolor{aqua}{ 3x^2 + 2xy + 3y^2}=1$上任意一点作椭圆的切线，试求该切线与两坐标轴所围三角形面积的最小值。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;本题没有概念性的东西，但硬算会算炸，主要考各种简化计算的技巧。&lt;/p&gt;
&lt;p&gt;比如说，切线可以用隐函数公式求得。方程$F(x,y)=0$在$(x_0,y_0)$处切线为$F_x(x_0,y_0)(x-x_0)+F_y(x_0,y_0)(y-y_0)=0$.&lt;/p&gt;
&lt;p&gt;我们先求出来&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;解:&lt;/p&gt;
&lt;p&gt;$F=3x^2+2xy+3y^2-1$, $F_x=6x+2y$, $F_y=2x+6y$, 在$(a,b)$处切线为
$$
(3a+b)x+(a+3b)y=1
$$
两截距分别为$\dfrac{1}{3a+b}$、$\dfrac{1}{a+3b}$, 故三角形面积
$$
\begin{align*}
S&amp;amp;=\frac{1}{2\left|(3a+b)(a+3b)\right|} \
&amp;amp;=\frac{1}{2\left|\textcolor{aqua}{ 3a^{2}+2ab+3b^{2} }+8ab\right|} \
&amp;amp;=\frac{1}{2|1+8ab|}
\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;从椭圆方程约束本身$\textcolor{aqua}{ 3x^2 + 2xy + 3y^2}=1$即可化简。&lt;/p&gt;
&lt;p&gt;注意，现在我们需要求三角形面积的最小值，即最小化$S$,也就是最大化$|1+8ab|$. 也就是考究$ab$的最值. 再换种说法，取$ab$的最大值和负的最小值比较，取更大者。总而言之，我们要&lt;strong&gt;求$ab$的驻点&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;然而，此处求得的函数$S$&lt;strong&gt;不是自由二维$\mathbb{R}^{2}$方程&lt;/strong&gt;。 为什么求到这里$x$和$y$变成了$a$和$b$, 因为$ab$之间&lt;strong&gt;有椭圆方程约束限制&lt;/strong&gt;，本质上是一维的。 如果是一般函数或按轴对齐的椭圆方程，或许还能提取出$b=f(a)$然后求函数$a\cdot f(a)$的驻点，但就这个躺倒的椭圆方程来看，明显不大行。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;Pasted%20image%2020260816043551.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;此时就是拉格朗日乘数法的引入时机。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在椭圆上求$xy$的最值。使用拉格朗日乘数法:
$$
\begin{align*}
L&amp;amp;=xy-\lambda(3x^2+2xy+3y^2-1) \
L_x&amp;amp;=y-\lambda(6x+2y)=0 \
L_y&amp;amp;=x-\lambda(2x+6y)=0 \
y(2x+6y)&amp;amp;=x(6x+2y) \
y^2&amp;amp;=x^2 \
y&amp;amp;=\pm x
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;当$y=x$时, $8x^2=1$, $xy=\dfrac18$.
当$y=-x$时, $4x^2=1$, $xy=-\dfrac14$.
令$S=\dfrac{1}{2|1+8ab|}$取最小, 取$xy=\dfrac18$, 此时
$$
S_{\min}=\frac{1}{2(1+8\cdot\frac18)}=\frac14
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;本题不用拉格朗日计算量会爆炸。不怕死的可以试试&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;27330:171/&amp;lt;u&amp;gt;120&amp;lt;/u&amp;gt;/★★★★☆&lt;/h3&gt;
&lt;p&gt;已知函数$z = f(x, y)$满足
$$
\lim\limits_{\substack{\Delta x \to 0 \ \Delta y \to 0}} \frac{f(x + \Delta x, y + \Delta y) - f(x, y) - 2x\Delta x + 2y\Delta y}{\sqrt{(\Delta x)^2 + (\Delta y)^2}} = 0
$$
且$f(0, 0) = 2$. 求$f(x, y)$在圆域$D = {(x, y) \mid x^2 + y^2 \leqslant 1}$上的最大值和最小值。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;分子长得就是可微定义的标准形状。$f$的增量减去线性主部再除以$\rho$。认出这一点，题就变成了「积分求原函数 + 一元最值」。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;对每个$(x,y)$, 条件正是$f$在该点可微且
$$
f_x(x,y)=2x,\qquad f_y(x,y)=-2y
$$
先对$x$积分，再用$f_y$定出积分常数:
$$
f(x,y)=x^2+\varphi(y),\quad \varphi&apos;(y)=-2y\implies \varphi(y)=-y^2+C
$$
$$
f(x,y)=x^2-y^2+C,\qquad f(0,0)=2\implies C=2
$$
$$
f(x,y)=x^2-y^2+2
$$
圆域$x^2+y^2\le1$上: 内部驻点只有$(0,0)$, $f=2$；边界$x^2+y^2=1$上
$$
f=x^2-y^2+2=2x^2+1,\quad x\in[-1,1]
$$
$$
\boxed{\max f=3\ (\text{在}(\pm1,0)),\qquad \min f=1\ (\text{在}(0,\pm1))}
$$&lt;/p&gt;
</content:encoded></item><item><title>【学习笔记】数学笔记其六 · 一元函数积分学【下】</title><link>https://blog.emumu.xyz/posts/2026-08-01-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-08-01-00/</guid><description>积分给我似啊啊啊啊啊啊啊啊(战吼</description><pubDate>Mon, 03 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;如果你是首次进入我的新数学笔记系列, 请先&lt;a href=&quot;/posts/2026-07-09-00/&quot;&gt;点此阅读预告回&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;积分我分为四类题型:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;计算&lt;/strong&gt;。包括简单的不定积分和定积分计算。即纯计算技巧。见上期&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分析&lt;/strong&gt;。比如比大小和单调等。基于计算技巧结合，此处不展开。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;中值&lt;/strong&gt;。由拉格朗日中值引出的积分中值定理和积分第二中值定理。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;应用&lt;/strong&gt;。包括旋转体和我们数二独有的物理题。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;本期内容比较少，因为主要是类型题。其中中值方面比较吃理解，应用方面只要跨过那个坎就是单纯的初见杀排雷现场。&lt;/p&gt;
&lt;p&gt;尽管内容比较少我也还是要分上下期，因为微分那期所有东西糊到一起导致卡顿问题很严重，而且微分那章内容也被压的很死，这次就不这么干了。(其实我试过 积分两期加一起比微分多30%)&lt;/p&gt;
&lt;h2&gt;证明类题&lt;/h2&gt;
&lt;p&gt;除了老生常谈的绝对C位积分中值，积分为主的证明题里分部积分也是出场率top之一。&lt;/p&gt;
&lt;h3&gt;积分中值定理&lt;/h3&gt;
&lt;p&gt;由拉格朗日中值推导:&lt;/p&gt;
&lt;p&gt;设$F(x)=\int_a^x f(t),dt$, 则$F&apos;(x)=f(x)$（微积分基本定理）。$F$在$[a,b]$上连续、$(a,b)$内可导，对$F$用拉格朗日中值定理:&lt;/p&gt;
&lt;p&gt;$$
\frac{F(b)-F(a)}{b-a} = F&apos;(\xi) = f(\xi)
$$&lt;/p&gt;
&lt;p&gt;即&lt;/p&gt;
&lt;p&gt;$$
\int_{a}^b f(x) dx = f(\xi)(b-a)
$$&lt;/p&gt;
&lt;p&gt;函数$f$在区间上起伏不定，但总能找到一点$\xi$, 让$f(\xi)$恰好等于$f$在$[a,b]$上的平均值。几何上就是&quot;面积=某一点的高×底&quot;。这就是积分中值定理，要我说就是把整个拉格朗日中值抽象积分了一下。&lt;/p&gt;
&lt;p&gt;还有一个重要推广: 若$g(x)$在$[a,b]$上&lt;strong&gt;不变号&lt;/strong&gt;，则存在$\xi\in[a,b]$使得&lt;/p&gt;
&lt;p&gt;$$
\textcolor{aqua}{ \int_a^b } \textcolor{yellow}{ f(x) }\textcolor{aqua}{ g(x) ,dx} = \textcolor{gold}{ f(\xi) }\textcolor{aqua}{ \int_a^b g(x),dx }
$$&lt;/p&gt;
&lt;p&gt;证明思路: $g$不变号时，把$f(x)g(x)$看作以$g$为&quot;权&quot;的加权平均，$g(x),dx$整体充当加宽的微元，与不加权的情形如出一辙。&lt;/p&gt;
&lt;p&gt;:::tip
我们经常需要证一些东西，比如$\int_{a}^\xi f(x)dx$, 当$a$已知时，我们通常设$F(x)=\int_{a}^x f(t)dt$, 这样能够很方便地让$\xi$“存在”。下限同理，求导时加负号不提。
:::&lt;/p&gt;
&lt;h3&gt;积分第二中值定理&lt;/h3&gt;
&lt;p&gt;我们用刚才的积分中值定理直接来证积分二中（的一个条件简化版）:&lt;/p&gt;
&lt;h3&gt;27330:137/&amp;lt;u&amp;gt;90&amp;lt;/u&amp;gt;/★★★★☆&lt;/h3&gt;
&lt;p&gt;设$f(x)$在$[a,b]$上单调可导，$g(x)$在$[a,b]$上连续。证明存在$\xi \in [a,b]$使得:&lt;/p&gt;
&lt;p&gt;$$
\int_{a}^b f(x)g(x)dx=f(a)\int_{a}^\xi g(x)dx+f(b)\int_{\xi}^bg(x)dx
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;分部积分，把$g$攒成$G$.乘积积分遇到单调/不变号因子。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;令$G(x)=\int_a^x g(t),dt$, 则$G&apos;(x)=g(x)$.分部积分得&lt;/p&gt;
&lt;p&gt;$$
\textcolor{lime}{ \int_a^b f(x)g(x),dx } = \textcolor{magenta}{ f(b)G(b) } - \textcolor{aqua}{ \int_a^b f&apos;(x)\textcolor{yellow}{ G(x) },dx }
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;$f$单调$\Rightarrow f&apos;$不变号，对$\int_a^b f&apos;G,dx$用推广的积分中值定理，把$G(x)$整只提成$G(\xi)$.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;因$f$单调，$f&apos;$在$[a,b]$上不变号；$G$连续。由推广的积分中值定理，存在$\xi\in(a,b)$使得&lt;/p&gt;
&lt;p&gt;$$
\textcolor{aqua}{ \int_a^b f&apos;(x)\textcolor{yellow}{ G(x) },dx } = \textcolor{gold}{G(\xi)}\textcolor{aqua}{ \int_a^b f&apos;(x),dx } = \textcolor{gold}{G(\xi)}\textcolor{aqua}{ \bigl(f(b)-f(a)\bigr)  }
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;代回，把$f(b)G(b)$拆成$f(b)G(\xi)$和$f(b)(G(b)-G(\xi))$, 对号入座。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;$$
\begin{align*}
\textcolor{lime}{ \int_a^b f(x)g(x),dx } &amp;amp;= \textcolor{magenta}{ f(b)G(b) } - \textcolor{gold}{ G(\xi)}\textcolor{aqua}{ \bigl(f(b)-f(a)\bigr) }  \
&amp;amp;= f(a)G(\xi) + f(b)\bigl(G(b)-G(\xi)\bigr) \
&amp;amp;= f(a)\int_a^\xi g(x),dx + f(b)\int_\xi^b g(x),dx
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;证毕。这个结论就叫&lt;strong&gt;积分第二中值定理&lt;/strong&gt;。$f$单调递减时$f&apos;\le0$, 同样不变号，完全同理。&lt;/p&gt;
&lt;p&gt;:::tip
学会证明一些定理对$\varepsilon-\delta$大boss是很有帮助的。&lt;/p&gt;
&lt;p&gt;不过这并不算基础定理，至少它不在考纲里。&lt;/p&gt;
&lt;p&gt;但它确实是有用的，比如说……↓
:::&lt;/p&gt;
&lt;h3&gt;27330:139/&amp;lt;u&amp;gt;90&amp;lt;/u&amp;gt;/★★★★☆&lt;/h3&gt;
&lt;p&gt;设$f(x)$在$[0,1]$上连续，且$\int_0^1x^2f(x)dx=\int_0^1f(x)dx$. 证明存在$\xi \in [0,1]$使得:&lt;/p&gt;
&lt;p&gt;$$
\int_{0}^\xi f(x)dx=0
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这道题可以用标准方法，也可以直接把积分二中套上来做。不过除非时间不够了，最好简单把二中证明一下。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;解&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;目标是证明这段积分为零。&lt;/p&gt;
&lt;p&gt;老规矩，先令$F(x)=\int_0^x f(t),dt$, 目标变为$F(\xi)=0$.&lt;/p&gt;
&lt;p&gt;再观察$F$, 显然条件本质是$\int_0^1(x^2-1)f(x),dx=0$, 分部积分得到$F$方便后续操作&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;令$F(x)=\int_0^x f(t),dt$, 则$F&apos;(x)=f(x)$.对$\int_0^1 x^2f(x),dx$分部积分:&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
\int_0^1 x^2 f(x),dx &amp;amp;= \bigl[x^2F(x)\bigr]_0^1 - \int_0^1 2xF(x),dx \
&amp;amp;= F(1) - 2\int_0^1 xF(x),dx
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;由条件$\int_0^1 x^2f(x),dx = \int_0^1 f(x),dx = F(1)$, 得&lt;/p&gt;
&lt;p&gt;$$
F(1) = F(1) - 2\int_0^1 xF(x),dx \quad\Longrightarrow\quad \int_0^1 xF(x),dx = 0
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;收尾很经典: $x$在$[0,1]$上非负不变号，$F$连续，推广的积分中值定理直接给出$F(\eta)=0$.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;由$F$连续、$x$在$[0,1]$上不变号，用推广的积分中值定理，存在$\eta\in[0,1]$使得&lt;/p&gt;
&lt;p&gt;$$
\int_0^1 xF(x),dx = F(\eta)\int_0^1 x,dx = \frac{F(\eta)}{2}
$$&lt;/p&gt;
&lt;p&gt;于是$F(\eta)=0$, 即存在$\xi=\eta\in[0,1]$使得&lt;/p&gt;
&lt;p&gt;$$
\int_0^\xi f(x),dx = 0
$$&lt;/p&gt;
&lt;p&gt;证毕。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;再看积分二中秒杀&lt;/p&gt;
&lt;p&gt;条件即$\int_0^1(x^2-1)f(x),dx=0$, 而$x^2-1$在$[0,1]$上单调递增，对$g(x)=x^2-1$和$f$用积分二中，存在$\xi\in[0,1]$使&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
0=&amp;amp;\int_0^1 (x^2-1)f(x),dx \
=&amp;amp; \underbrace{(0^2-1)}&lt;em&gt;{-1}\int_0^\xi f(x),dx + \underbrace{(1^2-1)}&lt;/em&gt;{0}\int_\xi^1 f(x),dx \
=&amp;amp; -\int_0^\xi f(x),dx=0
\end{align*}&lt;/p&gt;
&lt;p&gt;$$&lt;/p&gt;
&lt;p&gt;一步出答案。不过大题一般不用超纲结论，所以正文老老实实证了。选择题可以随便用这些小手段。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;27330:145/&amp;lt;u&amp;gt;135&amp;lt;/u&amp;gt;/★★★★★&lt;/h3&gt;
&lt;p&gt;设函数$f(x)$满足$f&apos;&apos;(x) &amp;gt; 0$, $\int_{0}^{1} f(x)\mathrm{d}x = 0$, 证明: 对任意$x \in [0,1]$, 都有$|f(x)| \leqslant \max{f(0), f(1)}$。&lt;/p&gt;
&lt;p&gt;:::tip
一个十分耐用的方法论是，当一个函数展现出接近于某种函数（如普通的一次、二次、其他显示或隐式函数）而又与它有显著不同的、有待研究的性质时，相减即可直接暴露这种性质。&lt;/p&gt;
&lt;p&gt;另一个方法论是实在无法正推一个看起来很显然的结论时，善用反证法，引入矛盾。
:::&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;首先分析条件: $f(x)$是凸函数，两侧端点必有一端是这一段函数值的上界。&lt;/p&gt;
&lt;p&gt;再分析条件: $|f(x)| \leqslant \max{f(0), f(1)}$, 不妨设$f(1)&amp;gt;f(0)$, 反正$f(0)&amp;gt;f(1)$肯定也成立。条件再展开为$-f(1) \leq f(x) \leq f(1)$. 上界由于凹函数是显然成立的，故只需要证明$f(x) \geq -f(1)$. 如果足够自信，也可以直接设$M = \max{f(0), f(1)}$, 考场试错成本更高，但答案也更有说服力。&lt;/p&gt;
&lt;p&gt;最后分析条件: $\int_{0}^{1} f(x)\mathrm{d}x = 0$.这个条件尤其简单，并不好利用，直接中值得到的结果也很可怜($\exists \xi \in (0,1),f(\xi)=0$)。但凹凸函数有很多关于直线的性质，其中就包括了&lt;strong&gt;凹曲线上两点的连线在该开区间内大于凹曲线&lt;/strong&gt;，这个性质在此处能够完美融合凹性、区间性(不要试图证明结论的超结论)、积分值(恰好构成不等式，与结论形式相同)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;令$M = \max{f(0), f(1)}$。&lt;/p&gt;
&lt;p&gt;对任意$x\in[0,1]$, 由凸性有
$$
f(x) \le (1-x)f(0) + x f(1) \le M.
$$&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;Pasted%20image%2020260803031919.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;下证$f(x) \ge -M$。用反证法。&lt;/p&gt;
&lt;p&gt;假设存在$x_0 \in (0,1)$使得$f(x_0) &amp;lt; -M$。由凸性，
$$
\begin{aligned}
x\in[0,x_0] &amp;amp;\Rightarrow f(x) \le f(0) + \frac{f(x_0)-f(0)}{x_0},x, \
x\in[x_0,1] &amp;amp;\Rightarrow f(x) \le f(x_0) + \frac{f(1)-f(x_0)}{1-x_0},(x-x_0).
\end{aligned}
$$
分别积分并相加得
$$
\int_0^1 f(x),dx \le \frac{x_0}{2}[f(0)+f(x_0)] + \frac{1-x_0}{2}[f(x_0)+f(1)].
$$
右端整理为$\dfrac12\bigl[f(0)x_0 + f(1)(1-x_0) + f(x_0)\bigr]$。&lt;/p&gt;
&lt;p&gt;由$f(0) \le M,, f(1) \le M$知$f(0)x_0 + f(1)(1-x_0) \le M$, 又$f(x_0) &amp;lt; -M$, 故
$$
\int_0^1 f(x),dx &amp;lt; \frac12\bigl[M + (-M)\bigr] = 0,
$$
与已知$\int_0^1 f(x),dx = 0$矛盾。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;Pasted%20image%2020260803031958.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;因此对一切$x\in[0,1]$均有$f(x) \ge -M$, 从而$|f(x)| \le M$。证毕。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;不使用反证法，直接积分折线面积与0比较也可以直接导出结论不等式。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;定积分的应用&lt;/h2&gt;
&lt;p&gt;这一章包括面积、弧长和体积的两种公式。直角、参数、极坐标公式又多又杂，我绝不推荐一个个死记硬背，哪怕最后没背下来也要考试现场能推出来。&lt;/p&gt;
&lt;h3&gt;面积&lt;/h3&gt;
&lt;p&gt;定积分本身就是&quot;宽$\to0$的长条面积求和&quot;，面积是它最直白的应用。曲线$y=f(x)$（$f\ge0$）与$x$轴及直线$x=a$、$x=b$围成的面积为&lt;/p&gt;
&lt;p&gt;$$
S = \int_a^b f(x),dx
$$&lt;/p&gt;
&lt;p&gt;最常用的变体是两条曲线之间的面积，上减下简单不提。如果不知道谁上谁下，就加绝对值或分段讨论。&lt;/p&gt;
&lt;p&gt;参数方程与极坐标是同一套逻辑，记住微元即可:&lt;/p&gt;
&lt;p&gt;参数方程$\begin{cases}x=x(t)\y=y(t)\end{cases}$有:&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
S=&amp;amp;\int y dx \
=&amp;amp;\int y(t) d(x(t)) \
=&amp;amp;\int y(t) x&apos;(t) dt
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;极坐标$r=r(\theta)$不一样，它使用扇形微元&lt;/p&gt;
&lt;p&gt;扇环微元$dS=\frac12 r^2,d\theta$, 即$S=\frac12\int_\alpha^\beta r^2(\theta),d\theta$.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;极坐标最经典的心形线$r=a(1+\cos\theta)$, 面积$S=\frac12\int_0^{2\pi}a^2(1+\cos\theta)^2,d\theta$, 读者自证不难（提示: 华里士/降幂）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;弧长&lt;/h3&gt;
&lt;p&gt;取曲线上的一小段微元$ds$, 近似为直角三角形斜边:&lt;/p&gt;
&lt;p&gt;$$
ds = \sqrt{(dx)^2 + (dy)^2}
$$&lt;/p&gt;
&lt;p&gt;三个场景都从这一个微元出发，把$dx,dy$换成各自的表达式即可。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;直角坐标&lt;/strong&gt; $y=f(x)$, $dy=f&apos;(x),dx$&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
s=&amp;amp;\int\sqrt{(dx)^2 + (dy)^2} \
=&amp;amp;\int \sqrt{1+\left( \frac{dy}{dx} \right)^2},dx \
=&amp;amp;\int \sqrt{1+[f&apos;(x)]^2},dx
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;参数方程&lt;/strong&gt; $\begin{cases}x=x(t)\y=y(t)\end{cases}$, $dx=x&apos;(t),dt$, $dy=y&apos;(t),dt$&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
s=&amp;amp;\int\sqrt{(dx)^2 + (dy)^2} \
=&amp;amp;\int \sqrt{(x&apos;(t),dt)^2+(y&apos;(t),dt)^{2}} \
=&amp;amp;\int \sqrt{x&apos;(t)^2+y&apos;(t)^2},dt
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;极坐标&lt;/strong&gt; $r=r(\theta)$, $x=r\cos\theta$, $y=r\sin\theta$&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
s &amp;amp;= \int\sqrt{(dx)^2 + (dy)^2} \
&amp;amp;= \int\sqrt{(r&apos;\cos\theta - r\sin\theta)^2 + (r&apos;\sin\theta + r\cos\theta)^2},d\theta \
&amp;amp;= \int\sqrt{r&apos;^2(\cos^2\theta+\sin^2\theta) + r^2(\sin^2\theta+\cos^2\theta)},d\theta \
&amp;amp;= \int\sqrt{r^2 + (r&apos;)^2},d\theta \
\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;推一遍比背三个公式靠谱。三个公式本来就是一个微元。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;侧面积&lt;/h3&gt;
&lt;p&gt;这里特指&lt;strong&gt;旋转体的侧面积&lt;/strong&gt;。它和体积是近亲，但微元完全不同，也是最容易记混的一对。&lt;/p&gt;
&lt;p&gt;简单来说，侧面积就是弧长再乘一个周长$2\pi y$。&lt;/p&gt;
&lt;p&gt;在$x$处取弧长微元$ds$, 它绕$x$轴旋转一周扫出一个&lt;strong&gt;圆台侧面&lt;/strong&gt;——上底半径$y$、下底半径$y+dy$、母线长$ds$. 圆台侧面积公式是初中几何: $\pi(R+r)l$, 在微元尺度上$R\approx r\approx y$, 故&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
dS &amp;amp;= \pi\bigl[(y+dy) + y\bigr]\cdot ds \
&amp;amp;= 2\pi y,ds + \pi,dy,ds \
&amp;amp;\approx 2\pi y,ds
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;即侧面积微元&lt;/p&gt;
&lt;p&gt;$$
dS = 2\pi y,ds
$$&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;56f299ad-323f-4361-be67-bac124a0dea1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;和弧长一样，三个场景从同一个微元出发，代入各自的$ds$即可。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;直角坐标&lt;/strong&gt; $y=f(x)$, $dy=f&apos;(x),dx$&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
S=&amp;amp;\int 2\pi y,ds \
=&amp;amp;\int 2\pi f(x)\sqrt{1+[f&apos;(x)]^2},dx
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;参数方程&lt;/strong&gt; $\begin{cases}x=x(t)\y=y(t)\end{cases}$&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
S=&amp;amp;\int 2\pi y,ds \
=&amp;amp;\int 2\pi y(t)\sqrt{x&apos;(t)^2+y&apos;(t)^2},dt
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;极坐标&lt;/strong&gt; $r=r(\theta)$, 此时$y=r\sin\theta$&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
S=&amp;amp;\int 2\pi y,ds \
=&amp;amp;\int 2\pi r\sin\theta,\sqrt{r^2+r&apos;^2},d\theta
\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;侧面积就是弧长再乘一个周长$2\pi y$。&lt;/p&gt;
&lt;p&gt;再次强调: 是&lt;strong&gt;弧长&lt;/strong&gt;。$S=\int 2\pi y;\textcolor{aqua}{ ds }$&lt;/p&gt;
&lt;p&gt;绕y轴如上。绕x轴同理，$S=\int 2\pi x;\textcolor{aqua}{ ds }$.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;体积（圆盘）&lt;/h3&gt;
&lt;p&gt;最简单的情形: 曲线$y=f(x)$（$f\ge0$）与$x$轴、$x=a$、$x=b$围成的区域绕$x$轴旋转一周得到的旋转体。&lt;/p&gt;
&lt;p&gt;在$x$处切一薄片，它近似是一个半径为$f(x)$、厚度$dx$的薄圆盘，体积微元&lt;/p&gt;
&lt;p&gt;$$
dV = \pi f(x)^2,dx
$$&lt;/p&gt;
&lt;p&gt;于是&lt;/p&gt;
&lt;p&gt;$$
V = \int_a^b \pi f(x)^2,dx
$$&lt;/p&gt;
&lt;p&gt;若旋转的是两条曲线之间的区域（$f\ge g$），薄片是&lt;strong&gt;垫圈&lt;/strong&gt;（外半径$f(x)$、内半径$g(x)$）:&lt;/p&gt;
&lt;p&gt;$$
V = \int_a^b \pi\bigl[f(x)^2 - g(x)^2\bigr],dx
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;注意是$f^2-g^2$, &lt;strong&gt;不是&lt;/strong&gt;$(f-g)^2$.外圆面积减内圆面积，平方差在半径上，不在半径差上。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;若绕平行于$x$轴的直线$y=c$旋转，把$f(x)$换成$|f(x)-c|$即可。绕$y$轴旋转则见下节柱壳法。&lt;/p&gt;
&lt;h3&gt;体积（柱壳）&lt;/h3&gt;
&lt;p&gt;在$x$处切一竖条，高$f(x)$、宽$dx$, 它绕$y$轴旋转扫出一个薄柱壳。&lt;/p&gt;
&lt;p&gt;半径$x$、高$f(x)$、壁厚$dx$的圆柱筒。展开成矩形是长$2\pi x$（周长）、宽$f(x)$、厚$dx$, 体积微元&lt;/p&gt;
&lt;p&gt;$$
dV = 2\pi x f(x),dx
$$&lt;/p&gt;
&lt;p&gt;于是&lt;/p&gt;
&lt;p&gt;$$
V = \int_a^b 2\pi x f(x),dx
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;圆柱筒侧面展开成矩形，底面周长$2\pi r$ × 高。柱壳法就是把每根空心圆柱筒展开算体积再攒起来。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;两条曲线之间绕$y$轴旋转时，把高度换成$f(x)-g(x)$.&lt;/p&gt;
&lt;h3&gt;重心（质心）&lt;/h3&gt;
&lt;p&gt;简单来说，&lt;strong&gt;质心 = 每个质点的位置按质量加权平均&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;把物体切成微元，每个微元贡献&quot;位置 × 质量&quot;（这叫静力矩），加起来除以总质量:&lt;/p&gt;
&lt;p&gt;$$
\bar{x} = \frac{\int x,dm}{\int dm}, \qquad \bar{y} = \frac{\int y,dm}{\int dm}
$$&lt;/p&gt;
&lt;p&gt;总质量 $M=\int dm$
对$y$轴的静力矩 $M_y=\int x,dm$
对$x$轴的静力矩 $M_x=\int y,dm$&lt;/p&gt;
&lt;p&gt;两个一除就是重心。问题在于一般来说$dm$会不太好算。比如密度不均匀（如$\rho=\rho(x)$）时把$dm=\rho(x),ds$代入分子分母一起积分，没有新东西。&lt;/p&gt;
&lt;p&gt;:::tip
&lt;strong&gt;帕普斯（古尔丁）定理&lt;/strong&gt;指出，平面区域绕不与之相交的轴旋转，旋转体体积 = 区域面积 × 形心绕轴走过的路程（$2\pi\bar{x}A$）。反过来，知道体积和面积就能反推形心位置。对称图形（圆、圆环、半圆）的形心在对称轴上，很多体积题用它一眼验算正误，或者干脆秒杀。
:::&lt;/p&gt;
&lt;h3&gt;27660:128/&amp;lt;u&amp;gt;110&amp;lt;/u&amp;gt;/★★★★☆&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;星形线具有对称性，面积、弧长、体积、侧面积均可利用参数方程在第一象限的部分计算后再乘倍数。面积用定积分$\int y,dx$, 弧长用$\int \sqrt{x&apos;^2+y&apos;^2},dt$, 体积用$\int \pi y^2,dx$, 侧面积用$\int 2\pi y,ds$, 再代入参数方程及微分化简。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;由对称性，只需计算第一象限$t\in[0,\frac{\pi}{2}]$的对应量，再乘以倍数。&lt;/p&gt;
&lt;p&gt;$$
\begin{cases}
x&amp;amp;=a\cos^3 t,\
y&amp;amp;=a\sin^3 t,\
x&apos;&amp;amp;=-3a\cos^2 t\sin t,\
y&apos;&amp;amp;=3a\sin^2 t\cos t, \
ds &amp;amp;= \sqrt{x&apos;^2+y&apos;^2},dt = 3a|\cos t\sin t|,dt= \frac{3a}{2}\sin 2t,dt.
\end{cases}
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;面积&lt;/strong&gt;$A$
$$
\begin{align*}
\frac{A}{4}&amp;amp;= \int_0^a y,dx \
&amp;amp;= \int_0^{\frac{\pi}{2}} (a\sin^3 t)(3a\cos^2 t\sin t),dt \
&amp;amp;= 3a^2\int_0^{\frac{\pi}{2}}\sin^4 t\cos^2 t,dt \
&amp;amp;= \frac{3\pi a^2}{32}, \
A &amp;amp;= \frac{3}{8}\pi a^2.
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;弧长&lt;/strong&gt;$L$
$$
\begin{align*}
L &amp;amp;= 4\int_0^{\frac{\pi}{2}} ds \
&amp;amp;= 4\int_0^{\frac{\pi}{2}} \frac{3a}{2}\sin 2t,dt \
&amp;amp;= 6a\left[-\frac{1}{2}\cos 2t\right]_0^{\frac{\pi}{2}} \
&amp;amp;= 6a.
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;体积&lt;/strong&gt;$V$（绕$x$轴，2倍第一象限体积）&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
V &amp;amp;= 2\int_0^a \pi y^2,dx \
&amp;amp;= 2\pi\int_0^{\frac{\pi}{2}} (a^2\sin^6 t)(3a\cos^2 t\sin t),dt \
&amp;amp;= 6\pi a^3\int_0^{\frac{\pi}{2}}\sin^7 t\cos^2 t,dt. \&lt;/p&gt;
&lt;p&gt;&amp;amp;= 6\pi a^3\int_0^{\frac{\pi}{2}}(\sin^7 t - \sin^9 t)dt\&lt;/p&gt;
&lt;p&gt;&amp;amp;= 6\pi a^3\cdot\frac{16}{315} \
&amp;amp;= \frac{32}{105}\pi a^3.
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;侧面积&lt;/strong&gt;$S$（绕$x$轴，上半部分旋转侧面积的2倍，或直接4倍第一象限侧面积）&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
S &amp;amp;= 2\int_{\text{上半}} 2\pi y,ds \
&amp;amp;= 4\pi\int_0^{\frac{\pi}{2}} y,ds \
&amp;amp;= 4\pi\int_0^{\frac{\pi}{2}} a\sin^3 t\cdot\frac{3a}{2}\sin 2t,dt \
&amp;amp;= 6\pi a^2\int_0^{\frac{\pi}{2}} \sin^3 t\cdot 2\sin t\cos t,dt. \
&amp;amp;= 6\pi a^2\cdot(2\int_0^1 u^4,du) \
&amp;amp;= 6\pi a^2\cdot\frac{2}{5} \
&amp;amp;= \frac{12}{5}\pi a^2.
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;$$
\boxed{A=\frac{3}{8}\pi a^2,\quad L=6a,\quad V=\frac{32}{105}\pi a^3,\quad S=\frac{12}{5}\pi a^2}
$$&lt;/p&gt;
&lt;h2&gt;积分的物理应用&lt;/h2&gt;
&lt;h3&gt;重看常见物理公式&lt;/h3&gt;
&lt;p&gt;数二独享的定积分应用就是物理题。我们要频繁地将物理公式从高中代数视角转化为高数微积分视角。高频考点如下:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;变力做功。&lt;/strong&gt; 力$F(x)$沿$x$轴把物体从$a$推到$b$.微元$dx$上力近似不变，做功$dW=F(x),dx$, 于是&lt;/p&gt;
&lt;p&gt;$$
W = \int_a^b F(x),dx
$$&lt;/p&gt;
&lt;p&gt;高中只考恒力$W=Fs$, 考研考变力, 弹簧的$F=kx$、引力、阻力，给出$F$随位置的变化规律，积分即可。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;液体压力。&lt;/strong&gt; 浸在液体中的平板，深度$h$处的压强$p=\rho g h$（$\rho$为液体密度）。取水平微条，宽$L(y)$、高$dy$、深度$h(y)$, 压力微元&lt;/p&gt;
&lt;p&gt;$$
dF = p,dA = \rho g,h(y),L(y),dy
$$&lt;/p&gt;
&lt;p&gt;然后积分。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;同一水平线上压强处处相等，所以要水平切片&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;细杆质量。&lt;/strong&gt; 线密度$\rho(x)$随位置变化，微元$dm=\rho(x),dx$, 质量&lt;/p&gt;
&lt;p&gt;$$
m = \int_a^b \rho(x),dx
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;三个公式全是&quot;微元=密度*长度/面积&quot;。物理应用题不会考新物理，考的是你敢不敢把高中公式拆成微元。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;微元化拆解&lt;/h3&gt;
&lt;p&gt;当然，实际题基本不会考简单的上面几个公式。大部分都是复杂的各种公式套一起要剥洋葱。具体怎么剥，看一道例题最合适:&lt;/p&gt;
&lt;h3&gt;27330:147/&amp;lt;u&amp;gt;90&amp;lt;/u&amp;gt;/★★★★☆&lt;/h3&gt;
&lt;p&gt;已知一容器的外表面由曲线$y = \frac{1}{2}x^2$($0 \leqslant y \leqslant h_0$) 绕$y$轴旋转一周得到，容积为$64\pi,\text{m}^3$, 现将容器盛满水，从容器顶部抽水。（水的密度为$\rho = 1000,\text{kg/m}^3$, $g = 10,\text{m/s}^2$）
(1) 若要将水全部抽出，至少要做多少功？
(2) 若将水抽出$28\pi,\text{m}^3$, 至少要做多少功？&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;Pasted%20image%2020260803062653.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;求功公式$dW=F,ds$.&lt;/li&gt;
&lt;li&gt;抽出所需的力是重力势能$F=mgh$. $g$是常数. $h$对于各层的水不同，故随$y$变化, $h=(h_{0}-y)$. $dF=gh,dm$&lt;/li&gt;
&lt;li&gt;$m$是质量, 由于容器外表面诡异, 每层水的质量也不同。$dm=\rho dV$.$\rho$是常数。&lt;/li&gt;
&lt;li&gt;$V$是体积, 由于容器外表面诡异, 每层谁的体积也不同。此处的体积微元已经是简单圆盘，半径与$x$有关，高度为微小值, $dV=\pi x^{2},dy$.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;(1). 解:&lt;/p&gt;
&lt;p&gt;:::tip
下面这个剥洋葱过程就是最难的一步
:::&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
\textcolor{lime}{ dW }=&amp;amp;F,ds \
=&amp;amp;\textcolor{aqua}{ g }h,dm \
=&amp;amp;\textcolor{aqua}{ g }(\textcolor{aqua}{ h_{0} }-\textcolor{magenta}{ y }),dm \
=&amp;amp;\textcolor{aqua}{ g }(\textcolor{aqua}{ h_{0} }-\textcolor{magenta}{ y })\textcolor{aqua}{ \rho } , dV \
=&amp;amp;\textcolor{aqua}{ g }(\textcolor{aqua}{ h_{0} }-\textcolor{magenta}{ y })\textcolor{aqua}{\rho\pi} \textcolor{magenta}{ x^{2} },\textcolor{yellow}{ dy } \
=&amp;amp;\textcolor{aqua}{ g }(\textcolor{aqua}{ h_{0} }-\textcolor{magenta}{ y })\textcolor{aqua}{\rho\pi } \textcolor{magenta}{ 2y },\textcolor{yellow}{ dy }
\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;上面的上色分别是$\textcolor{aqua}{ \text{常数} }$和$\textcolor{magenta}{ \text{变量} }$. 这两种都是我们能直接数学使用的。&lt;/p&gt;
&lt;p&gt;等会，高度$\textcolor{aqua}{ h_{0} }$好像还没有，不过给了总体积可以算，此处使用柱壳法&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;$$
\begin{align*}
V=&amp;amp;\int_{0}^r 2\pi xy,dx=\pi \int_{0}^r x^3,dx \
=&amp;amp;\frac{\pi}{4}r^4=64\pi \
r=&amp;amp;4 \
h_{0}=&amp;amp;\frac{1}{2}r^2=8
\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;计算总功&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;$$
\begin{align*}
W=&amp;amp;\int_{0}^{h_{0}} g(h_{0}-y)\rho\pi 2y,dy \
=&amp;amp;\frac{1}{3}g\rho\pi h_0^3 \
=&amp;amp;\frac{512}{3}\pi\cdot 10^4;(J)
\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;第二问，抽出$28\pi,\text{m}^3$的水。可以先算一下高度&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(2). 解:&lt;/p&gt;
&lt;p&gt;若抽出$28\pi,\text{m}^3$的水，剩余$64\pi-28\pi=36\pi,(\text{m}^3)$. 代入$V=\frac{\pi}{4}r^4=36\pi$可得$h_{1}=6,(\text{m}^3)$. 则所需的功&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
W=&amp;amp;\int_{h_{1}}^{h_{0}} g(h_{0}-y)\rho\pi 2y,dy \
=&amp;amp;2\pi\rho g \int_{6}^{8} (8y - y^2),dy \
=&amp;amp;2\pi\rho g \left[ \left(4\cdot 8^2 - \frac{8^3}{3}\right) - \left(4\cdot 6^2 - \frac{6^3}{3}\right) \right] \
=&amp;amp;2 \times \frac{40}{3} \times \pi \times 1000 \times 10 \
=&amp;amp; \frac{8}{3}\pi \cdot 10^5;(J)
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;:::caution
注意: 不能用$\frac{1}{3}g\rho\pi \cdot 8^3$减去$\frac{1}{3}g\rho\pi \cdot 6^3$。
:::&lt;/p&gt;
</content:encoded></item><item><title>【学习笔记】数学笔记其五 · 一元函数积分学【上】</title><link>https://blog.emumu.xyz/posts/2026-07-23-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-07-23-00/</guid><description>高数第三期, 最恐怖的一集</description><pubDate>Sun, 26 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;如果你是首次进入我的新数学笔记系列, 请先&lt;a href=&quot;/posts/2026-07-09-00/&quot;&gt;点此阅读预告回&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;如果说极限是纯计算技巧、微分学是纯理论技巧, 那积分学就是集两者之长: 它会考比极限更难的计算, 公式、技巧又多得多；又要考理论, 包括定义、中值、$\varepsilon-\delta$, 和微分不相上下。&lt;/p&gt;
&lt;p&gt;积分我分为四类题型:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;计算&lt;/strong&gt;。最大的领域, 包括简单的不定积分和定积分计算.涉及大量方法和公式.高数最长的河。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分析&lt;/strong&gt;。比如比大小和单调等.在基本计算的基础上进行分析, 可拉可神。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;中值&lt;/strong&gt;。堪比微分, 下期会见。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;应用&lt;/strong&gt;。包括旋转体和我们数二独有的物理题, 下期见。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;本期（上）只说计算。计算是后面一切的根本。虽然知识体系上可能有点像极限那期。这期是我做过积分方法里最完整，也是我认为讲述最结构化(至今)的一期。&lt;/p&gt;
&lt;h2&gt;基础与基本性质&lt;/h2&gt;
&lt;h3&gt;因式分解与分式裂项&lt;/h3&gt;
&lt;p&gt;对于被积函数为有理分式（多项式之比）的情形, 基本策略是先判断是否为假分式(即分子次数&amp;gt;=分母次数)，对假分式进行&lt;a href=&quot;https://www.shuxuele.com/algebra/polynomials-division-long.html&quot;&gt;&lt;strong&gt;多项式长除法&lt;/strong&gt;&lt;/a&gt;:spoiler[考虑到在初中教纲删掉之后很多大学生甚至没正经学过，故贴一个站外教程在这里], 将其拆为多项式部分+真分式部分；多项式部分直接积分, 真分式则使用裂项法.&lt;/p&gt;
&lt;p&gt;$$
\frac{P(x)}{Q(x)} = S(x) + \frac{R(x)}{Q(x)}
$$&lt;/p&gt;
&lt;p&gt;裂项法的本质是将一个复杂分式分解为若干分母为一次或二次不可约多项式的简单分式之和，每一单项均可通过基本积分公式或简单的换元完成，这个过程是机械的，也证明多项式的可积性。具体方法不在此细说，B站可以轻松找到一大把教程。&lt;/p&gt;
&lt;p&gt;其中, 我要特别强调&lt;strong&gt;平方差公式&lt;/strong&gt;$a^2 - b^2 = (a-b)(a+b)$是最高频的工具.大量积分的分式在配方或换元后会暴露形态各异的平方差结构, 从而得以裂项简化.辨识并主动往平方差上靠，尽管看起来可能生硬，但往往都是正确的. :spoiler[注意根号下的除外，那种情况下很可能还是三角代换更好] &lt;em&gt;[27330: 98, 100]&lt;/em&gt; 如:&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
I &amp;amp;= \int \frac{x^4}{x^2+1}\arctan x , dx \
&amp;amp;= \int \left( x^2 - 1 + \frac{1}{x^2+1} \right)\arctan x , dx \
&amp;amp;= \int (x^2 - 1)\arctan x , dx + \int \frac{\arctan x}{x^2+1} , dx. \
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;前项分部、后项凑微分不提。&lt;/p&gt;
&lt;h3&gt;夹逼准则&lt;/h3&gt;
&lt;p&gt;夹逼准则基本绑定于&lt;strong&gt;极限与积分的混合式&lt;/strong&gt;题型, 被积函数中含有$n$这样的离散参数, 极限难以直接求得. 典型模式是求$\lim_{n\to\infty} \int_{a}^{b} f_n(x), dx$. &lt;em&gt;[27330: 123, 126]&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;与极限篇相同，主要矛盾都在于上下界的构造.常见的构造思路有&lt;strong&gt;利用函数单调性&lt;/strong&gt;找到区间上的最大值和最小值、利用&lt;strong&gt;基本不等式&lt;/strong&gt;(部分可由泰勒推得)如$x - \frac{x^3}{6} &amp;lt; \sin x &amp;lt; x \quad (x&amp;gt;0)$等放大或缩小、将复杂函数&lt;strong&gt;瞪眼法替换为更简单的函数&lt;/strong&gt;, 例如将$\sqrt{1+x}$在$x\ge0$时放大为$1+x&amp;gt;\sqrt{ 1+x }$.&lt;/p&gt;
&lt;h3&gt;对称区间与奇偶性&lt;/h3&gt;
&lt;p&gt;对于对称区间$[-a,  a]$上的定积分, 奇偶性可以直接给出巨大的简化.设$f(x)$在$[-a, a]$上可积:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;若$f(x)$为&lt;strong&gt;偶函数&lt;/strong&gt;（$f(-x) = f(x)$）, 则$\int_{-a}^{a} f(x), dx = 2\int_{0}^{a} f(x), dx$；&lt;/li&gt;
&lt;li&gt;若$f(x)$为&lt;strong&gt;奇函数&lt;/strong&gt;（$f(-x) = -f(x)$）, 则$\int_{-a}^{a} f(x), dx = 0$.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当积分限&lt;strong&gt;包含正负对称区间&lt;/strong&gt;时, 应&lt;strong&gt;先花几秒钟判定奇偶性&lt;/strong&gt;, 可能直接得到零或简化积分区间, 省去大量运算.&lt;/p&gt;
&lt;p&gt;注意一个常见的变体是对非对称区间上具有某种平移对称的函数. 例如$\int_{0}^{2a} f(x), dx$不是对称区间, 但若$f(x)$满足$f(2a-x) = -f(x)$（关于$x=a$奇对称）, 则通过换元$t = 2a - x$可以导出$\int_{0}^{2a} f(x), dx = 0$. 显然这种偏移对称性比显然的奇偶性更好做文章. &lt;em&gt;[27330: 100]&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;积分的几何意义&lt;/h3&gt;
&lt;p&gt;定积分$\int_a^b f(x), dx$最基本的几何意义是曲线$y = f(x)$与$x$轴在$[a, b]$上所围的有向面积, $x$轴上方为正, 下方为负.这意味着我们可以将某些定积分的计算&lt;strong&gt;转化为对几何图形面积的直接观察&lt;/strong&gt;, 省去繁琐的代数运算.&lt;/p&gt;
&lt;p&gt;最经典的情形是&lt;strong&gt;半圆面积&lt;/strong&gt;. 被积函数中含有$\sqrt{r^2 - x^2}$时, 显然观察到这是一个半径为$r$的半圆, 于是$\int_{-r}^{r} \sqrt{r^2 - x^2}, dx = \frac{1}{2}\pi r^2$可以直接写出, 无需三角换元. 类似地, $\sqrt{r^2 - (x-h)^2}$对应圆心平移到$(h, 0)$的上半圆.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;Pasted%20image%2020260726010846.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;此外, 一些更隐蔽的几何意义也值得留意.例如$\int_0^a \sqrt{1 + [f&apos;(x)]^2}, dx$是曲线弧长（见下期应用部分）, $\int_a^b x, dy$与坐标轴围成的面积有时更方便计算.&lt;/p&gt;
&lt;p&gt;对于 &lt;em&gt;[27330: 123]&lt;/em&gt; , 如果你发现了这就是最大值函数($x$和$1-x$的无穷范数), 那么可以从几何视角快速得到直觉, 从而快速想到分段处理.&lt;/p&gt;
&lt;p&gt;不过拿分最好还是老实夹逼.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;Pasted%20image%2020260726011357.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;不定积分的奇点处理&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;这是求积分的一个基本原则&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;对于&lt;strong&gt;连续不可微&lt;/strong&gt;奇点，函数在一点不可微，也就不能积分法则. 比如$f(x)=|x|$. 很自然地，我们能想到分段处理，这没有错.&lt;/p&gt;
&lt;p&gt;但是，对于&lt;strong&gt;连续&lt;/strong&gt;不可微的点，两段必须一个取相同的常数. 因为积分天然是连续的. 这要求我们&lt;strong&gt;用常数拼接出连续性&lt;/strong&gt;. 读者尝试$\int\mathrm{max}{1,x^2} dx$. 答案::spoiler[函数三段的常数逐个差2/3]&lt;/p&gt;
&lt;p&gt;对于&lt;strong&gt;任意间断点&lt;/strong&gt;，两侧则可以取得不同的常数$C$. 所以严格来说:&lt;/p&gt;
&lt;p&gt;$$
\int \frac{1}{x} , dx =
\begin{cases}
\ln(-x) + C_1, &amp;amp; x &amp;lt; 0 \[6pt]
\ln(x) + C_2, &amp;amp; x &amp;gt; 0
\end{cases}
$$&lt;/p&gt;
&lt;p&gt;&lt;em&gt;[27330: 109, 110]&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;凑微分和换元法&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;这是求积分的基本方法之一&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;我注意力涣散，凑微分凑不出来怎么办？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;凑微分的原理是&lt;strong&gt;复合函数求导的逆运算&lt;/strong&gt;。它与变量代换法（无论是$x=\psi(t)$还是$u=\varphi (x)$）本质都完全相同。&lt;/p&gt;
&lt;p&gt;凑微分要求: 若被积函数具有$f(\varphi(x)) \cdot \varphi&apos;(x)$的形式, 则令$u = \varphi(x)$, 由于$\varphi&apos;(x)dx = du$, 积分变为$\int f(u), du$. 至于怎么看出来这个$\varphi$和$\varphi&apos;$你别管。&lt;/p&gt;
&lt;p&gt;变量代换法要求: &lt;strong&gt;显式地&lt;/strong&gt;将积分转化为关于$t$的积分.我们用例子$\int \frac{\sin x \cos x}{1+\sin^2 x} , dx$展示:&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
\int \frac{\sin x \cos x}{1 + \sin^2 x} , dx
&amp;amp;= \frac12 \int \frac{2 \sin x \cos x}{1 + \sin^2 x} , dx \
&amp;amp;= \frac12 \int \frac{d(1 + \sin^2 x)}{1 + \sin^2 x} \
&amp;amp;= \frac12 \ln(1 + \sin^2 x) + C.
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
\int \frac{\sin x \cos x}{1 + \sin^2 x} , dx
&amp;amp;= \int \frac{\frac{1}{2} dt}{t} \qquad \begin{cases}
t = 1 + \sin^2 x, \
dt = 2\sin x \cos x , dx, \
\end{cases} \
&amp;amp;= \frac{1}{2} \int \frac{1}{t} , dt \
&amp;amp;= \frac{1}{2} \ln|t| + C \
&amp;amp;= \frac{1}{2} \ln(1 + \sin^2 x) + C.
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;&lt;em&gt;[27330: 95, 101]&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;区间再现&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;这是一种被换元法知识点覆盖，但过于常见的考点&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在上下界$\int_{a}^b$的条件做代换$x = a + b - t$. 在此代换下:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;积分限$a$与$b$互换（导出负号）
-$dx = -dt$（导出负号，抵消）&lt;/li&gt;
&lt;li&gt;被积函数$f(x)$净变为$f(a+b-x)$的变换.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;即令$t$从$b$到$a$反着跑一遍原区间. 于是我们得到关键等式:&lt;/p&gt;
&lt;p&gt;$$
\int_a^b f(x), dx = \int_a^b f(a+b-x), dx
$$&lt;/p&gt;
&lt;p&gt;一方面, 我们大概率经常会见到题目中的$\int_{0}^x f(x-t) dt$, 像这种白骨精我们可以不用换元，直接化成$\int_{0}^x f(t)dt$就行了。&lt;/p&gt;
&lt;p&gt;另一方面, 这个等式的威力在于将原积分$I$与变换后的积分相加, 常常能凑出常数或简化形式$2I = \int_a^b [f(x) + f(a+b-x)], dx$从而求出$I$. 或者通过其他方式运算一番常常有所帮助. 这类题型辨识度较高, 一旦认出思路非常确定.&lt;/p&gt;
&lt;p&gt;区间再现最经典的应用之一是证明$\int_0^{\pi/2} \sin^n x, dx = \int_0^{\pi/2} \cos^n x, dx$, 读者自证不难.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;[27330: 106]&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;不得不提的是，在特定的上下界$0,\infty$上还有倒代换$x=\frac{1}{t}$, 也能起到很像区间再现的作用:&lt;/p&gt;
&lt;p&gt;$$
\int_0^\infty f(x),dx = \int_0^\infty \frac{1}{x^2} f\left(\frac{1}{x}\right),dx
$$&lt;/p&gt;
&lt;p&gt;另外此处我特别提醒一下:&lt;/p&gt;
&lt;p&gt;$$
\arctan x + \arctan \frac{1}{x} =
\begin{cases}
\dfrac{\pi}{2}, &amp;amp; x &amp;gt; 0, \[8pt]
-\dfrac{\pi}{2}, &amp;amp; x &amp;lt; 0.
\end{cases}
$$&lt;/p&gt;
&lt;h3&gt;三角换元&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;这是一种十分常见的换元方法，将根式化为三角函数&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;当积分式里出现$\sqrt{a^2 \pm x^2}$或$\sqrt{x^2 \pm a^2}$时, 九九成就得三角换元了.&lt;/p&gt;
&lt;p&gt;基本思想是: 利用三角恒等式$\sin^2\theta + \cos^2\theta = 1$及其衍生形式$1 + \tan^2\theta = \sec^2\theta$和$\sec^2\theta - 1 = \tan^2\theta$, 消去平方加减结构中的根号.具体来说:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;原式&lt;/th&gt;
&lt;th&gt;设&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;$\sqrt{a^2 - x^2}=a\cos t$&lt;/td&gt;
&lt;td&gt;$x = a\sin t, ;dx=a\cos t$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\sqrt{a^2 + x^2}=a\sec t$&lt;/td&gt;
&lt;td&gt;$x = a\tan t, ;dx=a\sec^2 t$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\sqrt{x^2 - a^2}=a\tan t$&lt;/td&gt;
&lt;td&gt;$x = a\sec t, ;dx=a\tan t\sec t$&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;回代时你会发现$\cos t, \tan t$, 但你手里只有$x = a\sin t$.此时你就需要画一个直角三角形, $t$作为一个锐角, 写出各边的比值, 从而将关于$t$的三角函数转化为$x$的表达式, 如$\cos t=\frac{\sqrt{ a^{2}-x^{2} }}{a}$.忘说了, 我其实建议使用$\theta$.&lt;/p&gt;
&lt;p&gt;此外, $\sqrt{ax^2 + bx + c}$型可以通过配方化为$\sqrt{(\text{线性式})^2 \pm m^2}$再进行换元如$ax+b=\sin t$.&lt;/p&gt;
&lt;h3&gt;万能代换&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;这是一种十分常见的换元方法，将三角函数化为有理函数&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;凡是三角函数有理式且其他方法均不便时, 可用&lt;strong&gt;万能代换&lt;/strong&gt;将其转化为$t$的有理函数积分.&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
t &amp;amp;= \tan\frac{x}{2} \
dx &amp;amp;= \frac{2}{1 + t^2},dt \
\sin x &amp;amp;= \frac{2t}{1 + t^2} \
\cos x &amp;amp;= \frac{1 - t^2}{1 + t^2} \
\tan x &amp;amp;= \frac{2t}{1 - t^2}
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;注意万能代换虽然万能，但一般你都走到这一步了，往往分母次数也都很高，计算量巨大。而且最重要的是，它的基本逻辑是&lt;strong&gt;将三角函数函数转化为有理函数&lt;/strong&gt;。如果你是从有理函数转化过来又没做任何进一步推导，很可能万能代换回去是一模一样的。一方面它可以作为最终手段使用，但另一方面，一些看似简单但无从下手的也可以尝试用万能代换无脑解决。&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
\int \csc x , dx
&amp;amp;= \int \frac{1}{\sin x} , dx
\qquad \begin{cases}
t = \tan\frac{x}{2} \
dx = \frac{2}{1+t^2},dt,\
\sin x = \frac{2t}{1+t^2}
\end{cases} \
&amp;amp;= \int \frac{1+t^2}{2t} \cdot \frac{2}{1+t^2} , dt \
&amp;amp;= \int \frac{1}{t} , dt = \ln|t| + C \
&amp;amp;= \ln\left|\tan\frac{x}{2}\right| + C.
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;&amp;lt;details&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;summary&amp;gt;关于csc这个例子……&amp;lt;/summary&amp;gt;&lt;/p&gt;
&lt;p&gt;这里有另一种做法，一般来说这才是正宗做法&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
\int \frac{dx}{\sin x}
&amp;amp;= \int \csc x , dx \
&amp;amp;= \int \frac{\csc x (\csc x - \cot x)}{\csc x - \cot x} , dx \
&amp;amp;= \int \frac{\csc^2 x - \csc x \cot x}{\csc x - \cot x} , dx \
&amp;amp;= \int \frac{1}{\csc x - \cot x} , d(\csc x - \cot x) \
&amp;amp;= \ln|\csc x - \cot x| + C.
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;答案是等价的。&lt;/p&gt;
&lt;p&gt;&amp;lt;/details&amp;gt;&lt;/p&gt;
&lt;h3&gt;双曲换元&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;这是一种少见的换元方法，作为高阶秒杀招使用&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;双曲函数$\sinh x = \frac{e^x - e^{-x}}{2}$、$\cosh x = \frac{e^x + e^{-x}}{2}$、$\tanh x = \frac{\sinh x}{\cosh x}$满足与三角函数平行但略有不同的恒等式.最核心的是$\cosh^2 x - \sinh^2 x = 1$（注意是减号而不是加号）, 其衍生形式为$\sinh^2 x + 1 = \cosh^2 x$和$1 - \tanh^2 x = \frac{1}{\cosh^2 x}$.与三角恒等式相比, 双曲恒等式中正负号的位置不同, 这恰好使其在另一种积分场景下成为自然之选.&lt;/p&gt;
&lt;p&gt;在三角换元中, 我们用$\sin t$消$\sqrt{a^2 - x^2}$, 用$\tan t$消$\sqrt{a^2 + x^2}$.双曲换元则提供了另一种可能性: 令$x = a\sinh t$消$\sqrt{a^2 + x^2}$（此时$\sqrt{a^2 + a^2\sinh^2 t} = a\cosh t$）, 或令$x = a\cosh t$消$\sqrt{x^2 - a^2}$（$\sqrt{a^2\cosh^2 t - a^2} = a\sinh t$）.与三角换元相比, 双曲换元的导数和回代均更为简单直接（$\sinh&apos; = \cosh$, $\cosh&apos; = \sinh$, 没有负号干扰）, 但&lt;strong&gt;代价是需要熟悉双曲函数的微积分公式&lt;/strong&gt;. 这些公式和普通三角比绝大多数都只加了一两个负号, 但要熟练使用也够你喝一壶的.&lt;/p&gt;
&lt;p&gt;实际考试中, 双曲换元并非必需, 更多是三角换元的补充手段——对于某些特定的根式, 双曲可以硬吃 &lt;em&gt;[27330: 93]&lt;/em&gt;, 但有时代价反而比三角更大 &lt;em&gt;[27330: 101]&lt;/em&gt; (毕竟绝大多数题目是设计给一般考生准备的). 判断标准通常是看换元后的积分是否更简单, 任选其一即可.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;前往 &lt;a href=&quot;/posts/2026-03-19-00/#%E5%8F%8C%E6%9B%B2%E5%87%BD%E6%95%B0&quot;&gt;【学习笔记】数学笔记其二 · 三角函数#双曲函数&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;消耗三角函数&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;这属于应有的基本计算能力&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;消耗三角函数, 指的是对形如$\int \sin^m x \cos^n x, dx$的被积函数进行降次或消去.这一部分其实等同于三角函数函数的积分方法.当我们已经将扩展三角函数和$\tan$转为倒数之后, 我们可以往下看.&lt;/p&gt;
&lt;h4&gt;最常见的sin^m x cos ^n x&lt;/h4&gt;
&lt;p&gt;当$m, n$中至少有一个为奇数时, 可以抽出来一个去凑微分.例如$\int \sin^2x \cos^3x, dx$, 剥出一个$\cos x$与$dx$组合成$d(\sin x)$, 剩余$\cos$通过简单变换转为$\cos^2x = 1 - \sin^2 x$, 由此转化为$\sin x$的多项式.对称地, 若$\sin x$是奇数幂, 则剥出$\sin x$凑成$-d(\cos x)$.&lt;/p&gt;
&lt;p&gt;当$m, n$均为正偶数时, 可以通过降幂公式反复降次:&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
\sin^2x &amp;amp;= \frac{1 - \cos 2x}{2} \
\cos^2x &amp;amp;= \frac{1 + \cos 2x}{2}
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;每次应用都将次数减半&lt;strong&gt;并引入倍角&lt;/strong&gt;, 最终将化为若干$\sin kx$或$\cos kx$的线性组合, 逐项积分即可.&lt;/p&gt;
&lt;p&gt;那么如果这是换元后的结果(如$x=\sin t$)，结果出现的$\sin 2t$和$\cos 2t$如何回代呢？&lt;strong&gt;不要试图强解&lt;/strong&gt;$\sin 2t = \sin(2\arcsin x)$. 原则上我们只需要将它们还原回$\sin t$和$\cos t$表示的形式。比如$\cos 2t$, 用升幂公式反回去: $\cos 2t=1 - 2\sin^2 t$.$\sin 2t$则需要$\sin 2t=2\sin t\cos t$. 总的来说还是高中数学.&lt;/p&gt;
&lt;h4&gt;tanx和secx主导时&lt;/h4&gt;
&lt;p&gt;对于$\tan^n x$或$\sec^n x$, 通常利用以及两组凑微分关系, 逐步降次到能积为止.&lt;/p&gt;
&lt;p&gt;大部分情况会使用凑微分结合$1 + \tan^2x = \sec^2x$互转，两组关系如下:&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
\sec x \tan x, dx &amp;amp;= d(\sec x) \
\sec^2x, dx &amp;amp;= d(\tan x)
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;又有两个最好背下来的基本公式&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
\int \tan x , dx &amp;amp;= \ln|\sec x| + C \
\int \sec x , dx &amp;amp;= \ln|\sec x + \tan x| + C
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;就基本可以做了。例如有:&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
\int \sec^3 x , dx&amp;amp;= \int \underbrace{\sec x}&lt;em&gt;{u} \cdot \underbrace{\sec^2 x , dx}&lt;/em&gt;{dv} \
&amp;amp;= \underbrace{\sec x}&lt;em&gt;{u} \cdot \underbrace{\tan x}&lt;/em&gt;{v}&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;\int \underbrace{\tan x}&lt;em&gt;{v} \cdot \underbrace{(\sec x \tan x , dx)}&lt;/em&gt;{du} \
&amp;amp;= \sec x \tan x - \int \sec x \tan^2 x , dx \
&amp;amp;= \sec x \tan x - \int \sec x \underbrace{(\sec^2 x - 1)}&lt;em&gt;{\tan^2 x} , dx \
&amp;amp;= \sec x \tan x - \int \sec^3 x , dx + \int \sec x , dx \
&amp;amp;= \sec x \tan x - \underbrace{\int \sec^3 x , dx}&lt;/em&gt;{I} + \int \sec x , dx \
2\int \sec^3 x , dx &amp;amp;= \sec x \tan x + \int \sec x , dx \
&amp;amp;= \sec x \tan x + \ln|\sec x + \tan x| + C_1 \
\int \sec^3 x , dx &amp;amp;= \frac{1}{2}\sec x \tan x + \frac{1}{2}\ln|\sec x + \tan x| + C
\end{align*}
$$&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;最吃时间的部分来了。做得多的同学可以开始背常见结论了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;华里士公式&lt;/h4&gt;
&lt;p&gt;华里士公式（Wallis formula）又称点火公式, 处理的是区间$[0, \frac{\pi}{2}]$上$\sin^n x$或$\cos^n x$的定积分. 结论如下:&lt;/p&gt;
&lt;p&gt;$$
\int_0^{\pi/2} \sin^n x, dx = \int_0^{\pi/2} \cos^n x, dx =
\begin{cases}
\frac{(n-1)!!}{n!!} \cdot \frac{\pi}{2},  &amp;amp; n\text{ 为偶数}\[6pt]
\frac{(n-1)!!}{n!!},  &amp;amp; n\text{ 为奇数}
\end{cases}
$$&lt;/p&gt;
&lt;p&gt;结合之前的众多方法后, 有时会残留一些阶很高的$\sin$和$\cos$被恶心, 如果是不定积分一般要用各种降阶互换凑微分, 但定积分的话, 我们可以通过移动区间、奇偶性等物理手段移动到$0,\frac{\pi}{2}$区间内, 然后秒杀.&lt;/p&gt;
&lt;p&gt;华里士公式本质上来自分部积分法: $\int_0^{\pi/2} \sin^n x, dx = \frac{n-1}{n} \int_0^{\pi/2} \sin^{n-2} x, dx$, 递推到底即得到上述连乘积.&lt;/p&gt;
&lt;h2&gt;分部积分法&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;这是求积分的基本方法之一&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;分部积分法做法本身简单不提。我草纸上一般会这么写:&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
&amp;amp;=\int \textcolor{aqua}{ \ln x } , \textcolor{orange}{ dx } \qquad \begin{cases}
\textcolor{aqua}{ u = \ln x },&amp;amp; \textcolor{orange}{ dv = dx } \
\textcolor{cornflowerblue}{ du = \frac{1}{x} dx },&amp;amp; \textcolor{yellow}{ v = x }
\end{cases} \
&amp;amp;= uv - \int v , du \
&amp;amp;= x \ln x - \int x \cdot \frac{1}{x} , dx \
&amp;amp;= x \ln x - \int 1 , dx \
&amp;amp;= x \ln x - x + C.
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;分部积分法本身来源于乘积求导$(uv)&apos; = u&apos;v + uv&apos;$的两边积分与移项, 得到$\int u, dv = uv - \int v, du$. 我们的关注点在于&lt;strong&gt;如何选择合适的&lt;/strong&gt;$u$和$v$.&lt;/p&gt;
&lt;p&gt;有一条广为流传的经验法则叫&lt;strong&gt;反对幂指三&lt;/strong&gt;(反三角&amp;gt;对数&amp;gt;多项式&amp;gt;指数&amp;gt;三角)，即越靠前的函数越倾向选为$u$.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;对数(如$\ln x$)和反三角(如$\arctan x$)的导数都是代数函数, 变为$du$后它们会凭空消失。净降低复杂度, 好.&lt;/li&gt;
&lt;li&gt;多项式越导越小. 只要作为另一部分的$dv$还能积, 就可以选择多项式. 例如$\int x e^x dx$选$u = x$.&lt;/li&gt;
&lt;li&gt;指数函数($e^{x}$)和三角函数的积分完全不会降低难度.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;循环移项&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;这是一种在分部积分法之上，常见的不易察觉的终结式&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;当对某些积分使用分部积分法时, 会出现情况如连续两次分部之后, 新积分恰好等于原来的积分（或与之成比例）, 此时方程中出现了&quot;积分 = 表达式 - 积分&quot;的形式, 将其视为未知数移到等号同侧, 即可解出积分值. 一般我们设原积分为$I$便于后续计算.&lt;/p&gt;
&lt;p&gt;刚才说过反对幂指三法则中指数函数和三角函数作$u$无法简化, 因为求一次或两次导之后还是它们自身. 如果没有对数或者反三角, 我们就可以利用这种模式构造循环移项, 如$\int e^{x}\sin x, dx$两次分部后$\sin$又变回$\sin$.&lt;/p&gt;
&lt;p&gt;定积分同样适用, 将$I$视为定积分的值（一个数）, 分部积分时上下限照常代入, 解出的方程直接给出$I$的数值, 不再涉及$+C$.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;[27330: 96]&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;升降幂积分&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;这是一种被分部积分法知识点覆盖，但过于常见又不易察觉的方法&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;升降幂这个名字是我自己起的。这种技巧似乎没有统一正式常用的名字，但这个方法是实实在在非常常用。&lt;/p&gt;
&lt;p&gt;这个方法我在第一个数学笔记里说过，此处完整重新介绍一番:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;升降幂积分其实就是分部积分法的两种特殊形式，对应$\textcolor{orange}{ dv=dx }$和$\textcolor{aqua}{ u=x }$的情况。&lt;/p&gt;
&lt;p&gt;**升幂: ** 适用于$f(x)$积不动但导数很简单的函数（如$\ln x, \arctan x$）.&lt;/p&gt;
&lt;p&gt;$$
\int \textcolor{aqua}{ f(x) } ,\textcolor{orange}{ \mathrm{d}x } = \textcolor{yellow}{ x } \textcolor{aqua}{ f(x) } - \int \textcolor{yellow}{ x } \textcolor{cornflowerblue}{ f&apos;(x),\mathrm{d}x }
$$&lt;/p&gt;
&lt;p&gt;**降幂: ** 适用于$f(x)$积得动, 但前面的$x$很碍事的情况（如$x \cos x$）.&lt;/p&gt;
&lt;p&gt;$$
\int \textcolor{aqua}{ x } \textcolor{orange}{ f(x) ,\mathrm{d}x } = \textcolor{aqua}{ x } \textcolor{yellow}{ F(x) } - \int \textcolor{yellow}{ F(x) } \textcolor{cornflowerblue}{ ,\mathrm{d}x } \quad (\text{其中 } F&apos;(x) = f(x))
$$&lt;/p&gt;
&lt;p&gt;这些特殊形式在$f(x)$看起来很整体而坚固的时候用有奇效，可惜我经常想不起来用分部。你一定要想起来用啊！&lt;/p&gt;
&lt;h3&gt;伽马函数&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;这是一种被分部积分法知识点覆盖，但略常见的考点，作为快捷方法使用&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;伽马函数$\Gamma(z)$是阶乘向实数和复数域的推广. 其最常用的积分定义为$\Gamma(z) = \int_0^\infty t^{z-1} e^{-t},dt$, 定义域为$\operatorname{Re}(z) &amp;gt; 0$. &lt;strong&gt;复数的定义域和一些乱七八糟的其实并不重要&lt;/strong&gt;, 我们主要观察非负整数$n$下, 有:&lt;/p&gt;
&lt;p&gt;$$
\int_0^\infty x^{n} e^{-x},dx = \Gamma(n+1) = n!
$$&lt;/p&gt;
&lt;p&gt;这是它被称为&quot;广义阶乘&quot;的原因. 再有递推关系为 $\Gamma(z+1) = z\Gamma(z)$, 分部积分一步可得.&lt;/p&gt;
&lt;p&gt;对于我们今天说的积分计算而言, 伽马函数的最大价值在于它能直接吞掉形如$\int_0^\infty x^a e^{-bx^c},dx$的积分. 通过换元$t = bx^c$, 这类积分可以统一化为伽马函数的标准形式.&lt;/p&gt;
&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;我们当年算$\int_0^\infty x^{n} e^{-x},dx$可是要$n$次分部积分的，你告诉我等于$n$ ！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;除了整数, 另一个极为重要的特殊值是$\Gamma(\frac{1}{2}) = \sqrt{\pi}$. 本质上，这就是高斯积分 $\int_{-\infty}^\infty e^{-x^2}dx = \sqrt{\pi}$ 的另一种写法, 然后通过递推式我们又可以得知$\Gamma(\frac{3}{2})$等值.&lt;/p&gt;
&lt;p&gt;考场上, 如果题目中出现 $\int_0^\infty x^n e^{-ax},dx$ 且$n$较大, 直接用伽马函数 $\frac{n!}{a^{n+1}}$ 写出答案即可, 无需暴露伽马符号.&lt;/p&gt;
&lt;h2&gt;定积分的极限求和定义&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;这是求&lt;strong&gt;极限&lt;/strong&gt;的基本方法之一&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;定积分的定义本身就植根于极限: 将区间$[a, b]$作$n$等分, 每份宽$\Delta x = \frac{b-a}{n}$, 在第$i$个小区间上取代表点$\xi_i$（通常取左端点、右端点或中点）, 作黎曼和$\sum_{i=1}^{n} f(\xi_i)\Delta x$, 当$n \to \infty$时这些和的极限就是$\int_a^b f(x), dx$. 反过来, 许多以极限形式出现的求和问题, 可以通过逆用这一定义转化为定积分求解.&lt;/p&gt;
&lt;p&gt;一般来说, 对于一个看起来可以改成积分的&lt;strong&gt;极限求和&lt;/strong&gt;题, 有步骤:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;将原式写成$\lim_{ n \to \infty }\frac{1}{n}\sum_{k=0}^n \cdot f\left(\frac{k}{n}, \frac{1}{n}\right)$, 即提取一个$\frac{1}{n}$因子, 其余部分用$\frac{k}{n}$和$\frac{1}{n}$表示.
其中, $\frac{1}{n}$用于定积分本身定义, $\frac{k}{n}$视为, 且剩余的$\frac{1}{n}$可以直接极限求得$0$.&lt;/li&gt;
&lt;li&gt;令$x = \lim_{n\to\infty} \frac{k}{n}$（即$k/n \to x$），同时令$\frac{1}{n} \to 0$, 得到$f(x,0)$.&lt;/li&gt;
&lt;li&gt;于是极限为$\int_0^1 f(x,0),dx$.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;例如:&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
x_n &amp;amp;= \frac{1}{n^2} \sum_{k=1}^{n} \sqrt{4n^2 - (2k-1)(2k)} \
&amp;amp;= \frac{1}{n} \sum_{k=1}^{n} 2\sqrt{1 - \frac{k^2}{n^2} + \frac{k}{2n^2}} \
\lim_{n\to\infty} x_n
&amp;amp;= \textcolor{yellow}{ \lim_{n\to\infty} } \textcolor{aqua}{ \frac{1}{n} } \textcolor{yellow}{ \sum_{k=1}^{n} } 2\sqrt{1 - \left(\textcolor{lime}{\frac{k}{n}}\right)^2 + \textcolor{gray}{\frac{1}{2n}\cdot\frac{k}{n}}} \
&amp;amp;= \textcolor{yellow}{ \int_0^1 } 2\sqrt{1 - \textcolor{lime}{ x }^2} , \textcolor{aqua}{ dx } \quad \left( \textcolor{gray}{ \frac{k}{2n^2} } \to 0 \right) \
&amp;amp;= 2 \cdot \frac{\pi}{4} = \frac{\pi}{2}.
\end{align*}
$$
特别注意，部分极限求和根本没法变换成$\lim_{ n \to \infty }\frac{1}{n}\sum_{k=0}^n \cdot f\left(\frac{k}{n}, \frac{1}{n}\right)$, 或者强行写成这样也完全没法算（毕竟之后要积分）。所以尝试不通的话不要死磕到底……可以去试试裂项相消.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;[27330: 102, 122]&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;莱布尼茨积分法则&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;这是求导数的基本方法之一&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;莱布尼茨积分法则（Leibniz integral rule）是处理积分式的求导的唯一指定工具。具体来说:&lt;/p&gt;
&lt;p&gt;$$
\frac{d}{dx} \int_{\varphi(x)}^{\psi(x)} f(t), dt = f(\psi(x)) \cdot \psi&apos;(x) - f(\varphi(x)) \cdot \varphi&apos;(x)
$$&lt;/p&gt;
&lt;p&gt;当上下限为常数和$x$时, 公式退化为最简单的逆运算:&lt;/p&gt;
&lt;p&gt;$$
\frac{d}{dx} \int_a^x f(t)dt=f(x)
$$&lt;/p&gt;
&lt;p&gt;&lt;em&gt;[27330: 107, 118]&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;完整的莱布尼茨积分法则&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;这是一种标答不会使用的高阶秒杀方法&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;当$f$与$x$无关时, 最后一项中$\frac{\partial}{\partial x} f(t,x)$为$0$, 显然积出来整体为$0$.&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
\frac{d}{dx}\int_{\textcolor{yellow}{ \varphi(x) }}^{\textcolor{magenta}{ \psi(x) }} \textcolor{aqua}{ f(t,x) },dt
=&amp;amp; \textcolor{fuchsia}{ f(\psi(x),x),\psi&apos;(x) } \
-&amp;amp; \textcolor{yellow}{ f(\varphi(x),x),\varphi&apos;(x) } \[6pt]
+&amp;amp; \textcolor{aqua}{ \int_{\varphi(x)}^{\psi(x)} \frac{\partial}{\partial x} f(t,x),dt }&lt;/p&gt;
&lt;p&gt;\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;选择题可以狠狠用(部分能秒)，大题并未见过标答使用，不建议直接用，建议能换元换元处理。实在没招了要用一定要写得标准，毕竟没说明确扣分，也没说明确给分，打小聪明历来都要看场合……&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;高斯积分&lt;/h2&gt;
&lt;p&gt;尽管不在考纲内, 高斯积分的极坐标路径展示了一种很诡异的通过二重积分找到出路计算定积分的方法. 这种超模的方法恐怕也只有这个例子能派上用场了.&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
I &amp;amp;= \int_{-\infty}^{+\infty} e^{-x^2} , dx, \
I^2 &amp;amp;= \left( \int_{-\infty}^{+\infty} e^{-x^2} , dx \right) \left( \int_{-\infty}^{+\infty} e^{-y^2} , dy \right) \
&amp;amp;= \int_{-\infty}^{+\infty} \int_{-\infty}^{+\infty} e^{-(x^2+y^2)} , dx,dy. \
&amp;amp;= \int_0^{2\pi} \int_0^{+\infty} e^{-r^2} , r , dr , d\theta \qquad \begin{cases}
x = r\cos\theta \
y = r\sin\theta \
dx,dy = r,dr,d\theta
\end{cases} \
&amp;amp;= \int_0^{2\pi} \left[ -\frac{1}{2} e^{-r^2} \right]_0^{+\infty} d\theta \
&amp;amp;= \int_0^{2\pi} \frac{1}{2} , d\theta \
&amp;amp;= \pi. \
I &amp;amp;= \sqrt{\pi}.\qquad s.t.\quad I &amp;gt; 0
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;我个人建议背下来这个过程, 首先理解它并不难, 其次高斯积分(更多的是其变体)经常作为一种不可初等积, 明摆着让你绕道的范例方程出现在各种题里. 这些变体大多可通过简单的线性换元从标准高斯积分推导出来. 例如$\int_{-\infty}^{\infty} e^{-ax^2} dx$令$t = \sqrt{a}x$即可；含$e^{-ax^2+bx}$的积分则先配平方化为$e^{-a(x - \frac{b}{2a})^2 + \frac{b^2}{4a}}$再平移积分变量.&lt;/p&gt;
&lt;p&gt;高斯积分不是必背公式, 它更多地作为一种选择题或者大题力大砖飞的无脑救命路径出现. &lt;em&gt;[27330: 124]&lt;/em&gt; (我当时看到答案有种救赎感, 那些秘秘变换鬼他妈能想到)&lt;/p&gt;
&lt;p&gt;&amp;lt;details&amp;gt;
&amp;lt;summary&amp;gt;想看的话 这里有一个更神的&amp;lt;/summary&amp;gt;&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
I &amp;amp;= \int_0^\infty \frac{\sin x}{x} , dx \
&amp;amp;= \int_0^\infty \sin x \left( \int_0^\infty e^{-xt} , dt \right) dx \
&amp;amp;= \int_0^\infty \int_0^\infty e^{-xt} \sin x , dt , dx \[6pt]
I &amp;amp;= \int_0^\infty \left( \int_0^\infty e^{-xt} \sin x , dx \right) dt. \
\int_0^\infty e^{-xt} \sin x , dx
&amp;amp;= \left[ -e^{-xt} \frac{t\sin x + \cos x}{t^2 + 1} \right]_{x=0}^{x \to \infty} \
&amp;amp;= 0 - \left( -\frac{1}{t^2+1} \right) \
&amp;amp;= \frac{1}{t^2+1}. \
I &amp;amp;= \int_0^\infty \frac{1}{t^2+1} , dt \
&amp;amp;= \left[ \arctan t \right]_0^\infty \
&amp;amp;= \frac{\pi}{2}
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;&amp;lt;/details&amp;gt;&lt;/p&gt;
&lt;h2&gt;不可初等积的函数一览&lt;/h2&gt;
&lt;p&gt;这里的不可初等积特指&lt;strong&gt;原函数不能用初等函数表示&lt;/strong&gt;, 即&lt;strong&gt;非初等积分&lt;/strong&gt;, 即不存在由幂函数、指数函数、对数函数、三角函数、反三角函数及其有限次四则运算和复合所构成的函数, 使其导数等于被积函数.&lt;/p&gt;
&lt;p&gt;注意这与定积分不存在（不可积）是不同的概念. 很多初等不可积的函数, 其定积分仍然存在且可通过数值方法或特殊函数表示.&lt;/p&gt;
&lt;p&gt;常见的初等不可积函数有:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;积分式$\int f(x), dx$&lt;/th&gt;
&lt;th&gt;简介(通通不用背，看个乐呵即可)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;$\int e^{-x^2} dx$&lt;/td&gt;
&lt;td&gt;误差函数$\operatorname{erf}(x)$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\int e^{x^2} dx$&lt;/td&gt;
&lt;td&gt;虚误差函数$\operatorname{erfi}(x)$, $\operatorname{erfi}(x) = -i\operatorname{erf}(ix)$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\int \frac{e^{-x}}{x} dx$&lt;/td&gt;
&lt;td&gt;指数积分$\operatorname{Ei}(x)$或$E_1(x)$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\int \frac{e^{x}}{x} dx$&lt;/td&gt;
&lt;td&gt;指数积分$\operatorname{Ei}(x)$, 上者的变体&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\int \frac{1}{\ln x} dx$&lt;/td&gt;
&lt;td&gt;对数积分$\operatorname{li}(x)$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\int \ln(\ln x) dx$&lt;/td&gt;
&lt;td&gt;可用对数积分$\operatorname{li}(x)$表示&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\int \frac{\sin x}{x} dx$&lt;/td&gt;
&lt;td&gt;正弦积分$\operatorname{Si}(x)$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\int \frac{\cos x}{x} dx$&lt;/td&gt;
&lt;td&gt;余弦积分$\operatorname{Ci}(x)$, 与$\operatorname{Si}(x)$成对出现&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\int \sin(x^2) dx$&lt;/td&gt;
&lt;td&gt;菲涅尔积分$S(x)$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\int \cos(x^2) dx$&lt;/td&gt;
&lt;td&gt;菲涅尔积分$C(x)$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\int R\big(x, \sqrt{ax^3+bx^2+cx+d}\big) dx$&lt;/td&gt;
&lt;td&gt;椭圆积分(第一/二/三类).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\int x^x dx$&lt;/td&gt;
&lt;td&gt;Sophomore&apos;s dream&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\int e^{e^x} dx$&lt;/td&gt;
&lt;td&gt;可化为指数积分$\operatorname{Ei}(e^x)$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\int \sin(\sin x) dx$&lt;/td&gt;
&lt;td&gt;雅可比-安古尔展开&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\int \cos(\sin x) dx$&lt;/td&gt;
&lt;td&gt;换成coscosx,sincosx也一样的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\int \sqrt{\cos x} dx$&lt;/td&gt;
&lt;td&gt;第二类椭圆积分。非初等（与$1/\sqrt{\cos x}$同类但不同阶）。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\int \frac{\sin x}{\ln x} dx$&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\int \frac{e^x}{\sin x} dx$&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;了解哪些函数积不出来的实用价值在于, 当你在考场上发现被积函数在这份清单上, 就该立刻回头审题, 很可能题目的本意不是让你直接积它, 而是要你用夹逼、互减、奇偶性、换元等间接手段处理它, 便于控制考试节奏, 避免无效劳动.&lt;/p&gt;
&lt;h2&gt;特别提醒&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;不定积分，要$+C$&lt;/p&gt;
&lt;p&gt;定积分换元，要换限&lt;/p&gt;
&lt;p&gt;变限积分求导，要乘以上下限的导&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>【学习笔记】数学笔记其四 · 一元函数微分学</title><link>https://blog.emumu.xyz/posts/2026-07-15-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-07-15-00/</guid><description>是高数第二期</description><pubDate>Wed, 15 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;如果你是首次进入我的新数学笔记系列，请先&lt;a href=&quot;/posts/2026-07-09-00/&quot;&gt;点此阅读预告回&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;这一章主题是微分。微分嘛，求导，求导谁不会，高中的东西。&lt;/p&gt;
&lt;p&gt;所以&lt;strong&gt;确实真的没什么题是纯求导的题&lt;/strong&gt;。全是概念，证明和一些乱七八糟的东西。&lt;/p&gt;
&lt;h2&gt;题型A: 连续性和可导性&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;导数&lt;/strong&gt;定义为
$$
f&apos;(x_0) = \lim_{\Delta x \to 0} \frac{f(x_0 + \Delta x) - f(x_0)}{\Delta x}
$$
这个定义式经常被各种考。在这章里这个公式的频率丝毫不亚于公式求导（高中用的那种）。因为我们常用的求导公式的大前提是函数是连续的。&lt;/p&gt;
&lt;p&gt;我们有经典函数
$$
f(x) =\begin{cases}
x^2 \sin \frac{1}{x},&amp;amp; (x\neq 0), \
0, &amp;amp;(x=0)&lt;br /&gt;
\end{cases}
$$
&lt;img src=&quot;x2sinx-1.png&quot; alt=&quot;该函数的图像。注意它在x=0处可导&quot; /&gt;
若求$x=0$处的导数，直接公式法得:
$$
f&apos;(x) = 2x \sin \frac{1}{x} + x^2 \cdot \cos \frac{1}{x} \cdot \left(-\frac{1}{x^2}\right) = 2x \sin \frac{1}{x} - \cos \frac{1}{x}
$$
显然$x\to0$时$\cos(\infty)$求不出。这时候使用定义则有:
$$
f&apos;(0) = \lim_{\Delta x \to 0} \frac{f(0 + \Delta x) - f(0)}{\Delta x} = \lim_{x \to 0} \frac{x^2 \sin \frac{1}{x} - 0}{x} = \lim_{x \to 0} x \sin \frac{1}{x}
$$
到这里已经说明了公式法的必要性。但为什么它“导数的极限不存在”但“导数存在”，我们留到下一章再说。先继续说这个导数定义式&lt;/p&gt;
&lt;p&gt;原导数定义隐含了$\Delta x$从$\Delta x\to 0^+$和$0^-$两侧极限相等的条件。如果两侧的极限不相等，我们就称&lt;strong&gt;函数在点$x_0$处“不可导”&lt;/strong&gt;。典型如$f(x)=\vert x\vert$, 零点左侧导数是-1，右侧导数是1，在原点就是直观的奇点。&lt;/p&gt;
&lt;p&gt;这个公式必须理解应用，因为实际应用时不仅要用这个，还要用它的各种变形。&lt;/p&gt;
&lt;h3&gt;定义式变形&lt;/h3&gt;
&lt;p&gt;作一点小巧思，当$x_0=0$、$f(x)$在$x=0$可导时:
$$
f&apos;(0) = \lim_{x \to 0} \frac{f(\sin x) - f(0)}{\tan x}
$$
也是成立的。不过&lt;strong&gt;和原导数定义相比，这需要保证当点可导&lt;/strong&gt;，即保证$\frac{f(\sin x) - f(0)}{\sin x}$的极限存在。$L=\lim_{x \to 0} \left[ \frac{f(\sin x) - f(0)}{\sin x} \cdot \frac{\sin x}{\tan x} \right]$才能倒推回定义。题中经常需要这么做来构造导数定义。&lt;/p&gt;
&lt;p&gt;但是:
$$
f&apos;(0) = \lim_{x \to 0} \frac{f(x^2) - f(0)}{x^2}
$$
&lt;strong&gt;不一定成立&lt;/strong&gt;。因为$x^2$永远大于等于0，无论$x$从左边还是右边来，$x^2$都只能从右侧趋近于0。这个极限如果存在，&lt;strong&gt;只能说明右导数$f&apos;_+(0)$存在&lt;/strong&gt;，根本无法保证左导数的存在。因此它不能定义$f&apos;(0)$。&lt;/p&gt;
&lt;p&gt;导数存在的一个充要条件是&lt;strong&gt;左右导数都存在且相等&lt;/strong&gt;。这一点上和连续很像，连续是&quot;左右极限存在且等于该点函数值&quot;。&lt;/p&gt;
&lt;h3&gt;27330:49/&amp;lt;u&amp;gt;120&amp;lt;/u&amp;gt;/★★★★☆&lt;/h3&gt;
&lt;p&gt;设$f(x)$是可导的偶函数，它在$x=0$的某邻域内满足
$$
f(1+x^3)-2f(1+\sin x^3)=x^3+o(x^3),
$$
求曲线$y=f(x)$在点$(-1,f(-1))$处的切线方程及法线方程。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;目标是求切线，就是要求$f(-1)$与$f&apos;(-1)$。&lt;/p&gt;
&lt;p&gt;我们看到题目等式似乎很适合凑出$f&apos;(1)$, 很不巧$f$还是偶函数，我们就可以转化为求$f(1)$与$f&apos;(1)$。&lt;/p&gt;
&lt;p&gt;已知等式在$x\to0$时有$f(1+x^3)$与$f(1+\sin x^3)$, 自然先令$x\to0$得$f(1)$；再将等式两边除以$x^3$, 通过加减$f(1)$凑出导数定义$\frac{f(1+\Delta)-f(1)}{\Delta}$, 并结合$\sin x^3\sim x^3;(x\to0)$求出$f&apos;(1)$。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;解&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;由可导必连续，对已知等式取$x\to0$的极限。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;$$
\begin{align*}
\lim_{x\to0}\bigl[f(1+x^3)-2f(1+\sin x^3)\bigr] &amp;amp;= \lim_{x\to0}\bigl[x^3+o(x^3)\bigr] \
f(1)-2f(1) &amp;amp;= 0 \
f(1) &amp;amp;= 0
\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;十分幸运地，分子$f(x_0+\Delta x) - f(x_0)$中的$f(x_0)$是$0$, 我们可以直接把它插进去。&lt;/p&gt;
&lt;p&gt;为求$f&apos;(1)$, 将等式两边同时除以$x^3$, 并向导数定义的形式变形。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;$$
\begin{align*}
\frac{f(1+x^3)-2f(1+\sin x^3)}{x^3} &amp;amp;= 1+o(1) \
\frac{f(1+x^3)-f(1)}{x^3}-2\frac{f(1+\sin x^3)-f(1)}{x^3} &amp;amp;= 1+o(1).
\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;第一个分式$\frac{f(1+x^3)-f(1)}{x^3}$的极限显然就是$f&apos;(1)$不提，第二个分式需凑出与$\sin x^3$的导数定义$\frac{\sin x^3}{x^3}$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;对上述等式取$x\to0$的极限:&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
\lim_{x\to0}\left(\frac{f(1+x^3)-f(1)}{x^3} - 2\cdot\frac{f(1+\sin x^3)-f(1)}{x^3}\right) &amp;amp;= 1 \&lt;/p&gt;
&lt;p&gt;\lim_{x\to0}
\left(\underbrace{ \frac{f(1+x^3)-f(1)}{x^3} }&lt;em&gt;{\to;f&apos;(1) } -
2\cdot\underbrace{ \frac{f(1+\sin x^3)-f(1)}{\sin x^3} }&lt;/em&gt;{ \to;f&apos;(1) }\cdot\underbrace{ \frac{\sin x^3}{x^3} }_{\to;1 }\right) &amp;amp;= 1 \&lt;/p&gt;
&lt;p&gt;f&apos;(1) - 2f&apos;(1) &amp;amp;= 1 \
f&apos;(1) &amp;amp;= -1.
\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;$f(1)$和$f&apos;(1)$都求完了。简单收尾&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;-$f$为偶函数，$f(-1)=f(1)=0$
-$f$可导，则$f&apos;$为奇函数，从而$f&apos;(-1)=-f&apos;(1)=1$。&lt;/p&gt;
&lt;p&gt;切线斜率$k_{\text{切}}=f&apos;(-1)=1$, 法线斜率$k_{\text{法}}=-1$。故有&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;切线方程: $y-0=1\cdot(x+1) ;\Longrightarrow; y=x+1$&lt;/li&gt;
&lt;li&gt;法线方程: $y-0=-1\cdot(x+1) ;\Longrightarrow; y=-x-1$&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;连续可导链体操&lt;/h3&gt;
&lt;p&gt;我们有经典梗图:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;bikes.png&quot; alt=&quot;连续不一定可倒，可倒一定连续&quot; /&gt;&lt;/p&gt;
&lt;p&gt;但这里还可以进一步说一说。&lt;/p&gt;
&lt;p&gt;简单来说，在点态和邻域中，分别有:
$$
\begin{aligned}
&amp;amp; f \text{ 连续} \Leftarrow\ f \text{ 可导}  \
\Leftarrow&lt;br /&gt;
&amp;amp; f&apos; \text{ 连续} \Leftarrow\ f&apos; \text{ 可导} \
\Leftarrow\ 
&amp;amp; f&apos;&apos; \text{ 连续} \Leftarrow\ \cdots
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;要详细说明，我们先定义一套符号表示这些东西:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;符号&lt;/th&gt;
&lt;th&gt;标准数学语言&lt;/th&gt;
&lt;th&gt;含义&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;$p_1$&lt;/td&gt;
&lt;td&gt;$f \in C^0(x_0)$&lt;/td&gt;
&lt;td&gt;$f$在$x_0$处连续&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$P_1$&lt;/td&gt;
&lt;td&gt;$\exists f&apos;(x_0)$&lt;/td&gt;
&lt;td&gt;$f$在$x_0$处可导&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$p_{1}^U$&lt;/td&gt;
&lt;td&gt;$f \in C^0(U)$&lt;/td&gt;
&lt;td&gt;$f$在$U$内处处连续&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$P_{1}^U$&lt;/td&gt;
&lt;td&gt;$\exists f&apos;(x), x \in U$&lt;/td&gt;
&lt;td&gt;$f$在$U$内处处可导&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$p_2$&lt;/td&gt;
&lt;td&gt;$f&apos; \in C^0(x_0)$&lt;/td&gt;
&lt;td&gt;$f&apos;$在$x_0$处连续&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$P_2$&lt;/td&gt;
&lt;td&gt;$\exists f&apos;&apos;(x_0)$&lt;/td&gt;
&lt;td&gt;$f$在$x_0$处二阶可导&amp;lt;br&amp;gt;($f&apos;$在该点可导)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$p_{2}^U$&lt;/td&gt;
&lt;td&gt;$f \in C^1(U)$&lt;/td&gt;
&lt;td&gt;$f&apos;$在$U$内处处连续&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$P_{2}^U$&lt;/td&gt;
&lt;td&gt;$\exists f&apos;&apos;(x), x \in U$&lt;/td&gt;
&lt;td&gt;$f$在$U$内处处二阶可导&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;我们有三条规则可以联系它们:&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;可导必定连续，导数连续必定可导
-$P_k \implies p_k \implies P_{k-1} \implies p_{k-1}$
-$P_k^U \implies p_k^U \implies P_{k-1}^U \implies p_{k-1}^U$&lt;/li&gt;
&lt;li&gt;局部必有点态
-$P_k^U \implies P_k$
-$p_k^U \implies p_k$&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;高阶点态连续要求低阶局部可导&lt;/strong&gt;
-$p_{k+1} \implies P_k^U$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;画成图示:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;graph TD
    classDef qNode fill:#d3e3fd,stroke:#0b57d0,color:#041e49,stroke-width:2px;
    classDef pNode fill:#c4eed0,stroke:#146c2e,color:#0f5223,stroke-width:2px;

    %% 节点定义
    q2U[&quot;P2U: 邻域二阶可导&amp;lt;br/&amp;gt;(f&apos;&apos;在U内存在)&quot;]:::qNode
    p2U[&quot;p2U: 邻域一阶导连续&amp;lt;br/&amp;gt;(f&apos;在U内连续)&quot;]:::pNode
    q2dot[&quot;P2: 点处二阶可导&amp;lt;br/&amp;gt;(f&apos;&apos;在x0处存在)&quot;]:::qNode
    p2dot[&quot;p2: 点处一阶导连续&amp;lt;br/&amp;gt;(f&apos;在x0处连续)&quot;]:::pNode
    q1U[&quot;P1U: 邻域一阶可导&amp;lt;br/&amp;gt;(f&apos;在U内存在)&quot;]:::qNode
    p1U[&quot;p1U: 邻域连续&amp;lt;br/&amp;gt;(f 在U内连续)&quot;]:::pNode
    q1dot[&quot;P1: 点处一阶可导&amp;lt;br/&amp;gt;(f&apos;在x_0处存在)&quot;]:::qNode
    p1dot[&quot;p1: 点处连续&amp;lt;br/&amp;gt;(f 在x_0处连续)&quot;]:::pNode

    %% 强弱主干链
    q2U --&amp;gt; p2U
    p2U --&amp;gt; p2dot
    p2dot --&amp;gt; q1U
    q1U --&amp;gt; p1U
    p1U --&amp;gt; p1dot

    %% 点态分支链
    q2U --&amp;gt; q2dot
    q2dot --&amp;gt; p2dot
    q1U --&amp;gt; q1dot
    q1dot --&amp;gt; p1dot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这8个命题中的任何两个本质都不相同。注意&lt;strong&gt;f&apos;存在&lt;/strong&gt;和&lt;strong&gt;f可导&lt;/strong&gt;是等价的。另外提一句，再往上接四个节点可以无缝衔接二阶导。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;邻域连续推不出点态可导($p_{1U} \nRightarrow P_1$)&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;函数$f(x) = |x|$在$0$的邻域内连续，但在$0$点不可导。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;chain_absx.png&quot; alt=&quot;邻域连续推不出点态可导 - 绝对值函数&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;点态可导推不出邻域连续($P_1 \nRightarrow p_{1U}$)&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;函数$f(x) = x^2 D(x)$($D(x)$为狄利克雷函数) 在$x=0$处不仅连续甚至可导（导数为0），但在$0$的任何邻域内，除了$0$点以外处处不连续。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;chain_xdx.png&quot; alt=&quot;点态可导推不出邻域连续 - 狄利克雷函数&quot; /&gt;
3. 邻域可导推不出导函数在点态连续($P_{1U} \nRightarrow p_{2\cdot}$)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;函数$f(x) = x^2 \sin(1/x)$($f(0)=0$)。它在任何邻域内处处可导，但它的导函数在$0$处发生剧烈振荡，因而不连续。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;chain_x2sinx-1.png&quot; alt=&quot;邻域可导推不出导函数在点态连续 - x2sin1/x&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;邻域连续、点处可导推不出邻域可导&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;$f(x)=xW(x)$。$W(x)$处处连续而处处不可导，但$xW(x)$在$x=0$处可导。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;chain_xwx.png&quot; alt=&quot;邻域连续+一阶可导无法推出邻域一阶可导&quot; /&gt;&lt;/p&gt;
&lt;p&gt;:::tip&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;命题a: 由$f&apos;(x)$在点态连续知$f(x)$在邻域可导&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;扩展到负一阶导:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;命题b: 由$g(x)$连续知$G(x)=\int_a^x f(t),\mathrm{d}t$在邻域可导&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;是不成立的。&lt;/p&gt;
&lt;p&gt;当我们说“函数$h(x) = f&apos;(x)$在$x_0$处连续”时，数学上的严格定义是:
$$
\lim_{x \to x_0} f&apos;(x) = f&apos;(x_0)
$$
为了让$\lim_{x \to x_0} f&apos;(x)$这个极限存在且能够被讨论，&lt;strong&gt;函数$f&apos;(x)$必须在$x_0$的某个去心邻域内存在&lt;/strong&gt;。也就是说，存在一个包含$x_0$的区间$U$, 在这个区间里的每一个点$x$, $f&apos;(x)$都是有意义（存在）的。这完全等价于“$f(x)$在区间$U$内可导”。 所以前者的成立并不是通过什么高深的定理推导出来的，而是“导函数连续”这个概念本身就强行要求了导数在邻域内存在。&lt;/p&gt;
&lt;p&gt;我们可以构造一个满足条件但结论不成立的反例:&lt;/p&gt;
&lt;p&gt;$$
f(x)=\begin{cases}
\frac{1}{n}, &amp;amp;x \in \left( \frac{1}{n+1}, \frac{1}{n} \right], n\in\mathbb{Z}^+  \
0, &amp;amp;x=0
\end{cases}
$$&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;$f(x)$在$x_0 = 0$处连续. 因为$x\to 0$时$f(x) = \frac{1}{n}\to 0$.&lt;/li&gt;
&lt;li&gt;$F(x) = \int_0^x f(t),\mathrm{d}t$存在. $f(x)$黎曼可积.&lt;/li&gt;
&lt;li&gt;$F(x)$在$x=0$的任意邻域内不可导.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;注意$x = \frac{1}{n}$一系列点有:
$$
\frac{1}{n}=f(1 /n^{-})=F&apos;&lt;em&gt;-(1/n)\neq F&apos;&lt;/em&gt;+(1/n) = f(1/n^+) = \frac{1}{n-1}
$$
所以$F(x)$在所有$x = \frac{1}{n}$处都&lt;strong&gt;不可导&lt;/strong&gt;。所以无论你找多么小的、包含0的邻域$U$, 里面都必然包含无穷多个点使得$F(x)$不可导。&lt;/p&gt;
&lt;p&gt;在我们平时的计算中，大家已经习惯了无脑写出$G&apos;(x) = \left( \int_a^x g(t),\mathrm{d}t \right)&apos; = g(x)$。但这并不是无条件成立的。比如:
$$
\begin{align*}
f(x)&amp;amp;=\begin{cases}
0,\qquad x\neq 0 \
1,\qquad x=0
\end{cases} \
F(x)&amp;amp;=\int_0^x f(t),\mathrm{d}t=0 \
F&apos;(x)&amp;amp;=0 \
F&apos;(0)&amp;amp;\neq f(0)
\end{align*}
$$
此处的$f(x)$, 它就是不可能作为任何函数的导数存在的。当然这是一个不连续的&lt;/p&gt;
&lt;p&gt;细说的话会拐到实分析去，我们就此结束。好奇者请自行使用考纲内定理证明达布定理。
:::&lt;/p&gt;
&lt;h3&gt;27330:35/&amp;lt;u&amp;gt;120&amp;lt;/u&amp;gt;/★★★☆☆&lt;/h3&gt;
&lt;p&gt;设
$$
f(x) = \begin{cases}
ax^2 + b\sin x + 2c, &amp;amp; x \le 0, \
\ln(1+x), &amp;amp; x &amp;gt; 0.
\end{cases}
$$
问$a,b,c$为何值时，$f(x)$在$x=0$处一阶导数连续，但二阶导数不存在。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;要使得这个函数一阶导数连续、二阶导数不存在，也就是使得:&lt;/p&gt;
&lt;p&gt;1.$f(x)$连续、可导
2.$f&apos;(x)$连续、不可导&lt;/p&gt;
&lt;p&gt;这些条件就足够我们确定这三个常数了&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;解&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;先处理连续性。连续是可导的前提。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;由$f(x)$在$x=0$处连续，得
$$
\begin{align*}
f(0) &amp;amp;= \
\lim_{x \to 0^-} f(x) &amp;amp;= \lim_{x \to 0^+} f(x) \
2c &amp;amp;= 0 \
c &amp;amp;= 0
\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;现在利用连续性求一阶导数。注意$f&apos;(0)$必须用定义计算。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;当$x&amp;lt;0$时，$f&apos;(x) = 2ax + b\cos x$；
当$x&amp;gt;0$时，$f&apos;(x) = \dfrac{1}{1+x}$。&lt;/p&gt;
&lt;p&gt;由一阶导数连续得:&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
f&apos;&lt;em&gt;-(0) &amp;amp;= f&apos;&lt;/em&gt;+(0) \
\lim_{x \to 0^-} (2ax + b\cos x) &amp;amp;= \lim_{x \to 0^+} \frac{1}{1+x}\
b &amp;amp;= 1.
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;此时$f&apos;(0) = 1$, 且$\lim_{x \to 0} f&apos;(x) = f&apos;(0)$自然成立。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;现在考察二阶导数。写出两侧的二阶导数表达式，再求左右极限。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;当$x&amp;lt;0$时，$f&apos;&apos;(x) = 2a - b\sin x = 2a - \sin x$；
当$x&amp;gt;0$时，$f&apos;&apos;(x) = -\dfrac{1}{(1+x)^2}$。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;要使二阶导数不存在，只需左右二阶导数不相等即可。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;$$
\begin{align*}
f&apos;&apos;&lt;em&gt;-(0) &amp;amp;\neq f&apos;&apos;&lt;/em&gt;+(0) \
\lim_{x \to 0^-} (2a - \sin x) &amp;amp;\neq \lim_{x \to 0^+} \left(-\frac{1}{(1+x)^2}\right) \
2a &amp;amp;\neq -1 \
a &amp;amp;\neq -\dfrac{1}{2}
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;综上，$f(x)$在$x=0$处一阶导数连续但二阶导数不存在的充要条件为
$$
\begin{cases}
a \neq -\frac{1}{2}, \
b = 1, \
c = 0
\end{cases}
$$&lt;/p&gt;
&lt;h2&gt;题型B: 求导&lt;/h2&gt;
&lt;p&gt;这类题型基本上是各种上下左右求导。有简单的题也有n阶导这类上限极高的。简单的一道如:&lt;/p&gt;
&lt;h3&gt;27330:75/&amp;lt;u&amp;gt;120&amp;lt;/u&amp;gt;/★★★★☆&lt;/h3&gt;
&lt;p&gt;设$f(x)=\arctan x$, 求$f^{(n)}(0)$.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;求函数在一点的高阶导数，直接逐阶求导会非常繁琐。初等函数的麦克劳林展开式中，系数与高阶导数有直接关系: $a_n = \dfrac{f^{(n)}(0)}{n!}$。这个关系的利用在特定点$n$阶导中非常常见。&lt;/p&gt;
&lt;p&gt;只要知道$\arctan x$的展开式，就可直接求出任意阶导数在$0$处的值。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;由
$$
f&apos;(x) = \frac{1}{1+x^2} = \sum_{k=0}^\infty (-1)^k x^{2k} \quad (|x|&amp;lt;1),
$$
且$f(0)=0$, 逐项积分得
$$
f(x) = \sum_{k=0}^\infty \frac{(-1)^k}{2k+1} x^{2k+1}.
$$&lt;/p&gt;
&lt;p&gt;又由泰勒展开式
$$
f(x) = \sum_{n=0}^\infty \frac{f^{(n)}(0)}{n!} x^n,
$$
比较系数:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当$n=2k$（偶数）时，$\displaystyle\frac{f^{(2k)}(0)}{(2k)!} = 0 ;\Longrightarrow; f^{(2k)}(0) = 0$；&lt;/li&gt;
&lt;li&gt;当$n=2k+1$（奇数）时，
$$
\displaystyle\frac{f^{(2k+1)}(0)}{(2k+1)!} = \frac{(-1)^k}{2k+1} ;\Longrightarrow; f^{(2k+1)}(0) = (-1)^k (2k)!
$$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;故
$$
f^{(n)}(0) =
\begin{cases}
0, &amp;amp; n \text{ 为偶数}, \
(-1)^{\frac{n-1}{2}}(n-1)!, &amp;amp; n \text{ 为奇数}.
\end{cases}
$$&lt;/p&gt;
&lt;h3&gt;27330:73/&amp;lt;u&amp;gt;120&amp;lt;/u&amp;gt;/★★★★☆&lt;/h3&gt;
&lt;p&gt;设函数$f(x)$在$(-\infty, +\infty)$上二阶连续可导，且对任意的$x$与$h$满足
$$
f(x+h)-f(x)=hf&apos;\left(x+\frac{h}{2}\right)
$$
求证: $f(x)=ax^2+bx+c$, 其中$a, b, c$为常数。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;已知条件对任意值成立&lt;/strong&gt;这种任意满足关系式，高中阶段也是能看到的。这类题我们主要通过取极值、取对称值互相加减来得到新关系式。&lt;/p&gt;
&lt;p&gt;题目要证明$f(x)$是一个二次函数。这类函数如何从推导中出现呢？&lt;/p&gt;
&lt;p&gt;我们可以通过证明$f&apos;&apos;(x)$是一个常数C，这样通过两次积分就能得到$f(x)=ax^{2}+bx+c$了。&lt;/p&gt;
&lt;p&gt;另一个需要注意的点是题目&lt;strong&gt;没有说$f(x)$三阶可导&lt;/strong&gt;，所以我们全过程都必须在二阶开始打住。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;至于何来思路，这种题最开始的尝试中 &lt;strong&gt;代0&lt;/strong&gt; 一定是对 &lt;strong&gt;任意满足关系式&lt;/strong&gt; 题型必不可少的尝试&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;原式令$x=0$可得:
$$
\begin{align*}
f(x+h)-f(x)&amp;amp;=hf&apos;\left(x+\frac{h}{2}\right) \
f(h)&amp;amp;=f(0)+hf&apos;\left( \frac{h}{2} \right) \tag{1}
\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;另外我们有$f(x)$二阶可导。也不要忘了求导试试，毕竟那个显眼包$\frac{h}{2}$肯定不是白给你的，最后总会有一个合适的形态解释出来的。&lt;/p&gt;
&lt;p&gt;或许是乘上了$2$, 或许是乘上$h$变成$\frac{h^{2}}{2}$然后导下去。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;原式对$h$求导、并且令$x=-\frac{h}{2}$可得:
$$
\begin{align*}
f(x+h)-f(x)&amp;amp;=hf&apos;\left(x+\frac{h}{2}\right) \
f&apos;(x+h)&amp;amp;=f&apos;\left( x+\frac{h}{2} \right) + \frac{h}{2}f&apos;&apos;\left( x+\frac{h}{2} \right) \
f&apos;\left( \frac{h}{2} \right)&amp;amp;=f&apos;\left( 0 \right) + \frac{h}{2}f&apos;&apos;\left( 0 \right) \tag{2}
\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“令$x=-\frac{h}{2}$”那步可以在草纸上求完导再发现。当我们注意到求导之后式子里出现两个$\left( x+\frac{h}{2} \right)$时就该考虑这件事了，把自变量凑成0一直都是很重要的事。&lt;/p&gt;
&lt;p&gt;我们现在通过&lt;strong&gt;代数值&lt;/strong&gt;和&lt;strong&gt;求导&lt;/strong&gt;造出了两个式子。其中式$(2)$是式$(1)$的一部分，&lt;strong&gt;使得$\frac{h}{2}$得以通过$hf&apos;\left( \frac{h}{2} \right)$乘到一个$h$。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;将$(2)$代入$(1)$得:&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
f(h)&amp;amp;=f(0)+hf&apos;\left( \frac{h}{2} \right) \
f(h)&amp;amp;=h\left[ f&apos;\left( 0 \right) + \frac{h}{2}f&apos;&apos;\left( 0 \right) \right] \
f(h)&amp;amp;=f(0)+hf&apos;(0)+\frac{h^{2}}{2}f&apos;&apos;(0)
\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这就是$f(x)$标准的麦克劳林前三项了。&lt;/p&gt;
&lt;p&gt;至于下一步证明...什么证明，这不已经是二次函数了吗？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;故$f(x)=ax^{2}+bx+c$。其中$a=\frac{f&apos;&apos;(0)}{2},b=f&apos;(0),c=f(0)$.&lt;/p&gt;
&lt;h2&gt;题型C: 函数性质&lt;/h2&gt;
&lt;p&gt;函数性质，就是要求单调性、凹凸性、极值、最值、零点、拐点。&lt;/p&gt;
&lt;p&gt;这些概念不过了。高中都学过。问题在于考研里这些题要么公式化，要么就是初见杀。公式化的题如证明
$$
\sqrt{\dfrac{1-x}{1+x}}&amp;lt;\dfrac{\ln(1+x)}{\arcsin x} \quad (0&amp;lt;x&amp;lt;1)
$$
这种糊起来最简单了。左右乘过去方便求导，求个值点，求个导数就证毕了，跟高中甚至都没什么区别。问题是那些初见杀:&lt;/p&gt;
&lt;h3&gt;27330:57/&amp;lt;u&amp;gt;120&amp;lt;/u&amp;gt;/★★★★☆&lt;/h3&gt;
&lt;p&gt;设$f(x), g(x)$在点$x=0$的某邻域内连续，且$f(x)$具有一阶连续导数，并有
$$
\lim_{x \to 0} \frac{g(x)}{x} = 2, \quad f&apos;(x) = -2x^2 + \int_{0}^{x} g(x-t)\mathrm{d}t,
$$
求曲线$y=f(x)$的一个拐点。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;$f&apos;&apos;(x)$在$x_0$的&lt;strong&gt;左右两侧异号&lt;/strong&gt;（一正一负），则$x_{0}$是$f$的一个拐点。&lt;/p&gt;
&lt;p&gt;这道题是一个简单的题。原因摆在题面上:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;我们已经明显看到$f&apos;(x)$, 我们直接求导就行。&lt;/li&gt;
&lt;li&gt;$\int_{0}^{x} g(x-t)\mathrm{d}t$是一个标准的不能再标准的区间再现公式。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;关于区间再现我会在积分那边讲。尽管形式上我们要写一下$u=x-t$, 但你草纸上直接写$\int_{0}^{x} g(t)\mathrm{d}t$就行。当然形式上基本积分换元推导要推熟练，还是那句话，有些东西本质推导熟练了背下来才算掌握了。&lt;/p&gt;
&lt;p&gt;我们先把第一步速通了&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;解&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;令$u=x-t$, 将积分化为$\int_0^x g(u),\mathrm{d}u$, 以便求导。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;$$
f&apos;(x) = -2x^2 + \int_0^x g(x-t),\mathrm{d}t = -2x^2 + \int_0^x g(u),\mathrm{d}u.
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;$g$连续，由微积分基本定理，$f&apos;(x)$可导，对其求导得$f&apos;&apos;(x)$。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;$$
f&apos;&apos;(x) = -4x + g(x).
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;二阶段，注意题目条件$\lim_{x \to 0} \frac{g(x)}{x} = 2$实质上隐藏了两个条件:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$g(x)\to 0$, 即$g(0)=0$&lt;/li&gt;
&lt;li&gt;$g&apos;(0)=2$。注意$g(x)$是连续的，我们才能说$g&apos;(0)$存在。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;由$\lim\limits_{x\to0}\frac{g(x)}{x}=2$及$g$连续，得$g(0)=0$, 于是$f&apos;&apos;(0)=0$.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;为判定$x=0$是否为拐点，需考察$f&apos;&apos;(x)$在$x=0$两侧是否变号。将$f&apos;&apos;(x)$写成$x(\frac{g(x)}{x}-4)$, 利用极限的保号性即可。
$$
f&apos;&apos;(x) = x\left(\frac{g(x)}{x}-4\right).
$$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;由$\lim_{x \to 0} \frac{g(x)}{x} = 2$, 显然$\left(\frac{g(x)}{x}-4\right)$在$x\to 0^+$和$x\to 0^-$不变号，而$x$变号。$f&apos;&apos;(x)$在$x=0$两侧由正变负。故点$(0, f(0))$为曲线$y=f(x)$的一个拐点。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;$f(0)$无法由已知条件确定，因为只给了$f&apos;$, 保留即可。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所求拐点为$(0, f(0))$.&lt;/p&gt;
&lt;h3&gt;27330:65/&amp;lt;u&amp;gt;120&amp;lt;/u&amp;gt;/★★★★★&lt;/h3&gt;
&lt;p&gt;已知任意$x \in (-\infty, +\infty)$,$f&apos;&apos;(x) \ge 0$, 且$0 \le f(x) \le 1 - e^{-x^2}$, 求$f(x)$。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我的天哪五星题大人。&lt;/p&gt;
&lt;p&gt;很多证明题在几何理解上十分直观，实际上并不好证。最难的一点就是找到矛盾在哪。我们尝试用一种既直观又严谨的语言理解:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;27330_65_1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;条件$f&apos;&apos;(x)\ge0$表明$f$是凹函数，而$1-e^{-x^2}$是一个有渐近线$y=1$的函数。条件要求$f(x)$从$(0,0)$开始:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在x轴和图中红线之间的区域前进&lt;/li&gt;
&lt;li&gt;永远不往右打方向盘&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;另一个隐藏前提: $f(x)$在从$(0,0)$向右出门的那一刻起的方向(即$f&apos;(0)$)一定是&lt;strong&gt;0&lt;/strong&gt;。否则出门的第一步就会走出红线。&lt;/p&gt;
&lt;p&gt;而只允许$f(x)$往左打方向盘的话，无论$f(x)$多微小地往左打一点方向盘，它都必然会冲破$y=1$。&lt;strong&gt;*注意: 我们这里其实是反证法&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;所以唯一的解就是不打方向盘，$f(x)$永远笔直地往右走，即$y=0$。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;解&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;由$f&apos;&apos;(x)\ge0$知$f$为$\mathbb{R}$上的凹函数。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;反证: 若非常数，由凹性可推出$f$无上界(即突出$y=0$和$y=1$包围圈)，与已知矛盾。&lt;/p&gt;
&lt;p&gt;先假设有两个点使得斜率不为0，然后凹性使得某一侧的斜率会持续不靠近0（斜率不会回落到水平），然后可以得证。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;假设$f$不恒为常数，则存在$a&amp;lt;b$使得$f(a)\neq f(b)$。不妨设$f(a)&amp;lt;f(b)$。由凹函数的割线斜率递增性，对任意$x&amp;gt;b$有
$$
\frac{f(x)-f(b)}{x-b} \ge \frac{f(b)-f(a)}{b-a}.
$$
&lt;img src=&quot;27330_65_2.png&quot; alt=&quot;b-c的斜率必然大于a-b的斜率；反向同理&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;于是，必定有一边的斜率一直增大而永远不会像$\sin x$一样摆动。这一边我们称之为$a&amp;lt;b&amp;lt;x$中$x$所在的一边。这一边必将冲向无穷大。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;于是有
$$
f(x) \ge f(b) + \frac{f(b)-f(a)}{b-a}(x-b) \xrightarrow{x\to+\infty} +\infty,
$$
与$f(x)\le 1-e^{-x^2}\le 1$矛盾。同理，若$f(a)&amp;gt;f(b)$, 令$x\to-\infty$亦得矛盾。&lt;/p&gt;
&lt;p&gt;故$f$必为常值函数，设$f(x)\equiv C$。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;利用原点处的夹逼求出常数。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在$x=0$处，由$0\le f(0)\le 1-e^{0}=0$得$f(0)=0$, 从而$C=0$。因此
$$
f(x)=0.
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;很多题的共性是要先理解题意、再知道如何把一些脑子里的直观步骤写到纸上。真正的推导链条并不复杂，至少没有近代数学那些推导那么复杂。&lt;/p&gt;
&lt;p&gt;哦对了微积分发明那个年代好像根本不在乎严谨推导。无所谓了，我们甚至都能用洛必达这么方便的东西了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;27330:66/&amp;lt;u&amp;gt;120&amp;lt;/u&amp;gt;/★★★★★&lt;/h3&gt;
&lt;p&gt;设$f(x)$是一多项式，$f(x) \ge x, f(x) \ge 1-x$, 证明$f\left(\frac{1}{2}\right) &amp;gt; \frac{1}{2}$。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我的天哪...&lt;/p&gt;
&lt;p&gt;抓不到矛盾的话，先看图说话吧。图解很好理解。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;27330_66_1.png&quot; alt=&quot;多项式是光滑的&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;先说矛盾: 矛盾在于，条件给出了的下界&lt;strong&gt;包含一个尖点&lt;/strong&gt;，而:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;尖点的位置正好就是题目中要求的$\left( \frac{1}{2}, \frac{1}{2}\right)$.&lt;/li&gt;
&lt;li&gt;$f(x) \ge x$和$f(x) \ge 1-x$都支持$f\left( \frac{1}{2} \right) \ge \frac{1}{2}$.&lt;/li&gt;
&lt;li&gt;$f\left( \frac{1}{2} \right) \gt \frac{1}{2}$是合理的，要证伪的是$f\left( \frac{1}{2} \right) = \frac{1}{2}$.也就排除这种可能性&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那么我们要看另一个条件: $f(x)$是一多项式。如果它经过$\left( \frac{1}{2}, \frac{1}{2} \right)$点:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$f$是多项式。多项式是光滑的。&lt;/li&gt;
&lt;li&gt;$f$先要同时大于左右两个下界，又要满足这个尖点，$f$自身&lt;strong&gt;必然会贴到这个尖角里，形成尖点。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;光滑的多项式里&lt;strong&gt;不能形成尖点&lt;/strong&gt;。多项式处处无限可导。&lt;/li&gt;
&lt;li&gt;这迫使$f&apos;(\frac{1}{2})$同时等于两条直线的斜率$1$和$-1$, 矛盾。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;证明&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;令$g(x)=f(x)-x$, $h(x)=f(x)-(1-x)$。依题意，对任意$x$有$g(x)\ge0$, $h(x)\ge0$。&lt;/p&gt;
&lt;p&gt;假设$f(\frac{1}{2})=\frac{1}{2}$, 则
$$
g!\left(\frac{1}{2}\right)=0,\qquad h!\left(\frac{1}{2}\right)=0.
$$
即$x=\frac{1}{2}$同时为$g(x)$与$h(x)$的最小值点。因$f$为多项式，可导，故
$$
g&apos;!\left(\frac{1}{2}\right)=0,\quad h&apos;!\left(\frac{1}{2}\right)=0.
$$
而$g&apos;(x)=f&apos;(x)-1$, $h&apos;(x)=f&apos;(x)+1$, 代入得
$$
f&apos;!\left(\frac{1}{2}\right)-1=0,\qquad f&apos;!\left(\frac{1}{2}\right)+1=0,
$$
矛盾。故假设不成立，从而
$$
f!\left(\frac{1}{2}\right)&amp;gt;\frac{1}{2}.
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这道题很妙地用到了多项式可导这个性质。也让我想到了一些很形象的场面，比如你绝对不可能把手指完美挤进一个直角墙角里，因为你的手指皮肤不能弯成那么完美的直角，一定会留下一个小空间 belike:
&lt;img src=&quot;27330_66_2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;27330:71/&amp;lt;u&amp;gt;130+&amp;lt;/u&amp;gt;/★★★★★&lt;/h3&gt;
&lt;p&gt;设$f(x)$在区间$(-\infty, +\infty)$上存在二阶导数，$f(0) &amp;lt; 0, f&apos;&apos;(x) &amp;gt; 0$. 试证明:
(1) 在$(-\infty, +\infty)$上$f(x)$至多有 2 个零点，至少有 1 个零点；
(2) 若的确有 2 个零点$x_1$与$x_2$, 则$x_1x_2 &amp;lt; 0$.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我的天哪130+的题&lt;/p&gt;
&lt;p&gt;其实这里的题型C是我为数不多能全过130+,5*题的类型。所以肯定要多讲讲。&lt;/p&gt;
&lt;p&gt;这道题和65题有异曲同工之妙，都利用了二阶导数锚定一阶导数，进而锚定的单调性解题。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;27330_71_1.png&quot; alt=&quot;三种符合条件的函数，有1或2个零点&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;条件$f&apos;&apos;(x)&amp;gt;0$表明函数严格凹，因此零点个数至多两个；同时，结合$f(0)&amp;lt;0$与导数的单调性，利用拉格朗日中值定理可证函数必在某方向趋于正无穷，从而穿过$x$轴，保证至少有一个零点。若恰有两个零点，由严格凹性知$f(0)&amp;lt;0$必须落在两零点之间，从而它们异号。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;函数有$f(0)&amp;lt;0$。假设我们从$(0,-1)$出发&lt;/li&gt;
&lt;li&gt;出发点的斜率是正或负？我们考虑两种情况:
&lt;ul&gt;
&lt;li&gt;A: $x&amp;gt;0$方向，$f&apos;(0)\geq 0$或$x&amp;lt;0$方向，$f&apos;(0)\leq 0$。这时这个方向必定有零点。条件会使得$f(x)$在该轴方向严格单调。必只有一个零点（如图中红色、绿色两函数）&lt;/li&gt;
&lt;li&gt;B: $x&amp;gt;0$方向，$f&apos;(0)\leq 0$或$x&amp;lt;0$方向，$f&apos;(0)\geq 0$。这时这个方向是否有零点取决于方向是否会从另一侧再次向上。
&lt;img src=&quot;27330_71_2.png&quot; alt=&quot;红色的函数有两个零点，橙色的没有&quot; /&gt;
我们显然发现在情况B下，&lt;strong&gt;驻点&lt;/strong&gt;是产生返回现象重要的转折点。顺理成章地，根据条件$f&apos;&apos;(x)&amp;gt;0$意味着$f&apos;$严格递增，从而$f$至多有一个驻点。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;我们先利用罗尔定理（用别的也可以）推出零点个数与驻点个数的关系，证出“至多两个零点”；再结合$f(0)&amp;lt;0$与凸函数的切线性质证出“至少一个零点”。第(2)问则利用严格凸函数在两点间恒在连线下方，结合$f(0)&amp;lt;0$导出两零点必分居原点两侧。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;**解: **&lt;/p&gt;
&lt;p&gt;(1). 若$f(x)$有三个互异零点$x_1&amp;lt;x_2&amp;lt;x_3$, 由罗尔定理，$f&apos;(x)$在$(x_1,x_2)$与$(x_2,x_3)$内各至少有一个零点，这与$f&apos;(x)$至多一个零点矛盾。故$f(x)$至多有两个零点。&lt;/p&gt;
&lt;p&gt;由$f&apos;&apos;(x)&amp;gt;0$知$f$为严格凹函数，其图形恒在其任一点切线的上方，故:
$$
f(x) \ge f(0)+f&apos;(0)x,\quad \forall x\in\mathbb{R}.
$$
因$f(0)&amp;lt;0$, 若$f&apos;(0)\ge 0$, 取$x_0&amp;gt;0$充分大可使$f(0)+f&apos;(0)x_0&amp;gt;0$；若$f&apos;(0)&amp;lt;0$, 取$x_0&amp;lt;0$且$|x_0|$充分大亦可使该线性函数为正。从而均有$f(x_0)&amp;gt;0$。对$f(x)$在$0$与$x_0$之间用连续函数的介值定理，即知至少存在一个零点。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;凹函数上，任意两点连线，连线之间的函数图像必然在连线直线的下方。&lt;/p&gt;
&lt;p&gt;故有两零点时，由凹性知两零点之间的函数值严格小于0，从而全在$x$轴下方。$f(0)&amp;lt;0$说明原点必在两零点之间。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;(2)&lt;/strong&gt;&lt;br /&gt;
若恰有两个零点$x_1&amp;lt;x_2$, 则$f(x_1)=f(x_2)=0$。由$f$的严格凸性，对任意$x\in(x_1,x_2)$有
$$
f(x) &amp;lt; \frac{x_2-x}{x_2-x_1}f(x_1)+\frac{x-x_1}{x_2-x_1}f(x_2)=0.
$$
已知$f(0)&amp;lt;0$, 故$0\in(x_1,x_2)$, 即$x_1&amp;lt;0&amp;lt;x_2$, 从而
$$
x_1x_2&amp;lt;0.
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;搓到这里现在是2026年7月14日02:27:04。&amp;lt;-这串时间是搜狗输入法打“sj”快捷点出来的。很方便吧。心脏有点难受，感觉要去见张师了。明天再码吧&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;题型D: 差分、微分、参数方程&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;我回来了。心脏不难受了哦。没事哦。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;开头我说的&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;微分嘛，求导&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这句话高考里是好使的。但考研不行。现在开始，我们会很快会进入一元函数微分学的深水区。来人，把定义式搬回来！&lt;/p&gt;
&lt;h3&gt;差分和微分&lt;/h3&gt;
&lt;p&gt;$$
f&apos;(x_0) = \lim_{\Delta x \to 0} \frac{f(x_0 + \Delta x) - f(x_0)}{\Delta x}
$$&lt;/p&gt;
&lt;p&gt;在这个导数定义式中，$\Delta x$是一个趋向于无穷小的量。趋于无穷小后它才能变成导数。如果没趋于极限，我们称其为&lt;strong&gt;差分&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;lim_difference.png&quot; alt=&quot;差分的极限是微分&quot; /&gt;&lt;/p&gt;
&lt;p&gt;如果我们将定义式的上半部分$f(x_0 + \Delta x) - f(x_0)$写作$\Delta y$, 原式变为
$$
f&apos;(x_0) = \lim_{\Delta x \to x_{0}} \frac{\Delta y}{\Delta x} = \frac{\mathrm{d}y}{\mathrm{d}x}
$$
这便是$\frac{\mathrm{d}y}{\mathrm{d}x}$的由来，也是微分式&lt;strong&gt;形式上&lt;/strong&gt;真能当成分数算的一种推导。比如一个看起来很诡异的关系，但实际上完全正确并且你可以直接用的事实是:
$$
y&apos;_x=\frac{\mathrm{d}y}{\mathrm{d}x}=\frac{1}{\frac{\mathrm{d}x}{\mathrm{d}y}}=\frac1{x&apos;_y}
$$&lt;/p&gt;
&lt;h3&gt;27330:42/&amp;lt;u&amp;gt;90&amp;lt;/u&amp;gt;/★★★☆☆&lt;/h3&gt;
&lt;p&gt;设严格单调函数$y = f(x)$有二阶连续导数，其反函数为$x = \varphi(y)$, 且$f(1) = 2, f&apos;(1) = 2, f&apos;&apos;(1) = 3$, 求$\varphi&apos;&apos;(2)$。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;首先，我们要求的:
$$
\varphi&apos;&apos;(x)=\frac{d}{dx}\varphi&apos;(x)=\frac{d }{dx}\frac{d }{dx}\varphi(x)
$$
其次，我们知道两个公式:
$$
\begin{align*}
\frac{d}{dy}x = 1 / \frac{d}{dx}y \
\frac{df}{dy}=\frac{dx}{dy} \cdot \frac{df}{dx}
\end{align*}
$$
这两个公式都非常有助于转换式子的&lt;strong&gt;相关变量&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;其实这道题说白了也就是介绍这两个公式，既然都直接放了，那也没什么好解说的了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;解&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
\varphi&apos;&apos;(y)
&amp;amp;= \underbrace{ \frac{d}{dy}\varphi&apos;(y) }&lt;em&gt;{\text{完全关于y}} \
&amp;amp;= \frac{d}{dy}!\left(\frac{1}{f&apos;(x)}\right) \
&amp;amp;= \underbrace{ \frac{d}{dx}!\left(\frac{1}{f&apos;(x)}\right) }&lt;/em&gt;{ \text{完全关于x,可代入} } \cdot \underbrace{ \frac{dx}{dy} }&lt;em&gt;{ \text{关于y的函数x&apos;(y)} } \
&amp;amp;= -\frac{f&apos;&apos;(x)}{\bigl[f&apos;(x)\bigr]^2} \cdot \underbrace{ \frac{1}{f&apos;(x)} }&lt;/em&gt;{ \text{完全关于x,可代入} } \
&amp;amp;= -\frac{f&apos;&apos;(x)}{\bigl[f&apos;(x)\bigr]^3}.
\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;因为题目给的是具体点（$f(1)=2$, 即$x=1$对应$y=2$），所以直接代入$x=1$即可。&lt;/p&gt;
&lt;p&gt;总之$\frac{d^2x}{dy^2} \neq 1 / \frac{d^2y}{dx^2}$。毕竟哪怕是按分数约分这俩也约不开。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;代入$x=1,; f&apos;(1)=2,; f&apos;&apos;(1)=3$得
$$
\varphi&apos;&apos;(2) = -\frac{3}{2^3} = -\frac{3}{8}.
$$&lt;/p&gt;
&lt;hr /&gt;
&lt;blockquote&gt;
&lt;p&gt;$\frac{dy}{dx}$的可操作性固然是好的。另一方面，有时候手动构建这种逻辑也是必要的&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;27330:48/&amp;lt;u&amp;gt;130+&amp;lt;/u&amp;gt;/★★★★☆&lt;/h3&gt;
&lt;p&gt;设函数$y$在任意点$x$处的增量满足
$$
\Delta y = \frac{x}{\sqrt{x^2 + 1}}\Delta x - \frac{x^2}{\sqrt{x^2 + 1} + 1}\Delta y + \frac{\sqrt{x^2 + 1}}{\sqrt{x^2 + 1} + 1}\Delta x\Delta y,
$$
且$y(0) = 0$, 计算极限$\lim_{x \to 0} \frac{\int_{0}^{\arctan x} y(t)\mathrm{d}t}{x^2 \ln(x + \sqrt{1 + x^2})}$。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;虽然看起来是130+，但其实这道题只要略微理解差分到微分的本质，思路就十分顺滑:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;要计算极限。极限中除了显然是送人头来的分母，就是上面的未知函数y。&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;这个分母可以通过等价无穷小一步步杀，也可以识别出是&lt;a href=&quot;https://blog.emumu.xyz/posts/2026-03-19-00/#%E5%8F%8C%E6%9B%B2%E5%87%BD%E6%95%B0&quot;&gt;&lt;strong&gt;反双曲正弦函数&lt;/strong&gt;&lt;/a&gt;，并通过$\operatorname{arcsinh} x \sim x$一脚踢死。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;既然都大方给了&lt;strong&gt;任意满足&lt;/strong&gt;差分方程，那我们大大方方地取个极限不过分吧&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;先不要当场就取。复习一下，我们知道的是:&lt;/li&gt;
&lt;li&gt;$\lim_{\Delta x \to x_{0}} \frac{\Delta y}{\Delta x} = f&apos;(x_0)$&lt;/li&gt;
&lt;li&gt;所以我们先至少造出一个像样的$\frac{\Delta y}{\Delta x}$, 再去取极限。我们就能得到干净的$y&apos;(x)$, 然后塞到极限式子里。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;解&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;由题意得&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}&lt;/p&gt;
&lt;p&gt;\Bigl(1+\frac{x^2}{\sqrt{x^2+1}+1}\Bigr)\Delta y &amp;amp;= \frac{x}{\sqrt{x^2+1}}\Delta x + \frac{\sqrt{x^2+1}}{\sqrt{x^2+1}+1}\Delta x\Delta y \&lt;/p&gt;
&lt;p&gt;\Bigl(1+\frac{x^2}{\sqrt{x^2+1}+1}\Bigr) \frac{\Delta y}{\Delta x} &amp;amp;= \frac{x}{\sqrt{x^2+1}} + \frac{\sqrt{x^2+1}}{\sqrt{x^2+1}+1}\Delta y \[12pt]&lt;/p&gt;
&lt;p&gt;\text{令}\Delta x\to0\text{，注意}\frac{\Delta y}{\Delta x}&amp;amp;\to y&apos;,\Delta y\to0\text{，得} \&lt;/p&gt;
&lt;p&gt;\sqrt{x^2+1}, y&apos; &amp;amp;= \frac{x}{\sqrt{x^2+1}} \&lt;/p&gt;
&lt;p&gt;y&apos; &amp;amp;= \frac{x}{1+x^2} \[12pt]&lt;/p&gt;
&lt;p&gt;\text{由} y(0)=0 &amp;amp;\text{，两侧积分得} \&lt;/p&gt;
&lt;p&gt;y &amp;amp;= \frac12\ln(1+x^2).&lt;/p&gt;
&lt;p&gt;\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;将$y$代入极限，当$x\to0$时，分母中$\ln(x+\sqrt{1+x^2})\sim x$, 故分母$\sim x^3$。分子是变上限积分，可考虑洛必达法则。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;极限为
$$
L = \lim_{x\to0}\frac{\int_0^{\arctan x} \frac12\ln(1+t^2),\mathrm dt}{x^2\ln(x+\sqrt{1+x^2})}.
$$
由$\ln(x+\sqrt{1+x^2})\sim x$及$\arctan x\sim x$, 并使用洛必达:
$$
\begin{align*}
L &amp;amp;= \lim_{x\to0}\frac{\frac12\ln(1+\arctan^2 x)\cdot\frac{1}{1+x^2}}{2x\ln(x+\sqrt{1+x^2}) + x^2\cdot\frac{1}{\sqrt{1+x^2}}} \
&amp;amp;= \lim_{x\to0}\frac{\frac12\arctan^2 x\cdot1}{2x^2 + x^2\cdot 1} \
&amp;amp;= \lim_{x\to0}\frac{\frac12 x^2}{3x^2} = \frac{1}{6}.
\end{align*}
$$&lt;/p&gt;
&lt;h2&gt;题型E: 中值定理&lt;/h2&gt;
&lt;p&gt;终于我们来到了微分最深不可测的领域。实话说我放弃了这里大量130+5*的大题。所以也只能浅说一说。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.desmos.com/calculator/tkn84bdiso&quot;&gt;&lt;img src=&quot;mvt.png&quot; alt=&quot;拉格朗日中值定理的desmos示例(点此处跳转)&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;拉格朗日中值定理的核心思想很简单。它将函数在区间两端的&lt;strong&gt;变化净值&lt;/strong&gt;（$\Delta y$），转化为了区间内部某一点的&lt;strong&gt;瞬时变化率&lt;/strong&gt;（导数）。:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;若$f(x)$在$[a,b]$连续，$(a,b)$可导，则至少存在一点$\xi \in (a,b)$, 使得:&lt;/p&gt;
&lt;p&gt;$$
f&apos;(\xi) = \frac{f(b) - f(a)}{(b-a)}
$$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;换句话说，瞬时速度必然在某一刻等于平均速度。从A地开车到B地，如果平均车速是80km/h，那么在此期间你的码表指针必定在某一瞬间指在80km/h上。&lt;/p&gt;
&lt;p&gt;以上这条就是&lt;strong&gt;拉格朗日中值定理&lt;/strong&gt;。我们还常用两种中值定理:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;罗尔定理&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;就是分子$f(b) - f(a)=0$的拉格朗日中值。由于公式会变成各种意义上都十分方便的$f&apos;(\xi) = 0$, 而且计算中&lt;strong&gt;经常要凑出这个$0$才能继续往下算&lt;/strong&gt;，所以是最常用的。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;柯西中值定理&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;若$f(x), g(x)$在$[a,b]$连续，$(a,b)$可导，且$g&apos;(x) \neq 0$, 则存在一点$\xi \in (a,b)$, 使得:
$$
\frac{f(b) - f(a)}{g(b) - g(a)} = \frac{f&apos;(\xi)}{g&apos;(\xi)}
$$
本质是&lt;strong&gt;参数方程&lt;/strong&gt;的拉格朗日定理。设曲线的参数方程为$x=g(t), y=f(t)$, 定理说明在曲线上必然存在一点，其切线斜率等于连接起终点的割线斜率。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这三者的推导本质上都是通过构造辅助函数，将其转化为&lt;strong&gt;罗尔定理&lt;/strong&gt;。罗尔定理虽然是最简单的，却也是重要极限一般的存在&lt;/p&gt;
&lt;p&gt;积分中值定理则是拉格朗日的另一种马甲，下一章我们说（又是一大天坑啊）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;27330:80/&amp;lt;u&amp;gt;90&amp;lt;/u&amp;gt;/★★★★☆&lt;/h3&gt;
&lt;p&gt;设$f(x)$在$[a,b]$上连续，在$(a,b)$内可导，$f(a)=f(b)=0$。证明存在$\xi \in (a,b)$, 使$f&apos;(\xi) + f^2(\xi) = 0$。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;为了让你顺心做这道题，我必须使你注意到:
$$
\begin{align*}
&amp;amp;\frac{d}{dx} \bigl[;f(x)\cdot e^{ G(x) dx };\bigr] \
=&amp;amp; \bigl[;f&apos;(x)+f(x)\cdot g(x);\bigr] e^{ G(x) dx }
\end{align*}
$$
显然，形如$f e^{\int f}$的函数求导后能产生因子$e^{\int f}(f&apos;+f^2)$, 恰好可利用$f(a)=f(b)=0$使该函数两端相等，从而用罗尔定理。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;构造辅助函数
$$
F(x) = f(x), e^{\int_a^x f(t),\mathrm{d}t},\quad x\in[a,b].
$$
由$f(x)$连续知$\int_a^x f(t),\mathrm{d}t$可导，且其导数为$f(x)$；又$f(x)$可导，故$F(x)$在$[a,b]$上连续，在$(a,b)$内可导，且
$$
F&apos;(x) = e^{\int_a^x f(t),\mathrm{d}t}\bigl[ f&apos;(x) + f^2(x) \bigr].
$$
因$f(a)=f(b)=0$, 有
$$
F(a) = 0\cdot e^0 = 0,\qquad F(b) = 0\cdot e^{\int_a^b f(t),\mathrm{d}t}=0,
$$
即$F(a)=F(b)$. 由罗尔定理，存在$\xi\in(a,b)$使得$F&apos;(\xi)=0$. 又$e^{\int_a^\xi f(t),\mathrm{d}t}\neq0$, 故
$$
f&apos;(\xi) + f^2(\xi) = 0.
$$&lt;/p&gt;
&lt;h3&gt;27330:81/&amp;lt;u&amp;gt;90&amp;lt;/u&amp;gt;/★★★★☆&lt;/h3&gt;
&lt;p&gt;设$f(x)$在$[0,1]$上可导，对于任意的$x \in (0,1]$, 满足$f&apos;(x) = f(\lambda x)$, 其中常数$\lambda \in (0,1]$, 且$f(0) = 0$。证明$f(x)$在$[0,1]$上恒为零。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;条件$f&apos;(x) = f(\lambda x)$将一点的导数与另一点函数值挂钩。由$f(0)=0$, 反复使用拉格朗日中值定理可将$f(x)$表示为一个乘积，用闭区间上连续函数的有界性放缩，令迭代次数趋于无穷即得$f(x)=0$。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;由$f$可导知$f$在$[0,1]$上连续，令$M = \max\limits_{[0,1]} |f(x)| &amp;lt; \infty$。&lt;/p&gt;
&lt;p&gt;任取$x \in (0,1]$。因$f(0)=0$, 由拉格朗日中值定理，存在$\xi_n \in (0,x)$使
$$
\begin{align*}
f(x)
&amp;amp;= f(x)-f(0) \
&amp;amp;= f&apos;(\xi_1) x \qquad ,\xi_{1} \in (0,x)\
&amp;amp;= f(\lambda \xi_1) x  \[12pt]&lt;/p&gt;
&lt;p&gt;f(\lambda\xi_{1})
&amp;amp;= f(\lambda\xi_{1})-f(0) \
&amp;amp;= f&apos;(\xi_2) \lambda\xi_{1} \qquad ,\xi_{2} \in (0,\lambda\xi_{1})\
&amp;amp;= f(\lambda \xi_2) \lambda\xi_{1}  \[12pt]&lt;/p&gt;
&lt;p&gt;f(\lambda\xi_{n})
&amp;amp;= f(\lambda\xi_{n})-f(0) \
&amp;amp;= f&apos;(\xi_{n+1}) \lambda\xi_{n} \qquad ,\xi_{n+1} \in (0,\lambda\xi_{n})\
&amp;amp;= f(\lambda \xi_{n=1}) \lambda\xi_{n}  \[12pt]&lt;/p&gt;
&lt;p&gt;f(x)
&amp;amp;= f(\lambda \xi_1) x \qquad ,\xi_{1} \in (0,x)\
&amp;amp;= f(\lambda \xi_{n})\cdot (\lambda \xi_{n-1})(\lambda \xi_{n-2})\cdots (\lambda \xi_{1})x\
&amp;amp;\qquad ,\xi_{n} \in (0,\lambda\xi_{n-1}) \subseteq (0,x) \
&amp;amp;= f(\lambda \xi_{n})\cdot\lambda^{n-1}\xi_{n-1}\xi_{n-2}\cdots \xi_{1}
\end{align*}
$$
$f(x)$在$[0,1]$可导，即在$[0,1]$有限。设$|f(x)|$在$[0,1]$上的最大值为$M$。则:&lt;/p&gt;
&lt;p&gt;$$
|f(x)|=|f(\lambda \xi_{n})\cdot\lambda^{n-1}\xi_{n-1}\xi_{n-2}\cdots \xi_{1}| \leq M\lambda^{n-1}
$$&lt;/p&gt;
&lt;p&gt;当任意值$n\to \infty$时，$M\lambda^{n-1}\to 0$, 故$|f(x)|\to 0$。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;《无尽的拉格朗日》&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;27330:83/&amp;lt;u&amp;gt;120&amp;lt;/u&amp;gt;/★★★★★&lt;/h3&gt;
&lt;p&gt;设$f(x)$在$[0,1]$上具有二阶导数，且满足$f(0)=0, f(1)=1, f\left(\frac{1}{2}\right) &amp;gt; \frac{1}{4}$, 证明:
(1) 存在一点$\xi \in (0,1)$, 使得$f&apos;&apos;(\xi) &amp;lt; 2$；
(2) 若对于任意的$x \in (0,1)$, $f&apos;&apos;(x) \neq 2$, 则对于任意的$x \in (0,1)$, $f(x) &amp;gt; x^2$。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;当一个函数满足另一个相似的函数的性质时，我们就应该考虑直接将它与我们想象中的函数相减。就比如$(0,0),\left( \frac{1}{2}, \frac{1}{4} \right),(1,1)$这样熟悉的三个点。&lt;/p&gt;
&lt;p&gt;(1) 构造辅助函数$g(x)=f(x)-x^2$, 条件转化为$g(0)=g(1)=0$, $g(1/2)&amp;gt;0$。对$g$在$[0,1/2]$和$[1/2,1]$上分别使用拉格朗日中值定理&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(1) 令$g(x)=f(x)-x^{2}$, 则
$$
g(0)=0,\quad g(1)=0,\quad g!\left(\frac12\right)=f!\left(\frac12\right)-\frac14&amp;gt;0.
$$
且有
$$
\begin{align*}
g(x)&amp;amp;=f(x)-x^{2} \
g&apos;(x)&amp;amp;=f&apos;(x)-2x \
g&apos;&apos;(x)&amp;amp;=f&apos;&apos;(x)-2
\end{align*}
$$
由拉格朗日中值定理，存在$\eta_{1}\in\left(0,\frac12\right),; \eta_{2}\in\left(\frac12,1\right)$使得
$$
\begin{align*}
g&apos;(\eta_{1})&amp;amp;=\frac{g(\frac12)-g(0)}{\frac12}=2g!\left(\frac12\right)&amp;gt;0  \
g&apos;(\eta_{2})&amp;amp;=\frac{g(1)-g(\frac12)}{1-\frac12}=-2g!\left(\frac12\right)&amp;lt;0.&lt;/p&gt;
&lt;p&gt;\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;显然这两个值还可以继续中值&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;继而存在$\xi\in(\eta_{1},\eta_{2})\subsetneq (0,1)$使得:
$$
\frac{g&apos;(\eta_{2})-g&apos;(\eta_{1})}{\eta_{2}-\eta_{1}}=g&apos;&apos;(\xi)
$$
其中$\eta_{2}-\eta_{1}&amp;gt;0$, $g&apos;(\eta_{2})-g&apos;(\eta_{1})&amp;lt;0$。&lt;/p&gt;
&lt;p&gt;于是$f&apos;&apos;(\xi_1)=g&apos;&apos;(\xi_1)+2&amp;lt;2$, 即存在$\xi\in(0,1)$使$f&apos;&apos;(\xi)&amp;lt;2$.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(2) 我们这里用反证法，再走一遍即可得到矛盾&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(2) 假设存在$c\in (0,1)$使得$f(c)\leq c^{2}$, 则:
$$
g(c)=f(c)-c^{2}\leq 0 \
$$
依旧有$g\left( \frac{1}{2} \right)&amp;gt;0$, 则由介值定理，必然存在一个$\chi$介于$c$和$\frac{1}{2}$之间使得$g(\chi)=0$。且$\chi\in(0,1)$。又有$g(0)=0,g(1)=0$, 则由罗尔定理$\exists \eta_{3}\in(0,\chi),\eta_{4}\in (\chi,1)$使得$g&apos;(\eta_{3})=g&apos;(\eta_{4})=0$, 继而$\exists \xi_{2}\in(\eta_{3},\eta_{4})\subsetneq (0,1)$使得$g&apos;&apos;(\xi_{2})=0$。即$f&apos;&apos;(\xi_{2})=2$, 导出矛盾，得证。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;批发$\exists$了啊&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;告一段落...&lt;/h2&gt;
&lt;p&gt;关于中值定理另有一些好题 &lt;em&gt;[27330:30]&lt;/em&gt;, &lt;em&gt;[27330:85]&lt;/em&gt; 等篇幅原因不再细说。但中值定理确实是一题一相，完全没有规律可循，而且难题扎堆。我会把中值定理和定积分并列排为数二最高的山最长的河。（幸好数二不考无穷级数 幸灾乐祸.jpg）&lt;/p&gt;
&lt;p&gt;其他题型或多或少都可以抓住一点通法，或是实在简单的不行。值得一提的是，相当一部分题我都使用了在参考答案官解（太跳脱难以想到）、AI解说盲解（非常繁琐绕远路）之外的第三种我个人思考下的解法。理解这些所有解法对理解有巨大的帮助。&lt;/p&gt;
&lt;p&gt;在此特别感谢Deepseek老师和Gemini老师。我虽然想过，让AI写这篇文章并且自己理解吃透是不是也算是记过笔记了呢，但我发现吃透概念之后自己手痒很难不上手写一段文字，尽管这段文字可能与AI生成文本相比更难让人理解，但..学习嘛，给自己学的。&lt;/p&gt;
&lt;p&gt;微分这篇为什么与极限篇比这么长呢？这篇文章占用了约60%以上的文本量写真题，一方面是我认为真题思路和真题训练是最有效的，另一方面是我发现在这一章里我难以总结什么做题技巧，不像极限篇，真的都是公式化套方法，微分能讲的就那么多，题型倒是百花齐放，日后有想法的话可能会回来补一些定理的基础证明（因为基础证明的理解确实对一些$\varepsilon-\delta$语言的题训练是有效的）。&lt;/p&gt;
&lt;p&gt;技巧倒也不是除了基础知识一点也写不出。比如遇到某一匿名或复杂函数有意去贴合但微小不同于另一简单函数，这时候大概率就要相减，不过这种东西不知道塞哪比较好...&lt;/p&gt;
&lt;p&gt;另外，一些小的desmos示例我保存了，但分享了感觉也没人看，有人要的话我传一下更新一下链接，观感会好很多&lt;/p&gt;
</content:encoded></item><item><title>【学习笔记】数学笔记其三 · 函数、极限、连续</title><link>https://blog.emumu.xyz/posts/2026-07-09-01/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-07-09-01/</guid><description>笔记正式的整理第一期</description><pubDate>Fri, 10 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;如果你是首次进入我的新数学笔记系列，请先&lt;a href=&quot;/posts/2026-07-09-00/&quot;&gt;点此阅读预告回&lt;/a&gt;。&lt;/p&gt;
&lt;h2&gt;计算方法&lt;/h2&gt;
&lt;h3&gt;泰勒展开&lt;/h3&gt;
&lt;p&gt;这是一种几近万能的方法。&lt;/p&gt;
&lt;p&gt;泰勒不是万能的，不会泰勒是万万不能的。对于具体要背哪些形式展开，具体公式在文末。个人经验而言，大部分背三项就够用了。&lt;/p&gt;
&lt;p&gt;“麦克劳林展开”指$x=0$的泰勒展开。麦克劳林展开是最主要（或者说我们一般只用麦克劳林展开）的，其他情况下的展开都会通过偏移改成麦克劳林展开的。&lt;/p&gt;
&lt;p&gt;一般地，要背的展开不仅包含具体函数展开比如$e^x$、$\sin x$的，也必须要包含以下的原始公式:
$$
\begin{align*}
f(x) &amp;amp;= \sum_{n=0}^{\infty} \frac{f^{(n)}(0)}{n!}x^n \
f(x) &amp;amp;= \sum_{n=0}^{\infty} \frac{f^{(n)}(x_0)}{n!}(x-x_0)^n
\end{align*}
$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;上方的&lt;strong&gt;麦克劳林展开式&lt;/strong&gt;会比较频繁地&lt;strong&gt;直接用到&lt;/strong&gt;，也会现推一些简单函数间接用到。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;下方的&lt;strong&gt;泰勒展开&lt;/strong&gt;是不在0展开的更通用的情况，&lt;strong&gt;偶尔也会遇到&lt;/strong&gt;。毕竟考试不是调库，匿名函数真的哪都可能出现。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;另外，除了特殊函数以外，看起来好像不是很特殊的如 $\frac{1}{1+x}$、$\frac{1}{1-x}$、$(1+x)^\alpha$ 也要背(最后一个尤其爱考$\alpha$为分数的情况) &lt;em&gt;[27660: 2,4]&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;关于余项，大部分情况用&lt;strong&gt;皮亚诺余项&lt;/strong&gt;$f(x)=x+x^2+o(x^2)$形式方便化简(比如把它视为$x^2+x^3$处理)，偶尔会用&lt;strong&gt;拉格朗日余项&lt;/strong&gt;
$$
f(x) = \sum_{k=0}^{n}\frac{f^{(k)}(x_0)}{k!}(x-x_0)^k
+\frac{f^{(n+1)}(\xi)}{(n+1)!}(x-x_0)^{n+1},\quad \xi \text{ 在 }x,x_0\text{ 之间} \
e.g.\quad\begin{cases}
\sin x=x - \dfrac{x^3}{6} + \dfrac{\sin\xi}{24},\quad \xi \text{ 在 }0,x\text{ 之间} \
\sin x = x - \dfrac{x^3}{6} + \dfrac{x^5}{120} + o(x^5)
\end{cases}
$$
用于一些证明题收尾或者捷径。 &lt;em&gt;[27660: 16]&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;注意: 那两个重要极限，其一就是$\lim_{x\to0}\frac{\sin x}{x}$, 虽然可以通过泰勒得到。不过$\sin x$的导数本身就是通过这个重要极限定义的，会造成循环论证。&lt;/p&gt;
&lt;p&gt;了解上层定理是通过重要极限推导而来的是必要的。不过用上层定理记忆重要极限也是很方便的。尤其是$e$那个&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;洛必达&lt;/h3&gt;
&lt;p&gt;洛必达(L&apos;Hopital&apos;s Rule)&lt;/p&gt;
&lt;p&gt;简单来说，对于$\frac{0}{0}$和$\frac{\infty}{\infty}$型不定式，对分子分母上下求导。这个比较常用常见，不细说了，看到多项式大力求导就好了 &lt;em&gt;[27330: 8; 27660: 227]&lt;/em&gt; 。但复杂题，尤其是部分涉及导数定义的，一定要看好条件，不要虚空判断:&lt;/p&gt;
&lt;p&gt;对于$\lim_{ x \to a }\frac{f(x)}{g(x)}$, 有使用条件:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;$f(x)$和$g(x)$的极限必须同时为$0$（即$0/0$型）或同时为无穷大（即$\infty/\infty$型）。&lt;/li&gt;
&lt;li&gt;$f(x)$和$g(x)$均满足在$x=a$的某&lt;strong&gt;去心邻域&lt;/strong&gt;内&lt;strong&gt;可导&lt;/strong&gt;。且$g&apos;(x) \neq 0$。&lt;/li&gt;
&lt;li&gt;$\lim_{ x \to a }\frac{f&apos;(x)}{g&apos;(x)}$&lt;strong&gt;必须存在&lt;/strong&gt;。
以上条件可以判断:
$$
\lim_{ x \to a } \frac{f(x)}{g(x)} = \lim_{ x \to a } \frac{f&apos;(x)}{g&apos;(x)}
$$&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;要是随地大小洛，这些条件经常在各种逻辑题里动不动出来咬你一口。比如:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;条件2的某去心邻域可导。在下一节微分学中我们会说到这个命题的地位，以及意味着什么。&lt;/li&gt;
&lt;li&gt;条件3的极限存在。如果$f(x)$和$g(x)$题里&lt;strong&gt;真的是&lt;/strong&gt;$f(x)$和$g(x)$, 尤其要注意这一点。“极限存在”是一个题目很不愿意给的条件。最多可能会给你一个某点导数存在&lt;/li&gt;
&lt;li&gt;洛必达法则是单向的。两侧极限相等并不代表分数线上下的函数谁是可导的。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我习惯这么写: $a \stackrel{L&apos;}{=} b$, 在等号上加一个$L&apos;$, 因为有时候D老师反应不过来这一步用的是洛必达。写上也没有歧义。&lt;/p&gt;
&lt;p&gt;数列极限不能导， 不过可以靠证一些单调之类的性质去转化。 &lt;em&gt;[27660: 225]&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;你可以将非$\frac{0}{0}$和$\frac{\infty}{\infty}$型的不定式爆改成合适的不定式。比如$\lim_{x\to0}x\ln x=\lim_{x\to0}\frac{\ln x}{1/x}$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;第二个重要极限$\lim_{x\to 0}(1+x)^{1/x}$可以通过变形后洛必达得到。当然洛的过程会涉及$\ln(1+x)$的导数$\frac{1}{1+x}$, 依旧循环论证。因为作为重要极限，这个极限也是推导链的起点之一。&lt;/p&gt;
&lt;p&gt;不过也没必要死记硬背了，毕竟这个重要极限变形真的太多，背起来确实容易混淆，大概率也不会真的考数学大厦真基建。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;拉格朗日中值&lt;/h3&gt;
&lt;p&gt;若$f(x)$在$[a, b]$上连续，在$(a, b)$内可导，则存在$\xi\in(a, b)$, 使得$f(b)-f(a)=f&apos;(\xi)(b-a)$&lt;/p&gt;
&lt;p&gt;对于同名异参的构型如
$$
L=\lim_{x\to0} \frac{e^{\sin x}-1}{\sin x}-\frac{e^{\tan x}-1}{\tan x}
$$&lt;/p&gt;
&lt;p&gt;，纯洛+泰勒可以做，但会恶心死人。 &lt;em&gt;[27330: 4,7]&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;更方便的做法是提取出隐含的函数
$$
f(x)=\frac{e^{x}-1}{x}
$$&lt;/p&gt;
&lt;p&gt;然后原式写为: $\lim_{x\to0}\left[ f(\sin x) - f(\tan x) \right] = f&apos;(\xi) \cdot (\sin x - \tan x)$。&lt;/p&gt;
&lt;p&gt;其中，$\xi$ 严格介于 $\sin x$ 和 $\tan x$ 之间。只要写:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;当$x\to 0$时，$\lim_{x\to0} \sin x = 0,\lim_{x\to0} \tan x = 0$, 故 $\lim_{x\to0} \xi = 0$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;就行了。然后导完f直接代0就可以。&lt;/p&gt;
&lt;p&gt;注意: &lt;strong&gt;不能对$\xi$求导！&lt;/strong&gt; 拉格朗日给你的$\xi$只是存在一下，它完全没保证可导，更别提链式法则和洛必达。$\xi$永远只要按仅“存在”进行处理。&lt;/p&gt;
&lt;p&gt;如果你在使用拉格朗日后，发现$\xi$相关的项在消去过程中遇到了复杂的差式（比如式子里留下了$\xi - x$），请立刻放弃改用泰勒。泰勒公式是拉格朗日的精确升级版，能处理更精细的抵消。&lt;/p&gt;
&lt;p&gt;$\xi$支持的性质包括:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;极限可知性&lt;/strong&gt;: 如上，通过夹逼可知$\xi$的具体极限值。如果你夹逼不出来，说明这题不该用拉格朗日中值。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;保号与连续复合&lt;/strong&gt;: 若$g(t)$在$t=0$处连续，则$\lim_{x \to 0} g(\xi) = g(0)$。这一性质允许我们在极限乘积式中将不为0的 $g(\xi)$ 部分直接求极限并提出去。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;等价可换性&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;当 $u(x) \sim x$ 且 $v(x) \sim x$ 时，有&lt;/li&gt;
&lt;li&gt;$\lim_{x \to 0} \frac{\xi}{x} = 1 \implies \xi \sim x$&lt;/li&gt;
&lt;li&gt;这也是$\xi-x$很危险的原因。你总不能两眼一闭把$\sin x-x$写成0吧。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;[27330: 13,248]&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;数列极限&lt;/h3&gt;
&lt;p&gt;数列极限经常很反直觉，因为它是离散的。要修复反直觉，养成离散上的直觉即可。&lt;/p&gt;
&lt;p&gt;举例来说，数列极限$\lim_{n\to\infty}\sin\left(\pi\sqrt{1+n^2}\right)$&lt;/p&gt;
&lt;p&gt;考虑全体实数时，$\sqrt{1+n^2}$项正常地从0向无穷远处连续地单调递增到无穷大。将它放进$\sin$里显然，原式在无穷远处极限震荡。&lt;/p&gt;
&lt;p&gt;只考虑整数时，$\sqrt{1+n^2}$项在整数条件下趋于无穷大时，$1$越来越不起眼，值也趋向$|n|$, 设其趋向整数$k$。$\sin(k\pi)$便是$0$了。&lt;/p&gt;
&lt;p&gt;将上述过程中引入的$k$以$n$的形式与$\sqrt{1+n^2}$对冲，即通过诱导公式引入整数$n$个$\pi$, 在内部相减，制造无穷小$\sqrt{1+n^2}-n$然后殺掉这一项，即可得解。 &lt;em&gt;[27330: 21]&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;夹逼与无穷项&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;无穷项&lt;/strong&gt;和&lt;strong&gt;夹逼准则&lt;/strong&gt;一定程度上绑定，也存在劈叉。&lt;/p&gt;
&lt;p&gt;无穷项最热门的解决方法就是灵活使用夹逼准则，尤其是求和中使用泰勒至$n$和至$n+1$项 &lt;em&gt;[27660: 19; 27330: 23]&lt;/em&gt; 或灵活使用题目第一问提示的不等式夹逼 &lt;em&gt;[27330: 24]&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;单说无穷项，除开夹逼准则以外有很多思想不好归纳，比如:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$n$次项分裂到各个项中以求简化 &lt;em&gt;[27660: 13]&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;裂项相消 &lt;em&gt;[27660: 19,20]&lt;/em&gt;
无穷项是极限整个一章最严厉的父亲。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;单说夹逼准则，它另一个很常用的方法是给 $\sin(\mathfrak{Lorem})$ 赋值为下界$-1$和上界$1$​作为上下界函数，然后快乐地求上下界的极限证等:spoiler[求出来不等就不快乐了]。当你直觉上感到函数震荡但有界或者看起来有难以证开的复杂分式，可以用这个。夹逼相比别的方法很突出的优点是很不容易错。&lt;/p&gt;
&lt;h3&gt;杂项&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;拆指数 $x^y=e^{y \ln x}$&lt;/li&gt;
&lt;li&gt;指数极限交换 $\lim e^f = e^{\lim f}$&lt;/li&gt;
&lt;li&gt;$\arctan{x}+\arctan{\frac{1}{x}}=\frac{\pi}{2}$&lt;/li&gt;
&lt;li&gt;注意极限不能先求加减法中的一部分 &lt;em&gt;[27660: 229]&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;27330:44/&amp;lt;u&amp;gt;90&amp;lt;/u&amp;gt;/★★★☆☆&lt;/h3&gt;
&lt;p&gt;设 $f&apos;&apos;(a)$ 存在，$f&apos;(a) \neq 0$, 求极限:
$$
\lim_{x \to a} \left[ \frac{1}{f&apos;(a)(x-a)} - \frac{1}{f(x)-f(a)} \right]
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我们十分敏锐地注意到:
$$
f(x)=f(a)+f&apos;(a)(x-a)+...
$$
两个分子中，第一个是泰勒第二项展开，第二个是泰勒第二~n项。这题用泰勒做准没跑。先通分还是替换随你。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;$$
\begin{align*}
&amp;amp;=\lim_{x \to a} \left[ \frac{1}{f&apos;(a)(x-a)} - \frac{1}{f(x)-f(a)} \right] \
&amp;amp;=\lim_{x \to a} \frac{f(x) - f(a) - f&apos;(a)(x-a)}{f&apos;(a)(x-a) \cdot [f(x)-f(a)]}
\end{align*}
$$
将泰勒展开式代入分子:
$$
\begin{align*}
&amp;amp;f(x) - f(a) - f&apos;(a)(x-a) \
=&amp;amp; \frac{1}{2} f&apos;&apos;(a)(x-a)^2 + o((x-a)^2)\
=&amp;amp; \frac12(x-a)^2 f&apos;&apos;(a) + o(1)
\end{align*}
$$
代入分母:
$$
\begin{align*}
&amp;amp;f&apos;(a)(x-a) \cdot \left[ f&apos;(a)(x-a) + \frac{1}{2} f&apos;&apos;(a)(x-a)^2 + o((x-a)^2) \right] \
=&amp;amp; f&apos;(a) \cdot (x-a)^2 \cdot \left[ f&apos;(a) + o(1) \right]
\end{align*}
$$
原式
$$
= \lim_{x \to a} \frac{ \frac{1}{2} f&apos;&apos;(a) + o(1) }{ f&apos;(a) \cdot [f&apos;(a) + o(1)] }
$$
当 $x \to a$ 时，$o(1)\to0$, 故:
$$
= \frac{ \frac{1}{2} f&apos;&apos;(a) }{ f&apos;(a) \cdot f&apos;(a) } = \frac{f&apos;&apos;(a)}{2[f&apos;(a)]^2}
$$&lt;/p&gt;
&lt;h3&gt;27330:40/&amp;lt;u&amp;gt;120&amp;lt;/u&amp;gt;/★★☆☆☆&lt;/h3&gt;
&lt;p&gt;设$f(x)$在x=0的某邻域内有连续的一阶导数，且$f&apos;(0)=0$, $f&apos;&apos;(0)$存在，求证:
$$
\lim_{x\to 0} \dfrac{f(x)-f[\ln (1+x)]}{x^3}=\dfrac12f&apos;&apos;(0)
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;看到题目，首先就能简单想到用拉格朗日中值。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;$$
\begin{align*}
&amp;amp;=\lim_{x\to 0} \dfrac{\frac{\mathrm{d}}{\mathrm{d}x}f(x)\vert_{x=\xi} ;\cdot;[x-\ln (1+x)] }{x^3} \
&amp;amp;=\lim_{x\to 0} \dfrac{f&apos;(\xi)\cdot[\dfrac12x^2+o(x^2)] }{x^3}
\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;其中$\xi$在$x$和$\ln(1+x)$之间，所以肯定有$\xi\sim x$, 要约掉。但这里要严谨地写，不能混为一谈。&lt;/p&gt;
&lt;p&gt;我们小学二年级学过，能约掉的本质是分子除以分母等于1。如何保证$\xi$的一阶是$x$不是$2x$呢？研究$\frac\xi x$的值是一种高效的方法.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;其中$\xi$介于$x$和$\ln(1+x)$之间，即$x\to0$时$\xi\to 0$, 又即$\frac \xi x$介于$\frac{\ln(1+x)}x$和$\frac xx$之间.故有$\lim_{x\to 0}\frac\xi x=1$.&lt;/p&gt;
&lt;p&gt;$$
\begin{align*}
&amp;amp;=\lim_{\xi\to 0}\dfrac{f&apos;(\xi)}{\xi}\cdot\lim_{x\to 0} \dfrac{\xi\cdot[\dfrac12x^2+o(x^2)] }{x^3} \
&amp;amp;=\lim_{\xi\to 0}\dfrac{f&apos;(\xi)}{\xi}\cdot\dfrac12 \
\end{align*}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;最后使用导数定义，下一节会讲到&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;$$
\begin{align*}
&amp;amp;=\lim_{\xi\to 0}\dfrac{f&apos;(\xi)-f&apos;(0)}{\xi}\cdot\dfrac12 \
&amp;amp;=\dfrac12f&apos;&apos;(0)
\end{align*}
$$&lt;/p&gt;
&lt;h2&gt;概念综合&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;这一部分主要考察:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;定义性的小题。看起来挺吓人但把所有一元函数的相关概念全说清楚就好了。&lt;/li&gt;
&lt;li&gt;证明大题。考$\varepsilon-\delta$语言&lt;s&gt;怎么还考希腊语&lt;/s&gt; 证明大题实话说随缘过了。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;邻域&lt;/strong&gt; &lt;em&gt;[27660: 253*,255]&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;设$x_0 \in \mathbb{R}$, $\delta &amp;gt; 0$。点$x_0$的$\delta$-邻域定义为
$$
U(x_0,\delta) = { x \in \mathbb{R} \mid |x - x_0| &amp;lt; \delta }.
$$
去心邻域定义为
$$
\mathring{U}(x_0,\delta) = { x \in \mathbb{R} \mid 0 &amp;lt; |x - x_0| &amp;lt; \delta }.
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;有界&lt;/strong&gt; &lt;em&gt;[27660: 234]&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;存在实数$K$使得
$$
\exists K&amp;gt;0,\forall x\in I,;|f(x)|\le K
$$
称$f(x)$在$x\in I$上有界。反之无界。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;左侧极限&lt;/strong&gt;
设函数$f$在$x_0$的某左去心邻域$(x_0-\delta,x_0)$内有定义。若存在实数 $L$ 使得
$$
\forall\varepsilon&amp;gt;0,;\exists\delta&amp;gt;0,;\forall x\in(x_0-\delta,x_0):;|f(x)-L|&amp;lt;\varepsilon,
$$
则称 $L$ 为$f$在$x_0$处的&lt;strong&gt;左侧极限&lt;/strong&gt;，记作$\lim_{x\to x_0^-}f(x)=L$。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;右侧极限&lt;/strong&gt;
设函数$f$在$x_0$的某右去心邻域$(x_0,x_0+\delta)$内有定义。若存在实数$R$使得
$$
\forall\varepsilon&amp;gt;0,;\exists\delta&amp;gt;0,;\forall x\in(x_0,x_0+\delta):;|f(x)-R|&amp;lt;\varepsilon,
$$
则称$R$为$f$在$x_0$处的&lt;strong&gt;右侧极限&lt;/strong&gt;，记作$\lim_{x\to x_0^+}f(x)=R$。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;$\varepsilon-\delta$语言虽然确实不会明晃晃从定义里抠空出来，但是真会拆散了按理解去考。&lt;em&gt;[27660: 215]&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;但是！如果你真的无法理解歪歪扭扭的希腊鬼画符，去看一些视频，知乎找点精品看也是能完成理解的，毕竟它确实真的不会从定义里抠空出来。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;我们现在闭门定义一些符号，因为打latex挺费劲:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$L$: 左侧极限，即$L=\lim_{x\to x_0^-}f(x)$&lt;/li&gt;
&lt;li&gt;$M$: 该点值，即$M=f(x_0)$。&lt;/li&gt;
&lt;li&gt;$R$: 右侧极限，即$R=\lim_{x\to x_0^+}f(x)$&lt;/li&gt;
&lt;li&gt;以上三个都可能不存在。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;存在&lt;/strong&gt;: 函数$f$在点$x_0$处有定义，即$M=f(x_0)$存在且为有限实数。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;邻域存在&lt;/strong&gt;: 存在$\delta&amp;gt;0$使得$U(x_0,\delta)\subseteq\operatorname{dom}f$, 即$f$在$x_0$的整个$\delta$-邻域上有定义。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;极限存在&lt;/strong&gt;: $L,R$均存在且$L=R\in\mathbb{R}$ &lt;em&gt;[27660: 232,235]&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;连续&lt;/strong&gt;: $L,M,R$均存在且$L=M=R\in\mathbb{R}$。 &lt;em&gt;[27660: 250]&lt;/em&gt;
用极限符号表示为
$$
\lim_{x\to x_0^-}f(x)=f(x_0)=\lim_{x\to x_0^+}f(x).
$$
基于以上概念，还有一些我认为比较看阅历的题 &lt;em&gt;[27660: 214]&lt;/em&gt; 。看的什么阅历呢？&lt;/p&gt;
&lt;p&gt;当然是见过的奇奇怪怪的函数的阅历。一条函数能在各个定义域部分表现成什么都是可能的。我十分推荐任何人长期使用&lt;a href=&quot;https://www.desmos.com&quot;&gt;Desmos&lt;/a&gt;或Geogebra这类工具，并且养成去看函数图像的习惯，养成函数图像-几何直觉，以便在各种题里随时举反例，或者知道为什么举不出反例。下面是一些比较有意思的函数，至于性质可以自己搜或者观察:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$f(x) = |x|$&lt;/li&gt;
&lt;li&gt;$f(x) = \begin{cases} 0, &amp;amp; x &amp;lt; 0 \ 1, &amp;amp; x \ge 0 \end{cases}$&lt;/li&gt;
&lt;li&gt;$f(x) = \begin{cases} x^{n}\sin x^{m}, &amp;amp; x \ne 0 \ 0, &amp;amp; x = 0 \end{cases}$ （很有价值，建议多研究）&lt;/li&gt;
&lt;li&gt;$f(x)=xe^x$&lt;/li&gt;
&lt;li&gt;$f(x)=\arctan x$&lt;/li&gt;
&lt;li&gt;狄利克雷函数，如$D(x)=\lim_{n\to\infty}\lim_{m\to\infty}\big[\cos(\pi\cdot m!\cdot x)\big]^{2n}$&lt;/li&gt;
&lt;li&gt;魏尔斯特拉斯函数，如$W(x)=\sum_{n=0}^{\infty}a^n\cos(b^n\pi x)$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;奇偶性、周期性、单调性、有界性&lt;/strong&gt;重要不提，这些概念全均可通过理解图像来理解。一定要定义的话&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;奇函数&lt;/strong&gt;: $f(x)=-f(-x)$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;偶函数&lt;/strong&gt;: $g(x)=g(-x)$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;单调递增&lt;/strong&gt;: $h&apos;(x)\ge0$, 若严格，$h&apos;(x)\gt0$, 单调递减反之。&lt;/p&gt;
&lt;p&gt;我个人十分不愿意背类似“奇*偶=奇”的公式，因为它是真的可以在脑子里推出来的，再不济公式正正负负推一遍也明白了。把东西背下来有两种途径，一个是理解之后多次回想推导，建成了真正的熟能生巧；二是从一开始就死记硬背。后者是很容易背出问题的，你怎么保证到考场上不会紧张背成偶*偶=奇呢。&lt;/p&gt;
&lt;p&gt;基于直觉的一些猜想，比如通过$f(0)$有界，$\lim f(+\infty)$有界，$f(x)$在$x\in[0,+\infty)$连续直觉推导出$f(x)$在$x\in(0,+\infty)$有界，也可以通过练习数学语言描述来尝试证明。&lt;/p&gt;
&lt;h3&gt;27330:12/&amp;lt;u&amp;gt;90&amp;lt;/u&amp;gt;/★★★☆☆&lt;/h3&gt;
&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;设函数$f(x)$在$[0,+\infty]$上连续，且满足$\lim_{x\to+\infty}f(x)=A$, 求$\lim_{x\to+\infty}\dfrac{\int_0^xf(t)dt}x$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;第一眼看到感觉可以用洛必达秒，那就肯定不能了。分母无穷大，观察一下分子:&lt;/p&gt;
&lt;p&gt;$\int_0^xf(t)dt$, 如果A不为0的话必然无穷大。x趋向无穷大的时候f(x)趋向常数A，那么我们可以直接假设从一个点开始f(x)就是A，然后后续直至无穷大不变一直是A。积下来总和就是无穷大。&lt;/p&gt;
&lt;p&gt;为0的话不好说。积出来也可能为0，也可能无穷大，还可能摆动。所以这题最好还是用$\varepsilon-\delta$语言严谨证明。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;（*强烈建议细看完这个流程图再去往下读）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    Start[/&quot;要证&amp;lt;br&amp;gt;原式 = A&quot;/]
    Start --&amp;gt; Convert[&quot;转化为证&amp;lt;br&amp;gt;原式 - A = 0&quot;]

    Convert --&amp;gt; ChooseEps[&quot;任取 ε&amp;gt;0&quot;]
    ChooseEps --&amp;gt; LimitTail[&quot;由\(∞\)f(t)-&amp;gt;A&amp;lt;br&amp;gt;有X1足够大,针对ε/2&amp;lt;br&amp;gt;t&amp;amp;gt;X1时,|f(t)-A|&amp;amp;lt;ε/2&quot;]

    LimitTail --&amp;gt; TailIntegral[&quot;一通乱算后得: &amp;lt;br&amp;gt;∫X1,x 原式&amp;amp;lt;ε/2&quot;]
    LimitTail --&amp;gt; FixedPart[&quot;固定部分G=&amp;lt;br&amp;gt;∫0,X1 \(f\(t\)-A\)dt&amp;lt;br&amp;gt;有界，是常数&quot;]

    FixedPart --&amp;gt; GtoZero[&quot;由\(∞\)G/x-&amp;gt;0&amp;lt;br&amp;gt;有X2足够大,针对ε/2&amp;lt;br&amp;gt;t&amp;amp;gt;X2时|G|/x&amp;lt;ε/2&quot;]

    TailIntegral --&amp;gt; Combine[&quot;取X=max{X1,X2}&quot;]
    GtoZero --&amp;gt; Combine

    Combine --&amp;gt; Final[&quot;当x&amp;amp;gt;X时&amp;lt;br&amp;gt;|(∫₀ˣ f(t)dt)/x - A|&amp;lt;br&amp;gt;≤ ∫0,X+∫X,x原式&amp;lt;br&amp;gt;&amp;lt; ε/2 + ε/2 = ε&quot;]

    Final --&amp;gt; Conclusion[/&quot;由ε的任意性&amp;lt;br&amp;gt;极限为 A&quot;/]
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;要证明，要先了解我们要证明什么。答案很明确，就是A。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;p1.png&quot; alt=&quot;//&quot; /&gt;&lt;/p&gt;
&lt;p&gt;如图所示，$A$​是蓝色区域上边界。我们现在要证明:
$$
\forall\varepsilon\gt0,\exists x:;\left|\frac{\int_0^x f(t)dt}{x} - A \right|\lt\varepsilon
$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;注意此处图中的方程只是举例，一般来说，这种证明题要画图联想的话随便举一个就可以了，只要保证不影响论证部分本身的严谨性。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;欲求$I=\lim_{x\to+\infty}\dfrac{\int_0^xf(t)dt}x$, 则求存在一个$I$使得: 对任意的$\varepsilon &amp;gt; 0$, 都存在一个$X &amp;gt; 0$, 使得当$x &amp;gt; X$时，有:
$$
\left| \frac{\int_0^x f(t)\mathrm dt}{x}-I \right| &amp;lt; \varepsilon
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我们的第一步是将原函数$-A$, 直接攻击$A=0$的情况
$$
\frac{\int_0^x f(t)dt}{x} - A = \frac{\int_0^x [f(t) - A]dt}{x}
$$
&lt;img src=&quot;p2.png&quot; alt=&quot;//&quot; /&gt;&lt;/p&gt;
&lt;p&gt;在这个情况下，证明这个函数$f(x)-A$有限比较容易，主要原因是$\lim_{x\to\infty}[f(x)-A]=0$。这样证右侧有限比较好证。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;已知
$$
\frac{\int_0^x f(t)dt}{x} - A = \frac{\int_0^x [f(t) - A]dt}{x}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;于是，我们总能找到一个分界点$X$使得&lt;strong&gt;左侧部分有限&lt;/strong&gt;，&lt;strong&gt;右侧部分足够小&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;p3.png&quot; alt=&quot;//&quot; /&gt;&lt;/p&gt;
&lt;p&gt;通过$X$的分割，原式被分为以下部分
$$
\left| \frac{\int_0^x [f(t) - A]dt}{x} \right| \le \frac{\left|\int_0^X [f(t) - A]dt\right|}{x} + \frac{\int_X^x |f(t) - A|dt}{x} \
\text{左侧};M(x)=\frac{\left|\int_0^X [f(t) - A]dt\right|}{x}=\frac{|G(X)|}x \
\text{右侧};N(x)=\frac{\int_X^x |f(t) - A|dt}{x}
$$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;左侧部分有限&lt;/strong&gt;，指的是$X$为有限数的条件下，图上的绿色面积$G=\int_0^X[f(x)-A]\mathrm dx$是一个定值，它在$x$增长的条件下($M=\frac Gx$)是不够看的，我们可以用一百种方法忽略它。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;右侧部分足够小&lt;/strong&gt;，是因为$X$需要基于这个右侧来定义得足够大。我们现需要使得右侧的$N&amp;lt;\frac\varepsilon 2$。即:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;设存在$X$, 使得&lt;/p&gt;
&lt;p&gt;$$
\left| \frac{\int_0^x [f(t) - A]dt}{x} \right| \le \frac{\left|\int_0^{X} [f(t) - A]dt\right|}{x} + \frac{\int_{X}^x |f(t) - A|dt}{x} \
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;至于为什么是$\frac\varepsilon 2$, 我只是设计成$M&amp;lt;\frac\varepsilon 2\land N&amp;lt;\frac\varepsilon 2$而已，方便最后整合不等式。&lt;/p&gt;
&lt;p&gt;有了这个$X$之后，便可以使得$N&amp;lt;\frac\varepsilon 2$了，具体来说:
$$
N=\frac{\int_X^x |f(t) - A|dt}{x} &amp;lt; \frac{\int_X^x \frac{\varepsilon}{2} dt}{x} = \frac{\frac{\varepsilon}{2}(x - X)}{x} = \frac{\varepsilon}{2} \left(1 - \frac{X}{x}\right) &amp;lt; \frac{\varepsilon}{2}
$$
如果不知道为什么会想到先让$|f(t) - A| &amp;lt; \frac{\varepsilon}{2}$, 可以从$N&amp;lt;\frac\varepsilon 2$反推一下。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;对于后半部分积分，&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;因为$\lim_{t\to+\infty} f(t) = A$, 故必存在一个足够大的常数$X_1&amp;gt;0$&lt;/strong&gt;，当$t&amp;gt;X_1$时，有$|f(t) - A| &amp;lt; \frac{\varepsilon}{2}$, 由于$t &amp;gt; X_1$, 有$|f(t) - A| &amp;lt; \frac{\varepsilon}{2}$, 因此:
$$
\forall\varepsilon&amp;gt;0,;\exists 0&amp;lt;X_1&amp;lt;x:\frac{\int_{X_1}^x |f(t) - A|dt}{x} &amp;lt; \frac{\frac{\varepsilon}{2}(x - X_1)}{x} &amp;lt; \frac{\varepsilon}{2}
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;接下来是$M$的处理。$M=\frac Gx$中$G$是一个定值，我们现在需要一个足够大的$x$使得$\frac Gx&amp;lt;\frac\epsilon 2$。&lt;/p&gt;
&lt;p&gt;之所以要先处理后半部分，是因为前面要先定死，$G$才能真正作为常数，给出关键的$\lim_{x\to+\infty} \frac{|G|}{x} = 0$。&lt;/p&gt;
&lt;p&gt;注意: 此处的$x$不能使用$X$, 因为要分别使得两个部分各自小于$\frac\varepsilon 2$, 我们要用另一个被定义的$X&apos;$来使得$M(X&apos;)&amp;lt;\frac\varepsilon 2$。&lt;/p&gt;
&lt;p&gt;由于$X$和$X&apos;$分别在使得$M(x)$和$N(x)$小于$\frac\varepsilon 2$的领域上足够大，且它们更大一定使得$M(x)$或$N(x)$更小，那么最终我们就可以取$X=\max{X,X&apos;}$, 使得$M(x)$和$N(x)$都保证小于$\frac\varepsilon 2$, 故可以写$M+N&amp;lt;\varepsilon$。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;对于前半部分积分，由于已确定的$X_1$是一个确定的常数，因此前段积分的值也是一个常数。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;因为$\lim_{x\to+\infty} \frac{\left|\int_0^{X_1} [f(t) - A]dt\right|}{x} = 0$, 故必存在一个足够大的常数$X_2&amp;gt;X_1$&lt;/strong&gt;，当$x &amp;gt; X_2$时，上述两个控制条件同时成立，有:
$$
\forall\varepsilon&amp;gt;0,;\exists X_2&amp;gt;0:\frac{\left|\int_0^{X_2} [f(t) - A]dt\right|}{x}&amp;lt;\frac\varepsilon 2
$$
则取得$X=X_2$, 可以使得:
$$
\forall\varepsilon&amp;gt;0,;\exists X&amp;gt;0:\left| \frac{\int_0^x f(t)\mathrm dt}{x}-A \right|=\left| \frac{\int_0^x [f(t) - A]dt}{x} \right| \le \frac{\left|\int_0^{X} [f(t) - A]dt\right|}{x} + \frac{\int_{X}^x |f(t) - A|dt}{x}&amp;lt;\varepsilon
$$&lt;/p&gt;
&lt;p&gt;原式极限为$A$。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;本题其实可以用广义洛必达去解，属于$\frac*\infty$型，但答案没这么写，我一估摸，显然属于一个纲的超。&lt;/p&gt;
&lt;p&gt;本题标准答案使用积分中值定理。那个虽然巧得很但实在太难想了。就写了一个我自己认为最顺理成章一步步顺下来的思路，当然得分标准下来也比较严格。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;极限存在&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;分辨极限存在不存在、及其条件，或以此求些东西。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;一、极限不存在&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;上一个考点说过，极限不存在，即有以下条件之一:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;左右极限之一不存在&lt;/li&gt;
&lt;li&gt;左右极限不相等 &lt;em&gt;[27330: 17]&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;用两个条件直接代入题环境判断计算即可。这种题型比较简单的&lt;/p&gt;
&lt;p&gt;另按间断点分成四类，包括:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;间断点&lt;/th&gt;
&lt;th&gt;极限&lt;/th&gt;
&lt;th&gt;判据&lt;/th&gt;
&lt;th&gt;举例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;一类&lt;/td&gt;
&lt;td&gt;可去间断点&lt;/td&gt;
&lt;td&gt;在该点存在&lt;/td&gt;
&lt;td&gt;$L=R\neq M$&amp;lt;br&amp;gt;或$f(x_0)$无定义&lt;/td&gt;
&lt;td&gt;$\dfrac{x^2-1}{x-1}$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;一类&lt;/td&gt;
&lt;td&gt;跳跃间断点&lt;/td&gt;
&lt;td&gt;左右分别存在&lt;/td&gt;
&lt;td&gt;$L\neq R$&lt;/td&gt;
&lt;td&gt;$\frac{d}{dx}\vert x\vert$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;二类&lt;/td&gt;
&lt;td&gt;无穷间断点&lt;/td&gt;
&lt;td&gt;至少一侧不存在&lt;/td&gt;
&lt;td&gt;$L$或$R$为$\infty$&lt;/td&gt;
&lt;td&gt;$x^{-1}$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;二类&lt;/td&gt;
&lt;td&gt;震荡间断点&lt;/td&gt;
&lt;td&gt;至少一侧不存在&lt;/td&gt;
&lt;td&gt;震荡。这个我不知道怎么说。&amp;lt;br&amp;gt;或许可以说邻域内有界无极限。嗯就这样&lt;/td&gt;
&lt;td&gt;$\sin x^{-1}$&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;间断点这块纯理解也是很好理解的，只要会灵活举反例 &lt;em&gt;[27660: 223]&lt;/em&gt; 一般不会丢分。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;二、极限存在&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;极限存在比较好证明。最难的那种可以用类似夹逼的方法，只要不震荡，且两侧均有界或者是0即可 &lt;em&gt;[27330: 25]&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;一定要严谨的话，哪怕从定义出发去证也不算是什么很难的题。&lt;/p&gt;
&lt;h3&gt;27330:9/&amp;lt;u&amp;gt;90&amp;lt;/u&amp;gt;/★★★★☆&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;$[x]$表示不超过$x$的最大整数，试确定常数$a$的值，使极限
$$
I=\lim_{x \to 0}\left{ \arctan \frac{2}{x} + \pi \frac{\ln\left(1+\mathrm{e}^{\frac{2}{x}}\right)}{\ln\left(1+\mathrm{e}^{\frac{1}{x}}\right)} + a\left[x^3 - x\right] \right}
$$
存在，并求出此极限。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;先求一下这个极限。注意，$\arctan x$在正负无穷大是不一样的，所以这题肯定和左右极限不同导致的不存在有关系:
$$
\begin{aligned}
\lim_{x\to0^+}\arctan\frac{2}{x}&amp;amp;=\frac{\pi}{2} \
\lim_{x\to0^+}\frac{\ln(1+\mathrm{e}^{\frac{2}{x}})}{\ln(1+\mathrm{e}^{\frac{1}{x}})}
&amp;amp;=\lim_{x\to0^+}\frac{\ln\left[\mathrm{e}^{\frac{2}{x}}\left(\mathrm{e}^{-\frac{2}{x}}+1\right)\right]}{\ln\left[\mathrm{e}^{\frac{1}{x}}\left(\mathrm{e}^{-\frac{1}{x}}+1\right)\right]}
=\lim_{x\to0^+}\frac{\frac{2}{x}+\ln(1+\mathrm{e}^{-\frac{2}{x}})}{\frac{1}{x}+\ln(1+\mathrm{e}^{-\frac{1}{x}})} \
&amp;amp;=\lim_{x\to0^+}\frac{2+x\ln(1+\mathrm{e}^{-\frac{2}{x}})}{1+x\ln(1+\mathrm{e}^{-\frac{1}{x}})}=2 \
x\to0^+&amp;amp;\Rightarrow-1&amp;lt;x^3-x&amp;lt;0\Rightarrow[x^3-x]=-1 \
I_+&amp;amp;=\frac{\pi}{2}+\pi\cdot 2+a\cdot(-1)=\frac{5\pi}{2}-a
\end{aligned}
$$
然后
$$
\begin{aligned}
\lim_{x\to0^-}\arctan\frac{2}{x}&amp;amp;=-\frac{\pi}{2} \
\lim_{x\to0^-}\frac{\ln(1+\mathrm{e}^{\frac{2}{x}})}{\ln(1+\mathrm{e}^{\frac{1}{x}})}
&amp;amp;=\lim_{x\to0^-}\frac{\ln\left(1+\mathrm{e}^{\frac{2}{x}}\right)}{\ln\left(1+\mathrm{e}^{\frac{1}{x}}\right)}
=\frac{\ln(1+0)}{\ln(1+0)}=0 \
x\to0^-&amp;amp;\Rightarrow0&amp;lt;x^3-x&amp;lt;1\Rightarrow[x^3-x]=0 \
I_-&amp;amp;=-\frac{\pi}{2}+\pi\cdot 0+a\cdot0=-\frac{\pi}{2}
\end{aligned}
$$
左右极限相等，则
$$
\frac{5\pi}{2}-a=-\frac{\pi}{2}
a=3\pi
I=-\frac{\pi}{2}
$$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;其他考点&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;递归方程&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;可以用证极限收敛并代回求解的方式做&lt;/li&gt;
&lt;li&gt;证单调、证有界等对函数的法子有时候也是有效的 &lt;em&gt;[27330: 26]&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;如果真不太好做，肉眼归纳法也是一种方法 &lt;em&gt;[27660: 22]&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;附&lt;/h2&gt;
&lt;p&gt;常用&lt;/p&gt;
&lt;p&gt;$$
\begin{aligned}
e^x &amp;amp;= 1+x+\frac{x^2}{2!}+\frac{x^3}{3!}+o(x^3) \
\ln(1+x) &amp;amp;= x-\frac{x^2}{2}+\frac{x^3}{3}+o(x^3) \
\sin x&amp;amp;= x-\frac{x^3}{3!}+\frac{x^5}{5!}+o(x^5) \
\cos x&amp;amp;= 1-\frac{x^2}{2!}+\frac{x^4}{4!}+o(x^4) \
\tan x&amp;amp;= x+\frac{x^3}{3}+\frac{2x^5}{15}+o(x^5) \
(1+x)^\alpha &amp;amp;= 1+\alpha x+\frac{\alpha(\alpha-1)}{2!}x^2+o(x^2) \
\end{aligned}
$$
不太常用
$$
\begin{aligned}
\frac{1}{1-x}&amp;amp;= 1+x+x^2+x^3+o(x^3) \
\frac{1}{1+x}&amp;amp;= 1-x+x^2-x^3+o(x^3) \
\sinh x&amp;amp;= x+\frac{x^3}{3!}+\frac{x^5}{5!}+o(x^5) \
\cosh x&amp;amp;= 1+\frac{x^2}{2!}+\frac{x^4}{4!}+o(x^4) \
\arcsin x&amp;amp;= x+\frac{1}{6}x^3+\frac{3}{40}x^5+o(x^5) \
\arctan x &amp;amp;= x-\frac{x^3}{3}+\frac{x^5}{5}+o(x^5) \
\end{aligned}
$$&lt;/p&gt;
</content:encoded></item><item><title>【学习笔记】数学笔记其2.5 · 预告回</title><link>https://blog.emumu.xyz/posts/2026-07-09-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-07-09-00/</guid><description>打算正式搞一搞学习笔记</description><pubDate>Thu, 09 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;数学，我用了一种D老师称之为剽悍、Gmn老师称之为野路子、豆包“绝对不要”的刷题方法: 不刷课、不看讲义、硬做题。所以知识点是很碎片化的。好处是提前(6.6就刷完了330)摸到了很深层的东西，坏处是地基是支离破碎的。浅做了一张模拟卷，81分，不高不低。&lt;/p&gt;
&lt;p&gt;费曼学习法是非常有效的。简单来说，就是尝试去教别人。但由于我十八级社恐属性，很难找到人落实并做到这一点。但学完并码完&lt;a href=&quot;/posts/2026-04-24-00/&quot;&gt;这个文章&lt;/a&gt;之后，我突然发现写博客其实能很好地达成这个目的。这是我自建博客以来认为博客带给我第二大的帮助。第一大是前端系列知识的习得。&lt;/p&gt;
&lt;p&gt;所以这几天打算通过博客仔细写一套笔记，得到了各赛博老师的一致高度认可。当然&lt;strong&gt;我的整理并不一定适合你，也不一定全，甚至不一定对&lt;/strong&gt;，完全为我个人复习服务。请保持批判性阅读，发现错误也请纠正我谢谢。&lt;/p&gt;
&lt;p&gt;正文里的题目标记:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;[27660: 123]&lt;/em&gt; 指 &lt;strong&gt;27&lt;/strong&gt;版&lt;strong&gt;660&lt;/strong&gt;题的第&lt;strong&gt;123&lt;/strong&gt;题。&lt;/li&gt;
&lt;li&gt;&lt;em&gt;[21302: 15]&lt;/em&gt; 指 &lt;strong&gt;21&lt;/strong&gt;年统考数二(&lt;strong&gt;302&lt;/strong&gt;)的第&lt;strong&gt;15&lt;/strong&gt;题。&lt;/li&gt;
&lt;li&gt;同理有330,880,1k这类能猜出来是什么的练习册代号。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;题号加*表示特殊例。&lt;/p&gt;
&lt;p&gt;六月份尝试性地，我简单尝试写了一下极限那章的内容，发现复习效果还是不错的，尤其是有时候能嚼透之前扔下的硬骨头这一点。所以打算今天重制一下之前极限那章，然后就此开始把整本书复习一遍&lt;/p&gt;
&lt;h3&gt;27330:45/&amp;lt;u&amp;gt;120&amp;lt;/u&amp;gt;/★★★★☆&lt;/h3&gt;
&lt;p&gt;第一段是题目内容&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这表示一个真题的讲解。真题题解大部分是讲330或者真题的大题，这个格式是指:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;27年版330题&lt;/li&gt;
&lt;li&gt;第45题&lt;/li&gt;
&lt;li&gt;参考目标分数120分(练习册标定)，难度4/5星。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这种引用块中的内容表示解题的思路、讲解等非题目上纸步骤的内容。对应地:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在引用块之外的内容是解答的正式部分。去掉所有引用块就是本题的完整解答。&lt;/p&gt;
</content:encoded></item><item><title>解决腾讯云Pages(Maker)pnpm安装依赖ERR_PNPM_IGNORED_BUILDS</title><link>https://blog.emumu.xyz/posts/2026-06-12-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-06-12-00/</guid><description>解决报错[ERR_PNPM_IGNORED_BUILDS] Ignored build scripts: esbuild@0.27.2Run &quot;pnpm approve-builds&quot; to pick which dependencies should be allowed to run scripts.</description><pubDate>Fri, 12 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;pnpm v11 对构建脚本的安全管控做了重大升级，所有非授权包的构建脚本默认拦截，且配置入口完全迁移到了 &lt;code&gt;pnpm-workspace.yaml&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;正确做法：在项目根目录新建 &lt;code&gt;pnpm-workspace.yaml&lt;/code&gt; 文件，写入：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;allowBuilds:
  esbuild: true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;推送即可。这是官方标准方案。&lt;/p&gt;
&lt;p&gt;就在今天，* EdgeOne Pages 现已升级为 EdgeOne Makers，在原有 Web 全栈开发能力之上，新增对 AI Agent 的原生支持。原有产品逻辑与功能保持不变。* ——&lt;a href=&quot;https://cloud.tencent.com/document/product/1552/127366&quot;&gt;边缘安全加速平台 EO 产品简介_腾讯云&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;常见网传与AI错误答案大集合：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;安装命令改为 &lt;code&gt;pnpm approve-builds esbuild &amp;amp;&amp;amp; pnpm install&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;approve-builds&lt;/code&gt;只能审批已经被安装检测到的待执行脚本，提前运行时还没有任何包触发拦截，审批完全无效；再加云端容器每次都是全新环境，本地审批状态也不会被继承。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;--ignore-builds=false&lt;/code&gt;和&lt;code&gt;--ignore-scripts=false&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;ignore-builds&lt;/code&gt;是AI幻觉参数。幻觉来源就是&lt;code&gt;ignore-scripts&lt;/code&gt;。&lt;code&gt;ignore-scripts&lt;/code&gt;管通用的生命周期脚本执行，管不了v10+新增的构建脚本强制审批规则（由&lt;code&gt;strictDepBuilds&lt;/code&gt;控制），二者互不影响。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;package.json&lt;/code&gt;配置&lt;code&gt;pnpm.onlyBuiltDependencies&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这是一个过时的配置。使用这个配置就会看到控制台报错，提示你用正确的配置。我就是从这个方法踩坑过来的。&lt;/p&gt;
</content:encoded></item><item><title>月宫小站 · 实验室震撼首发</title><link>https://blog.emumu.xyz/posts/2026-05-31-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-05-31-00/</guid><description>实验室集成了各种奇思妙想小东西！有些说不定真有用哦……</description><pubDate>Sun, 31 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;如何前去&lt;/h2&gt;
&lt;p&gt;本博客中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;电脑端&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;点击导航栏的“实验室”。&lt;/li&gt;
&lt;li&gt;或，鼠标中键点击这个链接：&lt;a href=&quot;https://lab.emumu.xyz/&quot;&gt;https://lab.emumu.xyz/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;移动端&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;点击右上角菜单，选择“实验室”。&lt;/li&gt;
&lt;li&gt;或在下方复制链接访问。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;https://lab.emumu.xyz/
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;小站主题及功能募集&lt;/h2&gt;
&lt;p&gt;暂定第一主题是一键解决数学建模竞赛乃至科研中相关的各种痛点，包括公式转换、针对Word等排版工具的格式化等等等等。无论你使用怎样的工具链，只要你需要的功能是简单而机械化的，是你觉得“应该是机器去完成而不是手动做的”，我会尽可能去实现（当然不要说一些不切实际的功能比如一键生成完整论文）&lt;/p&gt;
&lt;p&gt;如果你真的很不确定需要的工具是否是能实现的，可以截图这个页面问问AI那个功能能不能通过网站实现。放心如果真遇到问题我会以各种方式推辞拖延的（&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;不限于数学建模哦&lt;/strong&gt;，合适的工具包括各类站长工具、甚至小游戏可能都会做。&lt;/p&gt;
&lt;p&gt;依赖后端，尤其是存储服务的可能会有较低优先级，但如果呼声非常高（比如自有随机图API）也会优先做。&lt;/p&gt;
&lt;p&gt;最后，&lt;s&gt;EO Pages免费一天，小站就免费一天&lt;/s&gt; 得益于EO Pages的免费政策，小站会一直为大家免费服务下去。:spoiler[D老师说我那么说不太好感觉像会随时跑路，改一下]&lt;/p&gt;
&lt;h2&gt;唠点真正想唠的&lt;/h2&gt;
&lt;p&gt;吧。其实可以再开一集新建文件夹，但无所谓了。那边还有题材没写。&lt;/p&gt;
&lt;p&gt;下面是碎碎念了，路过的朋友可以去&lt;a href=&quot;https://lab.emumu.xyz/&quot;&gt;实验室逛逛&lt;/a&gt;了，真的对这个实验室站感兴趣的可以继续看下去&lt;/p&gt;
&lt;p&gt;网上各种在线工具参差不齐、风格不一、不保可用性、功能不完整是一直困扰我的，故此，一个工具站是一直以来都是我想做的。从大一开始想做文件快递柜、大二想做LaTeX编辑器、大三搓了一个学习进度工具壁纸，最后都因为各种各样的原因鸽掉或者删掉了。原因各式各样但归根结底是经验不足。&lt;/p&gt;
&lt;p&gt;偶然接触到博客圈之后，看到一些人的网站都有一个“实验室”，里面有一些可能不实用但是很好玩的小东西。我就在想什么时候自己也做一个“实验室”，开放意见并提供一系列可靠的服务，但这个意见通道若不是像qq群一样即时而深度绑定的又起不到作用，但又作为一个工具站，可能你打开一次之后就不会再打开第二次，绑定对双方都是徒劳的。&lt;/p&gt;
&lt;p&gt;除非工具站有一个主题，使用主题，或者其他方式，吸引了一批实在的长期用户。&lt;/p&gt;
&lt;p&gt;偶然间我发现了一个搜索引擎很照顾的工具站&lt;a href=&quot;https://toolwa.com/&quot;&gt;工具哇&lt;/a&gt;，这个站点不仅用大气统一的风格集结了一眼望不到头的工具，甚至还真的集成了一个小论坛。突然就发现，这个目标也不是那么难。&lt;/p&gt;
&lt;p&gt;于是我着手去查这件事的相关资料，当然最多的还是问AI可实现性。&lt;/p&gt;
&lt;p&gt;那些工具99%都是前端工具。纯前端建个站的话，我会。&lt;/p&gt;
&lt;p&gt;但没什么创新性。为了建站而建站不是我想要的，至少文件快递柜我还是想做。但后端……服务器钱确实出不太起，况且安全这块我并不是非常明白，防御战术鼓舞还没打出来，暂时没什么动力推进。&lt;/p&gt;
&lt;p&gt;另一个偏好是我&lt;strong&gt;在不被背刺的前提下&lt;/strong&gt;比较喜欢支持国内基础设施，所以我顺理成章地把目光转到了EdgeOne Pages Function上，期待它能给我弄出点什么比肩cf的东西，或者至少能起到代替后端的作用。好消息：理论全部可行，坏消息：代码会很费事。看我前几篇文章就能看出来了。腾讯云那边也是最近才开始猪突猛进推Serverless，KV存储刚出来我就开始研究，最近又出了Blob存储，暂时还没什么兴趣研究。&lt;/p&gt;
&lt;p&gt;前端则是选了处在知识盲区的React，当然实际使用的是Preact。&lt;/p&gt;
&lt;p&gt;开心的讨论和选型就到这里了，接下来是讨厌的工作时间。&lt;/p&gt;
&lt;p&gt;Deepseek V4出的时间简直刚刚好，好到我刚把基础的样式框架做好它就出现了，好像专门为我进入AI时代准备一样。一顿提示词风暴之后，我也成功依赖上了AI工作流。现在AI的代码真的很容易就能做到可预测，和模型本身有关，和我过去几个月的学习也有关。&lt;/p&gt;
&lt;p&gt;我很希望通过SPA把很多界面放到一起瞬间切换，但这样主bundle会很大，不太好。我首先想出将子应用提取为独立MPA形式，保持独立应用各自的风格，但在EO Pages体系下，不是很好实现，只能用&lt;code&gt;/index.html&lt;/code&gt;这种丑陋的后缀达到，所以我其次想到，且目前项目中充满了各种动态import和大库的初始化逻辑，比较后悔没早做好优雅的动态导入，导致AI流接入后的现在耦合严重，不知道怎么重构。还是那个道理，用AI、调包、不知道底层原理，迟早会吃亏，Vite不除外。&lt;/p&gt;
&lt;p&gt;还有tailwindcss v4配置、主题样式变量设计这种烦人的活计。不过就成品来说，也算是走出了一点自己的前端风格。商务不商务娱乐不娱乐的，怪怪的。&lt;/p&gt;
&lt;p&gt;值得一提的是我现在使用IndexedDB做前端存储，容量短时间内不愁了。IndexedDB的API设计的个人感觉有点反人类，于是我包了一层KV拿来用，手感还是很不错的。&lt;/p&gt;
&lt;p&gt;说到KV，最近真是把KV手动索引狠狠玩了一遍。EO的KV代数据库真是有点头疼，我也是尽可能保持最多只用一个反向索引尽可能完成这件事。&lt;/p&gt;
&lt;p&gt;后端是如此，但我到底为什么要把前端的DB包装成KV，然后手动做一遍索引呢？唉破收藏系统，过几天就重构。我还要做文件夹，还要做收藏夹同步，还要做多端分别在侧栏展示不同收藏夹。扯远了。&lt;/p&gt;
&lt;p&gt;无论怎么样，屎山是一定会形成的，AI只是加速了这个过程。&lt;/p&gt;
&lt;p&gt;PWA应用依旧AI指导。&lt;/p&gt;
&lt;p&gt;差不多就这些东西了。杂谈到此为止。修那个破SEO去了。&lt;/p&gt;
</content:encoded></item><item><title>最新Deepseek V4 Pro数学建模SOLO工作流</title><link>https://blog.emumu.xyz/posts/2026-05-10-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-05-10-00/</guid><description>面向零编程、零论文基础但走过一次数模流程的选手，一套基于Deepseek V4 Pro和Trae的纯SOLO数学建模工作流。从宏观建模、逐题求解到论文自动拼接输出，全部AI驱动，单次开销30元以内的完整实操指南。</description><pubDate>Fri, 15 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;:::tip
本文面向零编程、零论文、有数模基础人群，但你必须会基本的电脑操作，最好还自己弄过盗版资源和破解流程。&lt;/p&gt;
&lt;p&gt;有数模基础指至少参加、完整走过流程并成功提交过一次的选手。本工作流通过脚本和AI自动化了很多内容，&lt;strong&gt;如果你完全不会手动进行这些过程的步骤，请谨慎使用，出问题不保修。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果你有编程或论文基础，这个工作流会让你更加高效。&lt;/p&gt;
&lt;p&gt;本文重点面向弱校一带二或零队友人群，需要你有较强的自学能力。
:::&lt;/p&gt;
&lt;p&gt;数学建模是一个团队比赛。一般来说，比起传统的&quot;建模手/编程手/论文手&quot;配置的表面工程多线程，有效的团队都是三人一起讨论建模、一起编程、一起同步写论文的。&lt;/p&gt;
&lt;p&gt;当然我几乎没体验过这一点，上面的说法只是国赛大神们的自述与我的想法契合的部分而已。我今天要介绍的工作流是一个&lt;strong&gt;纯Solo&lt;/strong&gt;、&lt;strong&gt;充分利用人类优势进行创新&lt;/strong&gt;、基于DeepSeek V4、&lt;strong&gt;开销30R&lt;/strong&gt;以内的工作流。&lt;/p&gt;
&lt;h2&gt;快速开始&lt;/h2&gt;
&lt;p&gt;:::warning
开始之后，强烈建议你将这篇文章读完，而不是直接当场扔给AI。
:::&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;下载Trae &lt;strong&gt;IDE&lt;/strong&gt; &lt;a href=&quot;https://trae.cn&quot;&gt;点击前往官网&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;下载Git &lt;a href=&quot;https://git-scm.com/install/windows&quot;&gt;点击前往官网&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;在桌面创建一个文件夹，右键选择通过Trae打开&lt;/li&gt;
&lt;li&gt;复制并在Trae聊天框中输入以下内容以继续：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;1. 使用`git clone https://github.com/emumus/mathmodel-workflow.git .`直接克隆仓库到当前项目文件夹。
2. `uv sync`，然后阅读README.md。
3. 阅读 https://blog.emumu.xyz/posts/2026-05-10-00/ 深入理解项目
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;相关repo(打不开没关系正常):&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;emumus/mathmodel-workflow&quot;}&lt;/p&gt;
&lt;h2&gt;必须学习的东西&lt;/h2&gt;
&lt;h3&gt;1. 数学模型本身&lt;/h3&gt;
&lt;p&gt;理解基本数学模型是创新的基础，也是看懂ai出的图的基础。对模型的了解直接决定你能否做出合适的创新。&lt;/p&gt;
&lt;p&gt;最近(2026-05-30)我的一次校赛结果展示，“完成”一篇论文似乎已经不足为奇。实际来说，一篇格式没有问题但毫无创新点、图片平平无奇、结论中规中矩没有重大失误的文章在二本校赛里已经排不上优秀奖，只剩完赛奖了。两年前这样的论文至少是能得二等的。&lt;/p&gt;
&lt;p&gt;反之用同一工作流的我的格式与其完全相同，但注入了创新点:spoiler[纯硬创，奶茶加螺母那种~]和大量个人认为好看的图，以及最重要的正文篇幅28页。实际上拿到了个二等。&lt;/p&gt;
&lt;p&gt;不妨大胆预测一下，以后的数学建模恐怕会彻底消除代码隔阂、论文语言隔阂，让各种经验下的参赛者都真正集中于数学模型本身，就像这个工作流所期待的那样，模型和答案的合理性成为唯一入场券，图片的表达和创新会成为高处拉开分数差距的地方。&lt;/p&gt;
&lt;h3&gt;2. Markdown格式&lt;/h3&gt;
&lt;p&gt;这是生成式AI最常用的回复格式，它可以让AI改论文时大幅减轻上下文负担。&lt;/p&gt;
&lt;p&gt;这是一种与Office Word(可视化型)和LaTeX(基本是一个自足的排版系统)完全不属于同一分支的富文本格式，严格来说它属于第三个分支：HTML分支。虽然HTML已经够简单了，但Markdown在此之上还要更加简单。关于Markdown的语法网上已有巨量成熟教程且学习基本不超过5min，此处不再赘述。&lt;/p&gt;
&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Markdown 极其接近纯文本，只有极少的标记或格式，但仍能表示重要的文档结构。主流 LLMs，例如 OpenAI 的 GPT-4o，原生地“说”Markdown，并经常在未被提示的情况下将其融入回答中。这表明它们已在海量 Markdown 格式文本上训练过，并对其理解透彻。作为附带优点，Markdown 惯例也极具 token 效率。—— &lt;a href=&quot;https://github.com/microsoft/markitdown&quot;&gt;microsoft/markitdown&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;h2&gt;基本工具链&lt;/h2&gt;
&lt;h3&gt;1. Trae&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.trae.cn&quot;&gt;点击此处前往官方网站&lt;/a&gt;，注意下载Trae IDE，无需多虑直接下载国内版（除非你知道自己在做什么）。&lt;/p&gt;
&lt;p&gt;Trae本质上是一个AI辅助代码编辑器，但它不只能编辑代码，也能通过Markdown格式编辑论文。这将是我们的主力战场。&lt;/p&gt;
&lt;p&gt;&amp;lt;details&amp;gt;
&amp;lt;summary&amp;gt;&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;如果你从来没碰过代码项目或者Trae或类似AI代码编辑器，点我查看基础教程&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/summary&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Trae IDE打开的代码项目都基于一个文件夹，编辑代码后都需要通过&lt;code&gt;Ctrl+S&lt;/code&gt;保存，文件名后面的小白点指示了文件是否被动过，即是否需要保存。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IDE&lt;/strong&gt;指集成开发环境，环境里有你能看到的文件展示区、编辑区等。Trae这类则是集成了AI的超级环境，在这个软件内，&lt;strong&gt;AI可以按需自己挑选并阅读所有他想看的文件（而无需手动复制给他）&lt;/strong&gt;，大幅提高效率，同时它还能自动运行代码、自己处理自己代码中&lt;strong&gt;和代码外&lt;/strong&gt;无法运行的问题等（这称之为Agent能力，而Deepseek V4在这一点上十分强）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;p6.png&quot; alt=&quot;主界面&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Trae是基于VSCode开发的，继承VSCode插件体系，你可以添加包括Python插件在内的一系列插件提升使用体验，需要什么功能可以问问它。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;模型&lt;/strong&gt;是这类AI IDE的内核，通俗讲就是用什么AI去做这件事。比如豆包，肯定是做不成的。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Trae提供的Auto模型通常效果很差，高级模型又通常需要等待，故此强烈建议添加自己的Deepseek API。&lt;/strong&gt; Deepseek V4是截止本文目前最便宜而能用的大模型，也是此工作流中唯一的付费节点。建议使用V4 Pro，没贵多少、但是为此强一点确实有必要。&lt;/li&gt;
&lt;li&gt;你可以&lt;a href=&quot;https://platform.deepseek.com/&quot;&gt;点击此处前往DeepSeek开放平台&lt;/a&gt;注册充值获取。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;p1.png&quot; alt=&quot;添加自有API Key避免等待&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;p2.png&quot; alt=&quot;完成效果&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Skill&lt;/strong&gt;，通俗来说就是一套的被压缩的提示词和脚本，AI能获取Skill的一小部分介绍，并自行考量使用与否。当AI真的需要使用Skill中的流程时，它会自行获取Skill中的提示词、执行Skill中的代码。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;p3.png&quot; alt=&quot;&quot; /&gt;
&amp;lt;/details&amp;gt;&lt;/p&gt;
&lt;p&gt;工作区文件夹包含我们所有获得和途中收集、生成、需要记录的题目、思路、代码、图、论文等。它们分别在不同的文件夹里，形成一套规范，这套规范由AI遵守，由人类享受，避免混乱。&lt;/p&gt;
&lt;p&gt;我配置了两个skill：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;OpenAlex文献检索&lt;/strong&gt;：自动定位相关论文，搜集引用所需信息。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数学建模主技能&lt;/strong&gt;：贯穿所有阶段的流水线。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这两个skill我会放在.trae下，它会自动读取。&lt;/p&gt;
&lt;h3&gt;2. Typora&lt;/h3&gt;
&lt;p&gt;Typora是一个Markdown编辑器，它最大的特点是可以将Markdown文章直接渲染成PDF，而且还支持自定义主题，甚至将自定义主题渲染出来。&lt;/p&gt;
&lt;p&gt;我基于某一开源主题自改了一版用于数模论文的主题，可以直接预览论文格式。由于年代久远(一年多吧)，原库难以检索，如有线索欢迎回复，我会积极遵循原库的License重新发布。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;注意，Typora是一个付费软件。本站不提供任何关于破解软件的服务。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://typoraio.cn/&quot;&gt;点击此处前往官方网站&lt;/a&gt;，其官网支持支付宝支付，代理商数码荔枝处也支持微信支付。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;此工作流日后可能更新为基于pandoc转换的下位替代，但Typora软件的所见即所得、pdf导出、自动页码等功能的便利性不会改变。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;3. 辅助工具&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;X-Mouse Button Control&lt;/strong&gt;：极其强大的鼠标宏工具，带有详尽的文档(英语的)和屏幕位置获取器。其最大优势在于&lt;strong&gt;宏可以通过代码描述&lt;/strong&gt;。通过AI技能生成宏代码，那么对于某些难以自动化的重复性桌面操作（如Office下的重复型任务）也能全效工作。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Cherry Studio&lt;/strong&gt;：分担零碎任务，比如查证某个知识点、写一条 Excel 公式。专门设了一个技能，用来快速生成X-Mouse Button Control的配置宏&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;工作区&lt;/h2&gt;
&lt;p&gt;项目根目录下，我强制划分了这几个文件夹：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;project-root/
├─ doc/         # [不变] 给AI看的分阶段任务说明
├─ utils/       # [不变] 工具脚本与样式
├─ ques/        # [不改] 原始问题描述
├─ cit/         # [不改] 下载的论文、原始数据集
├─ code/        # 所有探索性代码与中间数据，不进入正式论文
│  ├─ raw/      # 探索阶段的 .py 文件，命名可随意如q1_v1.py
│  └─ q1/...    # 最终冻结后的拆分代码，日后会直接进入论文附录
│      └─ img/  # 代码产出的图片目录，会直接用于论文正文
├─ text/        # 一切过程文本：分析、草稿、半成品、成品论文
│  ├─ raw/      # 模型分析与求解过程记录
│  ├─ paper/    # 生成论文的各个章节块及合并文件
│  ├─ appendix/ # 额外的附录，可以无
│  └─ frozen/   # 生成拼接好的Markdown形式论文和完整附录
└─ frozen/      # 脚本会自动在此文件夹中创建打包好的论文,参考资料,md5信息
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;doc, utils&lt;/strong&gt;: 该文件夹存储一些执行文档以供AI阅读、一些工具代码以供AI使用。作为工作区的初始资源不变地存在。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ques, cit&lt;/strong&gt;: ques存放题目原文件、提取的题目原文.md、原始附件等原始题目信息，不能跑题这件事是很重要的。cit存放引用的原数据、原论文，很多赛参考资料要求一起打包。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;code&lt;/strong&gt;: 所有题没有敲定方案（也就是没完全确定论文里要写什么）之前都要在&lt;code&gt;code/raw/&lt;/code&gt;里写代码。这里可以让ai随意造次，反正最后也是它收拾。在敲定任一道题的方案后，我们可以让AI确定、提取最终的代码到&lt;code&gt;code/qX/&lt;/code&gt;中，不要其他无关的代码。这里的代码应当是能跑通的最小代码。同时，这个文件夹也锁定的图。这个文件夹应当有数个最小代码和数个画图代码。画图代码以&lt;code&gt;q*_draw_*py&lt;/code&gt;命名，这个规范使得画图代码不会流入论文正文。脚本会提取&lt;code&gt;code/qX/&lt;/code&gt;中的代码作为最终论文的一部分。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;text&lt;/strong&gt;: 所有题没有敲定方案之前，依旧要在&lt;code&gt;text/raw&lt;/code&gt;中进行结果的记录、思路的分析等。这包括之前都做过什么，结果如何。有助于敲定论文中对照分析的对象，也能让我们能看到它的模型思路。在&lt;code&gt;text/paper&lt;/code&gt;中存在多个&lt;code&gt;d_xxx.md&lt;/code&gt;，其中&lt;code&gt;d&lt;/code&gt;是一个数字，表示该段落是论文的第几部分。这个数字可以但不建议使用小数，只有在临时起意插入段落且不想逐个重命名时可以启用，如&lt;code&gt;4.5_敏感性分析.md&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;没搞懂？&lt;a href=&quot;#%E6%B5%81%E6%B0%B4%E7%BA%BF&quot;&gt;直接看流水线就完了↓&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;流水线&lt;/h2&gt;
&lt;h3&gt;阶段一：宏观建模&lt;/h3&gt;
&lt;p&gt;你需要读题、讨论整道题目的类型、方案等。这个过程中记录大体的模型选型、可能性等。&lt;/p&gt;
&lt;p&gt;&amp;lt;details&amp;gt;
&amp;lt;summary&amp;gt;对话例&amp;lt;/summary&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;[用户]&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;继续。问题3要求预测人口数量变化。预测函数首先要有函数。一个标准的人口拟合模型需要在问题2建立。大体上是人口=f(时间,*地区特性,*实行政策)。人口这个东西显然有很大惯性，我很想用微分方程去做这个事，但弄不好就会弄巧成拙。次选是决策树，决策树处理政策的0-1是比较好的。复合模型的话也可以用，但那样决策树可能要高度人工干预，不太纯，主观。最好今天能决定一个方向。基于问题1的分类，问题2要服务于问题3，问题4的预测模型实际上是问题3中预测模型针对政策的敏感性分析。各个政策作为参数恐怕不好。我认为实际上可以按政策深度分类。事实上，政策的实行和按指标的分类是有必然共同趋势的，所以问题一有一个必然优秀的解是基于基本指标，与当时实行的政策分类相同。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;[AI]&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;你的思考越来越深入了。我来帮你系统梳理一下你提出的几个关键决策点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;人口模型的函数形式&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;……&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;无政策 = 去掉政策影响项，仅保留自然趋势&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;……&lt;/p&gt;
&lt;p&gt;你提到的几个方向，我帮你对比一下：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;模型方向&lt;/th&gt;
&lt;th&gt;优势&lt;/th&gt;
&lt;th&gt;风险&lt;/th&gt;
&lt;th&gt;适合程度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;微分方程（如Leslie矩阵）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;符合人口惯性特征，年龄结构自然纳入&lt;/td&gt;
&lt;td&gt;政策变量难以嵌入，处理0-1政策变量不自然&lt;/td&gt;
&lt;td&gt;⭐⭐⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;……&lt;/p&gt;
&lt;p&gt;| &lt;strong&gt;结构化的差分方程模型&lt;/strong&gt; | 结合人口学经典方法，可嵌入政策参数 | 需要合理设定参数形式 | ⭐⭐⭐⭐⭐ |&lt;/p&gt;
&lt;p&gt;……&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;结构化人口模型（差分方程/Leslie矩阵） + 政策参数调制&lt;/strong&gt;，理由如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;人口惯性&lt;/strong&gt;是天然的一阶/二阶差分结构，微分/差分方程最自然&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Leslie矩阵&lt;/strong&gt;能天然处理年龄结构，而年龄结构是人口预测的核心&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;政策可以作为矩阵元素的调制参数&lt;/strong&gt;——比如生育政策影响出生率（矩阵第一行），教育/医疗政策影响存活率（矩阵对角线）&lt;/li&gt;
&lt;li&gt;这样问题4的&quot;有/无政策&quot;就是&lt;strong&gt;开关调制参数&lt;/strong&gt;，非常直观
你觉得这个方向怎么样？还是你更倾向于坚持微分方程的思路？&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;[用户]&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;你这个选型好，我基于你这个选型说……&lt;/p&gt;
&lt;p&gt;那么现在所有问题的分析都差不多了。我们需要通过找出区域的一些特征进行分类完成问题1，题目指明了要“地区人口、人口性别、年龄、受教育情况、城乡人口和流动人口”。并且“基于第四次至第七次全国人口普查的主要数据”。我们选择的参数最好要能直接与人口的y,y&apos;甚至y&apos;&apos;相关。&lt;/p&gt;
&lt;p&gt;……&lt;/p&gt;
&lt;p&gt;决定一个城市发展速度的参数很多，但中国有大量城市……这反而造就了不界限分明的边界……&lt;/p&gt;
&lt;p&gt;另外提一嘴，我不知道能不能进行类别状态机的构造，以此去拟合一些……&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;lt;/details&amp;gt;&lt;/p&gt;
&lt;p&gt;不包括整理数据，这个阶段的耗时一般在3小时左右。注意这时候的第一要事是读懂题目并分类，找到题目描述的矛盾点，假设等。&lt;/p&gt;
&lt;h3&gt;阶段二：逐个击破&lt;/h3&gt;
&lt;h4&gt;初始模型设计&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;让AI建立模型描述和数学逻辑&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;针对每个子问题（或数据预处理），让AI给出具体的模型建立计划，记录为&lt;code&gt;text/raw/问题一的建模与求解.md&lt;/code&gt;（或&lt;code&gt;数据预处理.md&lt;/code&gt;，类似的文件）。不需要论文格式，只管把数学逻辑、计算步骤讲清楚。&lt;/p&gt;
&lt;p&gt;:::tip
如果你是模型高手，希望奖项拿高一点，你可以人工审视并注入“创新点”，或者&lt;strong&gt;干脆甩给他一篇非常新的优化方法、评价方法的论文&lt;/strong&gt;。AI提出的模型往往中规中矩，日后的AI建模大赛，差异几乎都来自你的灵机一动。
:::&lt;/p&gt;
&lt;p&gt;这个步骤的结果最好人工审视一遍，因为它可能会在模型中使用一些&lt;strong&gt;拍脑袋参数或者子虚乌有的数据&lt;/strong&gt;，然后你要让它改。改成超参数优化（某种参数搜索）或者查能引用的论文说明，抑或是直接就问它这是什么。&lt;strong&gt;但要注意，有些东西确实需要在跑出来之后才能继续改进。&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;探索性代码实现&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;让AI根据计划生成初步代码，&lt;strong&gt;画出图&lt;/strong&gt;，解释模型输出。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这个阶段，AI可以生成&lt;strong&gt;读取、数据处理、求解计算画图&lt;/strong&gt;一体的、混乱不堪的代码，为的就是生成几张效果图给你看。你来评估这个模型得到的结果怎么样，然后挥鞭子让AI重做或者接受结果。&lt;/p&gt;
&lt;p&gt;实际上这个阶段依旧可以修改模型，不如说有时候只有跑出结果、看到大体数据分布之后才能知道调整方向。&lt;/p&gt;
&lt;p&gt;代码统一放在&lt;code&gt;code/raw/q*_xxx.py&lt;/code&gt;，随时覆盖、随时重试。同时更新&lt;code&gt;text/raw/*.md&lt;/code&gt;，记录所有模型、求解方法的结果，把所有关键数据、图表解释一并写入，形成一份“带数据的草稿”。&lt;/p&gt;
&lt;p&gt;这个阶段的代码是混沌的，允许冗余、调试痕迹，目的只为快速试错。&lt;/p&gt;
&lt;p&gt;:::tip
在去年(2025)，国内AI也不可能一次一个错不出地将代码全部写完，而今年上半年金模型频出，几乎可以完整排除不会代码的问题了。&lt;/p&gt;
&lt;p&gt;&lt;s&gt;（Python白学了.jpg）&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;Deepseek V4 Pro的代码能力足够强，以至于它可以自己完整地完成代码——模型的无缝互转工作，甚至和用户直接在模型层面上交流。&lt;/p&gt;
&lt;p&gt;当然前提是你知道它要做的是什么模型。一定要问清楚，还要自己搞清楚。除非你能读懂代码，代码永远是最清楚的。
:::&lt;/p&gt;
&lt;p&gt;&amp;lt;details&amp;gt;
&amp;lt;summary&amp;gt;对话例&amp;lt;/summary&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;[AI]&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;……&lt;/p&gt;
&lt;p&gt;最重要结论（对 Q3 的指向）&lt;/p&gt;
&lt;p&gt;四类的&lt;strong&gt;因子作用模式完全不同&lt;/strong&gt;——验证了我们不该用同一个模型拟合全中国：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;主流组&lt;/strong&gt;：GDP 和老龄化是正负两极，标准经济-人口模型&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;京沪组&lt;/strong&gt;：生育端彻底熄火，全靠迁移，且出现天花板效应——Q3 需要饱和机制&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;广东组&lt;/strong&gt;：青年移民持续稀释老龄化，大专+比的负增量说明产业工人为主——Q3 需要强化迁移项&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;西藏组&lt;/strong&gt;：高自然增长率主导，老龄化压力最小——Q3 需保留高基出生率&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;图已保存到 &lt;code&gt;img/&lt;/code&gt; 下，你看看有没有需要调整的。要不要接着看 Q3？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;[用户]&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;出生效应和迁移效应是算出来的？是否需要添加真实数据&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;[AI]&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;问得好。坦白说—— 目前的出生效应是估算的，不是真实数据 。&lt;/p&gt;
&lt;p&gt;让我看看原始附件里有没有出生/死亡数据可以用。&lt;/p&gt;
&lt;p&gt;……&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;（后面我手动去整理了数据。）
&amp;lt;/details&amp;gt;&lt;/p&gt;
&lt;h4&gt;结果结晶&lt;/h4&gt;
&lt;p&gt;当某个问题的结果令人满意，便进入沉淀环节。接下来由AI自行完成一个比较长的工作流。不出所料的话，对于每个小问做完这个你就该换对话清空上下文了。&lt;/p&gt;
&lt;p&gt;AI会根据之前积累出来的模型记录、真实模型代码、画图代码、结论和数据结果，整理成三种文件：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;提取模型本身的代码（&lt;strong&gt;模型代码&lt;/strong&gt;）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在&lt;code&gt;code/&lt;/code&gt;中创建&lt;code&gt;q1/&lt;/code&gt;目录，创建洗净的模型代码&lt;code&gt;code/q*/q*_model_*.py&lt;/code&gt;。这些代码不含弯路和不必要的注释，可执行最小化，将所有要为图服务的数据单独导出为&lt;code&gt;.csv&lt;/code&gt;、&lt;code&gt;.npy&lt;/code&gt;等文件。这些代码执行纯粹计算。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;提取模型本身的画图代码（&lt;strong&gt;画图代码&lt;/strong&gt;）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在&lt;code&gt;code/q1&lt;/code&gt;中创建洗净的图代码&lt;code&gt;code/q*/q*_img_*.py&lt;/code&gt;。这些代码只使用&lt;strong&gt;模型代码&lt;/strong&gt;所创建的。这些图的代码占比过于大且并不核心，不会被放入论文，但是&lt;strong&gt;会用于生成最终稿的图片&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;创建小问小结文件&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;根据最终真实的模型和图配置、呈现(图里显示了什么有时可能需要你来描述)，修正&lt;code&gt;text/raw/*.md&lt;/code&gt;中的模型表述，并附上对结果的详尽解释。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;这份文件将成为它后续撰写完整论文的第一手成果总结，因此需要绝对完整，不仅要有模型的数学推导，还包括比如本次小问解决的所有产出文件、图列表解释等。这个小问至此就算解决了。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;阶段三：完成论文&lt;/h3&gt;
&lt;p&gt;这是最能体现AI工作流魔力的阶段。我们调用预先写好的skill，让AI按固定流程执行：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;根据已有成果设计论文的章节分段预设。如&lt;code&gt;问题重述&lt;/code&gt;+&lt;code&gt;问题分析&lt;/code&gt;+&lt;code&gt;模型假设&lt;/code&gt;+&lt;code&gt;符号说明&lt;/code&gt;+&lt;code&gt;问题一模型的建立与求解&lt;/code&gt;+&lt;code&gt;问题二模型的建立与求解&lt;/code&gt;+&lt;code&gt;问题三模型的建立与求解&lt;/code&gt;+&lt;code&gt;问题四模型的建立与求解&lt;/code&gt;+&lt;code&gt;问题五模型的建立与求解&lt;/code&gt;+&lt;code&gt;模型优缺点&lt;/code&gt;+&lt;code&gt;参考文献&lt;/code&gt;。这就是一个很标准的章节分布。我放弃了将所有问题放入同一个大章节(5.1问题一, 5.2问题二这样)，因为分成多个大章节比较方便工作流。&lt;/li&gt;
&lt;li&gt;整理所有引用到的文献，为这些文献预先编号，便于后续在各个内容小块中用数字进行引用。&lt;/li&gt;
&lt;li&gt;按章节分段预设在&lt;code&gt;text/paper/&lt;/code&gt;下生成各章节的&lt;code&gt;.md&lt;/code&gt;文件，文件名带有数字前缀，如&lt;code&gt;1_问题重述.md&lt;/code&gt;、&lt;code&gt;2_模型假设.md&lt;/code&gt;、&lt;code&gt;3_问题一求解.md&lt;/code&gt;等。这一步由AI自行调度Trae的taskboard完成。每个小节的文件隔离是避免AI在长单次输出(如整篇论文)时主动缩减内容，不仅看起来单薄而且&lt;strong&gt;真的可能忽略重要的东西&lt;/strong&gt;。ps:这个环节其实还可以优化成并行的。&lt;/li&gt;
&lt;li&gt;运行第一次构建脚本。附录独立成一个&lt;code&gt;.md&lt;/code&gt;文件，和最大标题同级，避免Typora后续输出引用时把参考文献排到附录底部。这个过程完全由脚本完成。它机械地查找所有模型代码文件，读取。它还会添加&lt;code&gt;text/appendix/&lt;/code&gt;下的每个文件(依旧但是是可选地使用&lt;code&gt;/\d+_/&lt;/code&gt;开头命名，以保证顺序)作为额外附录（如大、长表）。自动编号后输出为&lt;code&gt;text/frozen/Appendix.md&lt;/code&gt;。脚本还会将各章节的&lt;code&gt;.md&lt;/code&gt;文件继续合并为&lt;code&gt;text/frozen/Main.md&lt;/code&gt;。这就是两个你需要完整过目的文件了。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;经过AI约一小时的苦战，现在你打开&lt;code&gt;text/frozen/&lt;/code&gt;，看到两个完整整理好的论文。图片是经过路径修正的，一定是能引用到的。你需要另开一个文件，从头到尾检查整篇文章不合适的地方，然后进行记录。&lt;/p&gt;
&lt;p&gt;:::note
一个经验之谈是在最终检查时，不要找一个错就改一个错，而是从头到尾把问题全部记下来之后再一一修改，避免solo时注意力和流程分崩离析的问题。
:::&lt;/p&gt;
&lt;p&gt;:::warning
修改时需要找到&lt;code&gt;text/paper/&lt;/code&gt;下对应章节的原文进行修改，修改后需要重跑上述&lt;code&gt;4.&lt;/code&gt;的脚本。&lt;strong&gt;切勿直接修改&lt;code&gt;text/frozen/Main.md&lt;/code&gt;。&lt;/strong&gt;
:::&lt;/p&gt;
&lt;p&gt;一般来说，你会遇到三类问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;表述问题&lt;/strong&gt;，如大量使用破折号&lt;code&gt;——&lt;/code&gt;、使用&lt;code&gt;vs&lt;/code&gt;甚至&lt;code&gt;「」&lt;/code&gt;导致的AI味。自己修改即可，无需浪费token&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;图片问题&lt;/strong&gt;，如文本遮挡、配色难以阅读、重复标题等。需要让AI修改源码中跑图的代码，重新生成图。一般最多就是改几行画图参数，也有大改的。如果能看懂代码，自己改也不是不行。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;论文问题&lt;/strong&gt;，如某章节中某个关键论述、关键结果、图表未能呈现？Solo工作流下手写论文实在有点费时费力，更何况原文还不是自己写的，此时就只能让AI返稿；能通读并识别出论文严重结构性问题的人只能有你，所以你才需要把上面每个小问的解决步骤、原理理清。这是证明论文原创的根本。:spoiler[你也不想上台答辩就介绍我最好的朋友大D老师吧]&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::note
终端是所有操作系统执行程序的主要入口。在Trae中，打开方式如图所示&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;p5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;终端可以理解为，敲一行命令，回车执行，的地方。理论上，终端可以执行除了打瓦以外所有你在电脑上通过鼠标执行的操作（&lt;/p&gt;
&lt;p&gt;在终端执行&lt;code&gt;python utils/build.py&lt;/code&gt;以手动运行第一阶段构建。AI到时候也会这么做。当然前提是你已经安装了python。
:::&lt;/p&gt;
&lt;h3&gt;阶段四：最终输出&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;前提：论文已没有任何问题。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;你用手打开Typora，选择预设的主题文件将&lt;code&gt;Main.md&lt;/code&gt;和&lt;code&gt;Appendix.md&lt;/code&gt;分别导出为&lt;code&gt;Main.pdf&lt;/code&gt;和&lt;code&gt;Appendix.pdf&lt;/code&gt;。原目录原样导出即可。&lt;/li&gt;
&lt;li&gt;运行第二次构建脚本。脚本会将两个pdf合并。如果你的学校要求在电子版前面再添加页面，还可以添加额外的第三个&lt;code&gt;Prefix.pdf&lt;/code&gt;，脚本会自动识别。脚本还会自动添加连续页码，最终输出到&lt;code&gt;frozen/[time]/我的论文.pdf&lt;/code&gt;。脚本还会将所有代码文件、原始数据集、引用论文等所有可能要塞进参考资料的文件打包放进&lt;code&gt;我的参考资料.zip&lt;/code&gt;里。最后还会自动计算两个文件的md5，国赛会需要。当然不使用这个md5而是直接把文件拖进官方提交程序也是可以的。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;frozen/
└─20260510_1345/
  ├─ 我的论文.pdf
  ├─ 我的参考资料.zip
  └─ md5.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::warning
第二次构建脚本导出的结果是最终品论文。如果你再发现论文原文问题，你需要：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;再修改论文的片段&lt;/li&gt;
&lt;li&gt;运行第一次构建流程&lt;/li&gt;
&lt;li&gt;使用Typora手动构建拼接版论文，可能还要构建附录&lt;/li&gt;
&lt;li&gt;运行第二次构建流程
非常麻烦。所以尽可能在最后进行论文的构建。
:::&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;flowchart TD
    subgraph 阶段一
        CIT[cit/&amp;lt;br&amp;gt;引用的原始论文&amp;lt;br&amp;gt;数据/参考文献]
        FIRST_ANALYSIS[第一阶段&amp;lt;br&amp;gt;初始分析]
        QUES[ques/&amp;lt;br&amp;gt;题目原文.md&amp;lt;br&amp;gt;原始附件]
    end

    QUES &amp;amp; CIT --&amp;gt; FIRST_ANALYSIS
    QUES --&amp;gt;|提取题目原文| TEXT_RAW
    QUES &amp;amp; FIRST_ANALYSIS &amp;amp; CIT --&amp;gt; CODE_RAW

    subgraph 阶段二
        CODE_RAW[混沌代码&amp;lt;br&amp;gt;快速试错]
        TEXT_RAW[草稿笔记&amp;lt;br&amp;gt;建模记录/数据解释]
        IMG[初步生成的结果图]
    end

    CODE_RAW ==&amp;gt;|生成图表| IMG
    IMG ==&amp;gt;|评估效果| TEXT_RAW
    TEXT_RAW ==&amp;gt;|反馈指导| CODE_RAW

    subgraph 阶段三
        CODE_QX_MODEL[最小可执行模型代码&amp;lt;br&amp;gt;及其结果数据]
        CODE_QX_IMG[最小画图代码]
        TEXT_PAPER[1.问题重述.md&amp;lt;br&amp;gt;2.问题分析.md&amp;lt;br&amp;gt;..]
        TEXT_APPENDIX[附加附录&amp;lt;br&amp;gt;大数据表等]
    end

    TEXT_RAW --&amp;gt;|优化图选型| CODE_QX_IMG
    CODE_QX_MODEL --&amp;gt;|模型代码| TEXT_APPENDIX
    CODE_RAW --&amp;gt;|确定方案后提取洗净代码| CODE_QX_MODEL
    CODE_RAW --&amp;gt;|提取纯净画图代码| CODE_QX_IMG
    TEXT_RAW --&amp;gt;|笔记完全提炼| TEXT_PAPER
    CODE_QX_IMG --&amp;gt;|最终使用图片| TEXT_PAPER
    CODE_QX_MODEL --&amp;gt;|实际代码模型和数据| TEXT_PAPER

    subgraph 冻结输出
        MAIN_MD[Main.md&amp;lt;br&amp;gt;正文&amp;lt;br&amp;gt;人工最终审查]
        APPENDIX_MD[Appendix.md&amp;lt;br&amp;gt;附录]
        FINAL_PDF[最终论文.pdf&amp;lt;br&amp;gt;我的参考资料.zip]
    end

    TEXT_PAPER --&amp;gt;|第一次构建| MAIN_MD
    TEXT_APPENDIX --&amp;gt;|第一次构建| APPENDIX_MD
    CODE_QX_MODEL --&amp;gt;|第一次构建| APPENDIX_MD

    MAIN_MD --&amp;gt;|优化表述| TEXT_PAPER

    MAIN_MD &amp;amp; APPENDIX_MD --&amp;gt;|Typora导出+第二次构建| FINAL_PDF
    CIT --&amp;gt;|第二次构建| FINAL_PDF

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;琐事&lt;/h2&gt;
&lt;h3&gt;虚拟环境&lt;/h3&gt;
&lt;p&gt;本文没提到Python虚拟环境，是为新手运行简单考虑。实际上我本人也不怎么用虚拟环境。只有真的用torch这种库，有必要的时候才会用uv去创建。&lt;/p&gt;
&lt;p&gt;另外本工作流提供了基于uv的基础环境搭建。让ai初始化的话则会立即创建。&lt;/p&gt;
&lt;h3&gt;关于Deepseek V4和论文&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;文首提到的30R是基于优惠价格和个人使用经验确定的。(2026-05-22)Deepseek平台官方已经声明：此次2.5折优惠后将永久下调至原价1/4（也就是保持此优惠价作为原价）。故价格已无需担心。&lt;/li&gt;
&lt;li&gt;测试发现Deepseek V4有很强的自己解决问题的趋向，这直接导致它很难在该问问题的时候问出问题来，所以必须让它该停停，不然很容易糊弄了事。比如 ↓&lt;/li&gt;
&lt;li&gt;我测试过让它直接跑完全程，这十分不现实，跑出来的论文虽然看起来像那么回事但一共就12页……十二页……:spoiler[我要是这么糊弄一般会被认为是找老师茬]&lt;/li&gt;
&lt;li&gt;针对认证杯公开论文及其分数的数模元分析发现，正文页数和论文分数成正比。所以一定要给它增加工作量，增加&lt;strong&gt;看起来有效&lt;/strong&gt;的工作量，当然实际上有没有效，无人在意。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;项目展望&lt;/h3&gt;
&lt;p&gt;本工作流完全基于我所熟悉的Python，日后若有matlab大佬相助，可能有支持的打算，但也还是会优先考虑AI集成。&lt;/p&gt;
&lt;p&gt;欢迎issue~ 本仓库不同于严肃的开源社区，对非程序员有一定接纳度，想提问题可以随意提哦~(PS: issue相当于github的工单系统，不过是完全公开的，所有人都能自由讨论的)&lt;/p&gt;
</content:encoded></item><item><title>如何将微分方程写成python看得懂的函数？开始学习计算机求解微分方程的暴力美学 (初识数值实验·上)</title><link>https://blog.emumu.xyz/posts/2026-04-24-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-04-24-00/</guid><description>如何把数学方程翻译成Python函数、RK4的原理实现、以cupy为例如何使用显卡进行计算</description><pubDate>Fri, 24 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;本教程以 &lt;code&gt;scipy.integrate&lt;/code&gt; 和 &lt;code&gt;cupy&lt;/code&gt; 为例。以你会基本的 Python 编程和常微分方程基础为前提，以求解常微分方程（ODE）的初值问题为线索。我们将从科学计算的标准接口 &lt;code&gt;solve_ivp&lt;/code&gt; 入手，教你如何把数学方程翻译成计算机看得懂的函数；然后亲手拆解黑盒，用 NumPy 实现经典的四阶龙格‑库塔法（RK4）；最后以双摆系统的大规模模拟为例，用 CuPy 把计算搬上显卡，体验数值求解的暴力美学。学完本文，你将彻底掌握从单条轨迹求解理论到上万组轨迹并行加速的全过程。&lt;/p&gt;
&lt;p&gt;ps: 本人并非相关专业，仅面向代码和交叉学科基础，如有不严谨还请见谅。&lt;/p&gt;
&lt;p&gt;本期的源代码在以下仓库：&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;emumus/solve_ivp&quot;}&lt;/p&gt;
&lt;h2&gt;solve_ivp 标准的格式&lt;/h2&gt;
&lt;p&gt;本节的目标：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;学会 &lt;code&gt;solve_ivp&lt;/code&gt; 函数的用法。&lt;/li&gt;
&lt;li&gt;学会把数学微分方程改写成它的形式。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在深入研究如何用 GPU 加速或手动实现高级算法之前，我们必须先理解 Python 科学计算社区定义的第一协议: &lt;code&gt;scipy.integrate.solve_ivp&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;solve_ivp&lt;/code&gt; 的接口定义是所有微分方程数值解的通用语言，也是描述一个微分方程最通用的标准格式。对大多数混作业的大学生来说，学到这里其实就够了。&lt;/p&gt;
&lt;p&gt;在SciPy中，你只需要调用：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from scipy.integrate import solve_ivp
sol = solve_ivp(derivative_func, [t_start, t_end], y0, args=(alpha,))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;就能在 &lt;code&gt;sol.y[0]&lt;/code&gt; 中获得从 &lt;code&gt;t_start&lt;/code&gt; 到 &lt;code&gt;t_end&lt;/code&gt; 期间，以$f(t_{start})=y_0$的共几个点处的&lt;strong&gt;数值解&lt;/strong&gt;。当然了，计算机不会像人一样生龙活虎地解微分方程，人家硬算的。&lt;/p&gt;
&lt;h3&gt;把数学微分方程转为python函数&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;计算机不认识微分，只认识当点的变化率。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在数学纸面上，我们习惯写 $\frac{d\mathbf{y}}{dt} = f(\mathbf{y}, t)$。但在编程中，求解器本质上只会机械地（黑盒地）调用你写的函数。它只向你要一件东西：&lt;strong&gt;给定当前的时间 $t$ 和当前的&amp;lt;u&amp;gt;状态&amp;lt;/u&amp;gt; $\mathbf{y}$，请告诉我此刻的斜率（导数）是多少？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这个返回&lt;strong&gt;斜率&lt;/strong&gt;的函数，就是我们需要编写的pyhton函数。你的函数必须遵循以下结构：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def derivative_func(
    t, # 时间，更熟悉的说法是y=f(x)的x，自变量，求解范围指的就是这个数的范围。
    state, # 状态，更熟悉的说法是y=f(x)的y，因变量。注意这里可以且必须是一个向量。
    *args # 方程的其他外部参数会被这样传进来
):
    # 1. 解构状态变量
    y1, y2 = state # 如两个
    # 2. 根据数学公式计算变化率
    dy1_dt = ... # 可以自行用dy和t来计算
    dy2_dt = ...
    # 3. 返回变化率列表或数组
    return [dy1_dt, dy2_dt, ...]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们来看具体的例子:&lt;/p&gt;
&lt;h3&gt;示例 ：单变量情况&lt;/h3&gt;
&lt;p&gt;给定&lt;strong&gt;衰减系统微分方程&lt;/strong&gt;：
$$
\frac{dy}{dt} = -\alpha y
$$
其中 $\alpha$ 是衰减系数。&lt;/p&gt;
&lt;p&gt;左侧的 $\frac{dy}{dt}$ 正是我们需要返回的&lt;strong&gt;变化率&lt;/strong&gt;。&lt;strong&gt;变化率&lt;/strong&gt;的定义就是-的因变量状态 $\times$ 系数 $\alpha$ 。同时注意因变量状态的参数 &lt;code&gt;y&lt;/code&gt; 总是一个列表。故要写 &lt;code&gt;y[0]&lt;/code&gt; 。返回的也必须是一个变化率列表 &lt;code&gt;[dydt]&lt;/code&gt; 。&lt;/p&gt;
&lt;p&gt;那么就可以写：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def decay_system(t, state, alpha):
    dydt = -alpha * state[0] # 解包免了，我们就直接用state[0]
    return [dydt]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意: &lt;code&gt;t&lt;/code&gt; 和 &lt;code&gt;y&lt;/code&gt; 的位置是确定的，&lt;code&gt;alpha&lt;/code&gt; 以及后续可能出现的其他外部变量可以直接排列到函数参数中，不久之后通过 &lt;code&gt;solve_ivp&lt;/code&gt; 传入，&lt;code&gt;solve_ivp&lt;/code&gt; 调用你的函数的时候会自动把参数填进去的。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;solve_ivp(decay_system, [0, 10], 100, args=(0.5,))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::tip&lt;/p&gt;
&lt;p&gt;出于业界习惯标准，我们现在应该开始接受将自变量 $x$ 称为时间维度 $t$，因变量 $y$ 称为状态变量。后续将涉及多个状态之间相互影响和高阶互相影响的情况，这套称呼的优点将逐渐显现。&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;h3&gt;示例 ：多变量耦合&lt;/h3&gt;
&lt;p&gt;当系统有多个变量时，$y$ 就变成了一个&lt;strong&gt;状态向量&lt;/strong&gt;。（骗你的只有一个你也得写成数组）&lt;/p&gt;
&lt;p&gt;举例来说，&lt;strong&gt;洛伦兹方程的数学表达：&lt;/strong&gt;
$$
\begin{cases}
\dfrac{dx}{dt} = \sigma,(y - x)\[4pt]
\dfrac{dy}{dt} = x,(\rho - z) - y\[4pt]
\dfrac{dz}{dt} = xy - \beta,z
\end{cases}
$$
不同的状态之间互相影响在混在一起的向量状态在这种格式中是很方便随意互相取用的。同时又因为python里有很方便的解包语法。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def lorenz_partial(t, state, sigma, rho, beta):
    x, y, z = state 
    
    dxdt = sigma * (y - x)
    dydt = x * (rho - z) - y
    dzdt = x * y - beta * z
    
    return [dxdt, dydt, dzdt]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note&lt;/p&gt;
&lt;p&gt;为什么 &lt;code&gt;solve_ivp&lt;/code&gt; 就知道 &lt;code&gt;state&lt;/code&gt; 是三元组呢？其实 &lt;code&gt;solve_ivp&lt;/code&gt; 会先根据你传入的初值数组长度确定状态个数，之后直接把初值作为&lt;code&gt;state&lt;/code&gt;塞进你的函数，不管你的函数实际上解包多少参数。哈基py感觉不对会自己报错的（&lt;code&gt;not enough values to unpack (expected m, got n)&lt;/code&gt;）。所以一定要自己保证初值数组匹配函数的状态数量哦。&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;h3&gt;示例 ：高阶常微分方程&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;solve_ivp&lt;/code&gt; 只能求解&lt;strong&gt;一阶&lt;/strong&gt;常微分方程组。如果你遇到的是高阶方程（比如二阶、三阶），必须先把它拆解成一阶方程组。这个过程十分简单粗暴：
$$
\frac{d^2 y}{dt^2} = f(t, y, \frac{dy}{dt}) \&lt;/p&gt;
&lt;p&gt;\text{设},v = \frac{dy}{dt} ,\quad&lt;/p&gt;
&lt;p&gt;\begin{cases}
\frac{dy}{dt} = v \[4pt]
\frac{dv}{dt} = f(t, y, v)
\end{cases}
$$
举例来说，&lt;strong&gt;简谐振荡器的数学表达&lt;/strong&gt;：
$$
\frac{d^2 x}{dt^2} = -\frac{k}{m} x \&lt;/p&gt;
&lt;p&gt;\text{设},v = \frac{dx}{dt},\quad&lt;/p&gt;
&lt;p&gt;\begin{cases}
\frac{dx}{dt} = v \[4pt]
\frac{dv}{dt} = -\frac{k}{m} x
\end{cases}
$$
这实际上就是两个互相干扰的一阶微分方程。$x$ 的变化率由 $v$ 决定，$v$ 的变化率由 $x$ 决定，何尝又不是一对苦命鸳鸯。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def harmonic_oscillator(t, state, k, m):
    x, v = state
    dxdt = v
    dvdt = -(k / m) * x
    return [dxdt, dvdt]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::tip&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;即使你的方程中没有显式出现时间（自变量） $t$（即自治系统），在定义函数时也必须保留 &lt;code&gt;t&lt;/code&gt; 作为第一个参数，这是为了兼容那些随时间变化的非自治系统。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;solve_ivp&lt;/code&gt; 是为通用&lt;strong&gt;CPU计算&lt;/strong&gt;设计的。当你需要同时模拟&lt;strong&gt;一百万组不同的轨迹&lt;/strong&gt;（比如蒙特卡洛模拟或大规模粒子系统）时，&lt;code&gt;solve_ivp&lt;/code&gt; 会慢得绝望。但只要你有一张普通的消费级显卡，再结合后续章节的一些知识，某些任务上&lt;strong&gt;加速百倍起步完全不是问题&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;h3&gt;求解器 &lt;code&gt;solve_ivp&lt;/code&gt; 的完全版用法&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;solve_ivp&lt;/code&gt; 的完整签名如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;solve_ivp(
    fun, # 上面所说格式的函数
    t_span, # t的左右界，如[0, 100]
    y0, # 左界初值 *向量*
    method=&apos;RK45&apos;, # 更多优化器待你解锁……不清楚的话就先用RK45吧！
    t_eval=None, 
    dense_output=False,
    events=None, 
    vectorized=False, 
    args=None, 
    **options
)
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;fun&lt;/strong&gt;: 如上定义的函数。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;t_span&lt;/strong&gt;: 二元组 &lt;code&gt;(t0, tf)&lt;/code&gt;。允许 &lt;code&gt;tf &amp;lt; t0&lt;/code&gt; 反向积分。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;y0&lt;/strong&gt;: 初始条件。形状为 &lt;code&gt;(n,)&lt;/code&gt; 的一维数组。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;method&lt;/strong&gt;: 选择求解器。刚性问题建议使用 &lt;code&gt;&apos;Radau&apos;&lt;/code&gt; 或 &lt;code&gt;&apos;BDF&apos;&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;t_eval&lt;/strong&gt;: 指定需要输出结果的时间点。
&lt;ul&gt;
&lt;li&gt;这与 &lt;code&gt;t_span&lt;/code&gt; 并不冲突，&lt;code&gt;t_span&lt;/code&gt; 确定它实际求解计算的范围，&lt;code&gt;t_eval&lt;/code&gt; 指定我所需要的那些值。&lt;/li&gt;
&lt;li&gt;举例来说，我需要$[1,2]$的步长 &lt;code&gt;0.1&lt;/code&gt; 的值，但我只有在0处的初值，则我会传入求解的范围 &lt;code&gt;t_span=[0,2]&lt;/code&gt; 而所需的值 &lt;code&gt;t_eval=np.arange(1, 2, 0.1)&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;求解器仍会从0正常地算到2，只是最后只返回1到2之间的点。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dense_output&lt;/strong&gt;: 启用后会在内存里保存一些求解信息，允许随时通过 &lt;code&gt;sol.sol(t)&lt;/code&gt; 获取任意 $t\in t_{\mathrm{span}}$ 的解。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;events&lt;/strong&gt;: 检测事件函数 &lt;code&gt;event(t, y, *args)&lt;/code&gt; 的零点。可设置 &lt;code&gt;terminal=True&lt;/code&gt; 停止积分。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;vectorized&lt;/strong&gt;: 若 &lt;code&gt;fun&lt;/code&gt; 能同时接受多个 &lt;code&gt;y&lt;/code&gt; 列（形状 &lt;code&gt;(n, k)&lt;/code&gt; ），设为 &lt;code&gt;True&lt;/code&gt; 可加速（仅限部分方法）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;args&lt;/strong&gt;: 额外参数的元组，按顺序传递给 &lt;code&gt;fun&lt;/code&gt; 和 &lt;code&gt;events&lt;/code&gt;。即微分方程函数中 &lt;code&gt;t&lt;/code&gt;、&lt;code&gt;state&lt;/code&gt; 之后的参数。&lt;/li&gt;
&lt;li&gt;部分方法有自己独特的额外options，如 &lt;code&gt;atol&lt;/code&gt;、&lt;code&gt;rtol&lt;/code&gt; 等等。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;求解器 &lt;code&gt;solve_ivp&lt;/code&gt; 返回的的对象&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;solve_ivp&lt;/code&gt; 返回 &lt;code&gt;Bunch&lt;/code&gt; 对象，以下字段较为常用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;t: ndarray&lt;/code&gt;: 返回各个求得值的时间点，形状 &lt;code&gt;(n_points,)&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;y: ndarray&lt;/code&gt;: 在各个&lt;code&gt;t&lt;/code&gt;处的解的值。形状 &lt;code&gt;(n, n_points)&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sol: OdeSolution|None&lt;/code&gt;: 找到的解作为 &lt;code&gt;OdeSolution&lt;/code&gt; 实例。如果 &lt;code&gt;dense_output&lt;/code&gt; 设置为 False，则为 None。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;status&lt;/code&gt;: 算法终止的原因：
&lt;ul&gt;
&lt;li&gt;-1：积分步长失败。&lt;/li&gt;
&lt;li&gt;0：求解器成功到达 &lt;code&gt;tspan&lt;/code&gt; 的终点。&lt;/li&gt;
&lt;li&gt;1：发生了终止事件。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;message: str&lt;/code&gt;: 可读的终止原因描述。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;success: bool&lt;/code&gt;: 如果求解器达到区间终点或发生终止事件（&lt;code&gt;status &amp;gt;= 0&lt;/code&gt;），则为 True。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;复习微分方程以及RK4原理&lt;/h2&gt;
&lt;p&gt;现在，我们将打破黑盒，用 NumPy 手动实现 RK4 算法，手动复现一个青春版 &lt;code&gt;solve_ivp&lt;/code&gt;。&lt;/p&gt;
&lt;h3&gt;计算机是如何解微分方程的？&lt;/h3&gt;
&lt;p&gt;在高数课上，我们解微分方程是靠各种模式背方法找原函数模式。但计算机可没那么聪明（至少在数值计算领域不是）。数值求解的核心思想极其简单粗暴：&lt;strong&gt;切线迭代（或者叫步进）&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;想象一下，你站在一张空白的画布上。你想画出这个 $y(t)$。你知道这个函数过初值点$(0, 0)$。&lt;/p&gt;
&lt;p&gt;你手里有一个魔法罗盘（也就是那个返回导数的 Python 函数）。只要你告诉罗盘你当前的时间 $t$ 和位置 $y$，罗盘就会立刻告诉你这一个距离下的斜率 $\frac{dy}{dt}$。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;pic1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;欧拉法（Euler Method）：最天真的走法&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;你问一次罗盘，得到方向，然后沿着这个方向直勾勾地往前跨一大步($h$)。
$$
y_{n+1} = y_n + h \cdot f(t_n, y_n)
$$
这就是最基础的欧拉法。但问题很明显：真实的曲线大概率是二阶可导的，你沿着切线直走，只要步子迈得稍微大一点，下一步落地时你就会偏离真实的曲线。随着时间推移，误差会疯狂累积，直到你的结果离题万里。&lt;/p&gt;
&lt;h3&gt;龙格-库塔法（RK4）：货比四家&lt;/h3&gt;
&lt;p&gt;为了解决直走偏航的问题，数学家们发明了经典的四阶龙格-库塔法（Runge-Kutta 4th Order Method，简称 RK4）。&lt;/p&gt;
&lt;p&gt;RK4 的核心哲学是：&lt;strong&gt;不要急着迈步，先在这个步长 $h$ 范围内多探几个点的斜率，综合起来再走。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;具体来说，它会在每一次跨步前，试探性地计算 4 个斜率（通常记为 $k$）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;$k_1$（起点斜率）：&lt;/strong&gt; 在当前位置问罗盘得到的真实斜率。&lt;/p&gt;
&lt;p&gt;$$k_1 = f(t_n, y_n)$$&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;$k_2$（中点试探斜率1）：&lt;/strong&gt; 假装用 $k_1$ 往前走半步，到达中点，问罗盘这个中点的斜率。&lt;/p&gt;
&lt;p&gt;$$k_2 = f(t_n + \frac{h}{2}, y_n + h\frac{k_1}{2})$$&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;$k_3$（中点试探斜率2）：&lt;/strong&gt; 刚才用 $k_1$ 走半步可能不太准，这次我们用刚求出的 $k_2$ 重新走到半步的位置，再问罗盘获取斜率。&lt;/p&gt;
&lt;p&gt;$$k_3 = f(t_n + \frac{h}{2}, y_n + h\frac{k_2}{2})$$&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;$k_4$（终点试探斜率）：&lt;/strong&gt; 最后，用 $k_3$ 往前走完整整一步到达终点，在这个预测的终点处，再问最后一次罗盘。&lt;/p&gt;
&lt;p&gt;$$k_4 = f(t_n + h, y_n + h k_3)$$&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;最终合并：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;拿到这四个斜率后，RK4 给它们赋予不同的权重（中点的斜率最重要，权重是两头的两倍），求出一个平均斜率，然后用这个平均斜率迈出最终的一步：&lt;/p&gt;
&lt;p&gt;$$y_{n+1} = y_n + \frac{h}{6}(k_1 + 2k_2 + 2k_3 + k_4)$$&lt;/p&gt;
&lt;p&gt;就是这么简单。这四个斜率线性组合，巧妙地抵消了泰勒展开四阶的误差。&lt;/p&gt;
&lt;h3&gt;动手实现青春版RK4求解器&lt;/h3&gt;
&lt;p&gt;这里我们借助 NumPy 的向量化运算，让它可以同时处理上一节提到的多变量状态向量。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import numpy as np
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;适配 &lt;code&gt;solve_ivp&lt;/code&gt; 的解对象的格式。我们先只兼容直接取 &lt;code&gt;t&lt;/code&gt; 和 &lt;code&gt;y&lt;/code&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class OdeSolution:
    def __init__(self, t, y):
        self.t = t
        self.y = y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;先实现一个单步的函数，我们以此通过 $t$ 和 $\mathbf{y}(x_0)$ 计算 $\mathbf{y}(x_0+h)$。逻辑就是刚刚提到的斜率线性组合。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def rk4_step(fun, t, y, h, args):
    &quot;&quot;&quot;
    单步RK4
    :param fun: 你的微分方程函数，签名为 fun(t, y, *args)
    :param t: 当前时间
    :param y: 当前状态 (numpy数组)
    :param h: 步长
    &quot;&quot;&quot;
    k1 = np.array(fun(t, y, *args))
    k2 = np.array(fun(t + h / 2, y + h * k1 / 2, *args))
    k3 = np.array(fun(t + h / 2, y + h * k2 / 2, *args))
    k4 = np.array(fun(t + h, y + h * k3, *args))

    y_next = y + (h / 6.0) * (k1 + 2 * k2 + 2 * k3 + k4)
    return y_next
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后简单地从y0开始，以h为步长循环就可以了。唯一要说的是我们提前构建了一个二维数组(其实是np矩阵) &lt;code&gt;y_history&lt;/code&gt;，以列为单位，每次将上次用过的状态向量拿出来，算好后放到下一个列。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def my_solve_ivp(fun, t_span, y0, args, h=1e-3):
    &quot;&quot;&quot;
    青春版rk4求解器
    &quot;&quot;&quot;
    t_start, t_end = t_span

    # 计算需要的步数
    n_steps = int(np.ceil((t_end - t_start) / h))
    # 生成要计算的所有时间点
    t_eval = np.linspace(t_start, t_end, n_steps + 1)

    # y_history 形状为 (状态数, 时间点数)，与 scipy 标准保持一致
    y_history = np.zeros((len(y0), n_steps + 1))
    # 初值是这么用的
    y_history[:, 0] = y0

    current_y = np.array(y0)
    for i in range(n_steps):
        current_t = t_eval[i]  # 每次拿取下一个t值
        # 更新状态
        current_y = rk4_step(fun, current_t, current_y, h, args)
        y_history[:, i + 1] = current_y

    return OdeSolution(t_eval, y_history)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;有了这段代码，你就彻底摆脱了对 &lt;code&gt;scipy.integrate&lt;/code&gt; 的依赖。虽然它功能单一（只支持固定步长 $h$），但它的逻辑完全透明，并且是后续我们向 GPU 加速进军的基石。&lt;/p&gt;
&lt;p&gt;:::warning&lt;/p&gt;
&lt;p&gt;这个手搓的版本与 &lt;code&gt;solve_ivp&lt;/code&gt; 相比多一个重要的默认参数 &lt;code&gt;h=1e-3&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;步长 $h$ 需要你自己设定。$h$ 如果太大，误差就会爆炸；$h$ 如果太小（比如 $10^{-8}$），不仅计算极其缓慢，还会因为计算机浮点数精度限制产生严重的舍入误差。&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;pic2.png&quot; alt=&quot;各种方法步长在一个黑洞方程上的表现&quot; /&gt;&lt;/p&gt;
&lt;p&gt;:::tip&lt;/p&gt;
&lt;p&gt;此处用于测试的方程 $y&apos; = y - 2x/y$ 在初值 $y(0)=1$ 在数学上有一个看起来很完美的特解 $\sqrt{2x+1}$，但在计算机眼中，这个解就像是走钢丝。&lt;/p&gt;
&lt;p&gt;它的通解是 $y=\sqrt{1+2x+Ce^{2x}}$。但凡迭代过程稍微出现一点误差，指数就会爆出根号冲向天空。可以看到即使是 &lt;code&gt;scipy.integrate.solve_ivp&lt;/code&gt; 的RK45也倒在了 $x=3$ 左右。&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;h3&gt;简单扩展：有没有RKn？&lt;/h3&gt;
&lt;p&gt;有的有的。并且还有一个叫布彻尔表(Butcher Tableau)的东西，是数学家们总结出的一套系数，就是它指明了满足各阶精度的阶条件。这里不涉及太多数学概念。当然越高者系数计算量越大，并且一般方程不会有像 $y&apos; = y - 2x/y$ 这样的走钢丝函数一样的性质。所以工程权衡下就有了RK45这个优化方法。&lt;/p&gt;
&lt;p&gt;推荐拓展阅读：&lt;a href=&quot;https://zhuanlan.zhihu.com/p/408015963&quot;&gt;龙格库塔方法与它的布彻表.py - 知乎&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;简单扩展：RK45 又是什么？&lt;/h3&gt;
&lt;p&gt;在使用 &lt;code&gt;solve_ivp&lt;/code&gt; 时，默认的 &lt;code&gt;method=&apos;RK45&apos;&lt;/code&gt;（也被称为 Dormand-Prince 法）经常让人迷惑：它到底是 4 阶还是 5 阶？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;它同时是 4 阶和 5 阶。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在现实的物理模拟中，系统有时变化剧烈（比如弹簧突然崩开），有时又风平浪静。如果一直用固定的步长 $h$，在剧烈变化时误差极大，在平静时又浪费算力。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;自适应步长&lt;/strong&gt;是RK45的灵魂：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;它在每一步计算时，不仅算出一个 4 阶精度的预估值 $y_4$，还会额外算出一个 5 阶精度的预估值 $y_5$。&lt;/li&gt;
&lt;li&gt;计算机把这两个结果拿来相减，得到一个误差估计值 $error = |y_5 - y_4|$。&lt;/li&gt;
&lt;li&gt;如果 $error$ 超出了你容忍的阈值（比如上一节提到的 &lt;code&gt;rtol&lt;/code&gt; 和 &lt;code&gt;atol&lt;/code&gt;），说明当前步长太大，求解器会&lt;strong&gt;拒绝这一步&lt;/strong&gt;，把步长 $h$ 减小，重新算一次。&lt;/li&gt;
&lt;li&gt;如果 $error$ 极小，说明现在系统很平稳，求解器会&lt;strong&gt;偷偷把下一步的 $h$ 放大&lt;/strong&gt;，从而飞速跨过平稳区，为你节省大量时间。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这就是为什么 &lt;code&gt;solve_ivp&lt;/code&gt; 非常通用且鲁棒:spoiler[我喜欢鲁棒这个词，它抽象得令人记忆深刻]。但在我们需要极致并行性能时，带有 &lt;code&gt;if-else&lt;/code&gt; 判断的自适应步长算法在 GPU 上反而容易成为性能瓶颈，这也是我们为什么要在后续章节坚持回归纯粹固定步长 RK4 的原因。&lt;/p&gt;
&lt;h2&gt;显卡计算（听起来就专业）&lt;/h2&gt;
&lt;p&gt;在前一章中，我们已经拥有了一个逻辑透明的青春版 RK4 求解器。对于求解单一物体的运动轨迹，现代 CPU 的单核性能绰绰有余，跑完几万步迭代也就是眨眼间的功夫。&lt;/p&gt;
&lt;p&gt;但如果我们面对的是&lt;strong&gt;大规模的并行模拟&lt;/strong&gt;呢？&lt;/p&gt;
&lt;p&gt;:::warning&lt;/p&gt;
&lt;p&gt;本章主要内容是代码，说俗了就是教你调库，晕代码的同学可以跳，AI写的也不错。&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;h3&gt;复杂耦合方程的噩梦：双摆系统&lt;/h3&gt;
&lt;p&gt;为了直观地展示算力瓶颈，我们请出物理学界著名混沌系统&lt;strong&gt;双摆&lt;/strong&gt;。想必很多人已经见识到了最近一些科普视频展示的双摆美丽的动态相空间示意图。&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;//player.bilibili.com/player.html?bvid=BV1Z2MfzeEVL&amp;amp;p=1&amp;amp;autoplay=0&quot; scrolling=&quot;no&quot; border=&quot;0&quot; frameborder=&quot;no&quot; framespacing=&quot;0&quot; allowfullscreen=&quot;true&quot; &amp;amp;autoplay=0&amp;gt; &amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;p&gt;双摆系统由两个单摆首尾相连构成。尽管它的结构看似简单，但根据拉格朗日力学推导出的微分方程却极其复杂，且各状态变量（两个角度 $\theta_1, \theta_2$ 和两个角速度 $\omega_1, \omega_2$）之间深度耦合。稍微改变一点点初始角度，其后续的运动轨迹就会天差地别。
$$
\begin{cases}
\Delta &amp;amp;= \theta_1 - \theta_2 \
D &amp;amp;= 16 - 9\cos^2\Delta \
\dot{\theta}_1 &amp;amp;= \frac{6}{ml^2 D}\left(2p_1 - 3\cos\Delta , p_2\right) \
\dot{\theta}_2 &amp;amp;= \frac{6}{ml^2 D}\left(8p_2 - 3\cos\Delta , p_1\right) \
\dot{p}_1 &amp;amp;= -\frac{1}{2}ml\left(3g\sin\theta_1 + l\dot{\theta}_1\dot{\theta}_2\sin\Delta\right) \
\dot{p}_2 &amp;amp;= -\frac{1}{2}ml\left(g\sin\theta_2 - l\dot{\theta}_1\dot{\theta}_2\sin\Delta\right)
\end{cases}
$$
用 Python 将其微分方程写出来，大致是这样的：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def double_pendulum_cp(t, group_state, m, l, g):
    # 沿着列切片，拿到 N 个双摆的对应状态。截取出的变量形状皆为 (N,)
    theta1, theta2, p1, p2 = group_state

    # 重用量
    delta = theta1 - theta2
    cos_delta = np.cos(delta)
    c1 = l * theta1_dot * theta2_dot * np.sin(delta)
    c2 = 6.0 / (m * l * l) / (16.0 - 9.0 * cos_delta * cos_delta)
    c3 = -0.5 * m * l  # -1/2 m l

    # 角速度
    theta1_dot = c2 * (2.0 * p1 - 3.0 * cos_delta * p2)
    theta2_dot = c2 * (8.0 * p2 - 3.0 * cos_delta * p1)

    # 动量导数
    p1_dot = c3 * (3.0 * g * np.sin(theta1) + c1)
    p2_dot = c3 * (g * np.sin(theta2) - c1)

    # 构建为 (4, N)
    return np.array([theta1_dot, theta2_dot, p1_dot, p2_dot])
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;CPU 的叹息&lt;/h3&gt;
&lt;p&gt;如同视频里那样，假设我们想研究：&lt;strong&gt;在不同的初始角度 $(\theta_1, \theta_2)$ 下，双摆在 10 秒后会处于什么状态？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;为此，我们需要在 $[-\pi, \pi]$ 的范围内，均匀划分出一个 $n \times n$ 的网格。哪怕只有 $n=50$，这也意味着我们需要同时求解 &lt;strong&gt;2500 个独立但计算密集的微分方程&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;如果使用传统的 &lt;code&gt;for&lt;/code&gt; 循环：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;results = []
for th1 in np.linspace(-np.pi, np.pi, 50):
    for th2 in np.linspace(-np.pi, np.pi, 50):
        sol = solve_ivp(
            double_pendulum, (0.0, 10.0),
            [th1, th2, 0.0, 0.0],
            h=1e-2, args=args,
        )
        results[(th1, th2)] = sol.y
        progress.update(1)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;你可以切换窗口去稍微摸一会儿鱼了。在 Python 中，解释器执行这个双重循环，并且在最内层频繁调用数学函数，效率是极其低下的。&lt;/p&gt;
&lt;p&gt;跑完这 2500 条轨迹，可能需要十几分钟。如果你的网格扩大到 $1000 \times 1000$，那基本就可以下班了。&lt;/p&gt;
&lt;p&gt;这时候，就该让 GPU 出场了。&lt;/p&gt;
&lt;h3&gt;怎么用我的显卡？&lt;/h3&gt;
&lt;p&gt;在 Python 科学计算界，想用 GPU 加速有很多流派：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;JAX&lt;/strong&gt;：Google 出品，支持自动微分和 XLA 编译，非常强大。但它的生态深度绑定 Linux，在 Windows 上配置 CUDA 环境时常让人抓狂。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PyTorch / TensorFlow&lt;/strong&gt;：虽然是深度学习框架，但本质上也是张量计算库，完全可以用来做数值积分。只是为了解个方程引入这么庞大的库，略显臃肿。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Taichi / Numba&lt;/strong&gt;：需要你手动编写 Kernel 代码，学习成本较高。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我们以 &lt;strong&gt;CuPy&lt;/strong&gt; 为例教学。它的API对标 Numpy，说不定是最平易近人的，但肯定是最方便我们理解和使用的。&lt;/p&gt;
&lt;p&gt;它的核心理念可以用一句话概括：&lt;strong&gt;它是运行在 NVIDIA 显卡上的 NumPy。&lt;/strong&gt; 只要你的电脑有一张 N 卡，&lt;code&gt;pip install cupy&lt;/code&gt; 之后，把代码里的 &lt;code&gt;import numpy as np&lt;/code&gt; 换成 &lt;code&gt;import cupy as cp&lt;/code&gt;，绝大多数数组操作就能直接获得成百上千倍的加速。本质上，CuPy 在底层自动帮你把 NumPy 的广播操作编译成了 CUDA Kernel 并在几千个流处理器上并发执行。&lt;/p&gt;
&lt;p&gt;:::tip&lt;/p&gt;
&lt;p&gt;示例代码里已经写好能用的画图函数了，你可以直接用哦&lt;/p&gt;
&lt;p&gt;配置cuda和cupy本文略。这又是一个分硬件分人的事。&lt;/p&gt;
&lt;p&gt;NVIDIA提供的cuda进行数值计算，其他卡也提供了各自家显卡用于数值计算的库，且几乎都有python的包装，逻辑大同小异。&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;h3&gt;新增维度来代替循环&lt;/h3&gt;
&lt;p&gt;我们的循环基于 CPU 对代码逐个进行计算。GPU 不知道什么是循环，但它知道什么是矩阵。它为矩阵生，为矩阵死。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import cupy as cp  # 导入cupy，它的API与numpy类似。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;解 1 个双摆和解 2500 个双摆的逻辑是一模一样的，只是数组的维度变长了而已。我们将 2500 个 &lt;code&gt;[th1, th2, w1, w2]&lt;/code&gt; 拼成一个形状为 &lt;code&gt;(2500, 4)&lt;/code&gt; 的巨大二维矩阵，一次性喂给方程。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;double_pendulum_cp&lt;/code&gt;、&lt;code&gt;rk4_step&lt;/code&gt; 等函数的改动不提，简单把 &lt;code&gt;np&lt;/code&gt; 改 &lt;code&gt;cp&lt;/code&gt; 即可。只要注意量级：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def double_pendulum_cp(t, group_state, m, l, g):
    &quot;&quot;&quot;
    注意：这里的 group_state 形状是 (4, N)，N 是并行的双摆数量。
    CuPy 会自动对 N 这个维度进行并行广播运算。
    &quot;&quot;&quot;
    # 将所有np换为cp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们的 &lt;code&gt;solve_ivp&lt;/code&gt; 也要进行改动，主要是殺了循环&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def my_solve_ivp_cupy(
    fun, t_span, y0, h, args=(), step_func=rk4_step_cupy, show_progress=None
):
    t_start, t_end = t_span
    y0 = cp.asarray(y0)
    n_steps = int(np.ceil((t_end - t_start) / h))
    t_eval = np.linspace(t_start, t_end, n_steps + 1)
    # y_history 形状为 (状态数, 组数, 时间点数)
    y_history = cp.zeros((y0.shape[0], y0.shape[1], n_steps + 1), dtype=y0.dtype)
    y_history[:, :, 0] = y0
    current_y = y0
    iterator = range(n_steps)
    if show_progress:
        iterator = tqdm(iterator)
    for i in iterator:
        current_t = t_eval[i]  # 每次拿取下一个t值
        # 更新状态
        current_y = step_func(fun, current_t, current_y, h, args)
        y_history[:, :, i + 1] = current_y

    return GroupedOdeSolution(t_eval, y_history)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之后我们就可以组装大量的初值向量 &lt;code&gt;[th1, th2, p1, p2]&lt;/code&gt; 了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
    # 生成 50x50 网格初始角度
    theta1_vals = np.linspace(-np.pi, np.pi, 50)
    theta2_vals = np.linspace(-np.pi, np.pi, 50)
    aTH1, aTH2 = np.meshgrid(theta1_vals, theta2_vals, indexing=&quot;ij&quot;)
    theta1_init = aTH1.ravel()  # (2500,)
    theta2_init = aTH2.ravel()
    p1_init = np.zeros_like(theta1_init)
    p2_init = np.zeros_like(theta1_init)

    # 组装批量初始状态 (4, N)
    y0_np = np.array([theta1_init, theta2_init, p1_init, p2_init])
    y0_cp = cp.asarray(y0_np)

    sol = solve_ivp(
        double_pendulum_cp,
        t_span=(0.0, 10.0),
        y0=y0_cp,
        h=1e-3,
        step_func=rk5_step_cupy,
        args=args,
        show_progress=True,
    )
    results = {}
    for i, y in enumerate(sol.y):
        results[(i // 50, i % 50)] = y

    plot_dpmat(results, args, interval=1)
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;在主流的消费级显卡（例如 RTX 3060 或 4070）上，完成这 2500 个双摆长达 10000 步（总计两千五百万次状态更新）的计算，通常只需要几秒。—— Gemini&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;pic3.png&quot; alt=&quot;RK5,1e-3,0~10,100x100. GTX2060 6G,cupy. 42s.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;pic4.png&quot; alt=&quot;RK5,1e-2,0~10,500x250. GTX2060 6G,cupy. 5s.&quot; /&gt;
:::tip
因为100x100和250x500在我这里都没有超过一个批次的计算量，到显卡里也只是一瞬间的功夫，所以模拟规模在这里影响甚微。起主要作用的是步长：&lt;/p&gt;
&lt;p&gt;图一的参数下共迭代 &lt;code&gt;1e4&lt;/code&gt; 次，图二 &lt;code&gt;1e3&lt;/code&gt; 次，于是时间差了约十倍。
:::&lt;/p&gt;
&lt;h3&gt;关于显卡计算的一些坑与废话&lt;/h3&gt;
&lt;p&gt;上了显卡，虽然爽，但有几个重要的事必须交代清楚：&lt;/p&gt;
&lt;p&gt;:::tip&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 内存和显存之间的数据搬运一事&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;不要在 &lt;code&gt;for&lt;/code&gt; 循环内部频繁地将 CuPy 数组拉回 NumPy 数组（即把数据从显存搬回内存）。CPU 和 GPU 之间的数据传输通道（PCIe 总线）相对而言是非常慢的。&lt;/p&gt;
&lt;p&gt;正确的做法是：&lt;strong&gt;让数据在显卡里一直待到所有迭代结束&lt;/strong&gt;，最后只把需要的最终结果（或者稀疏采样的历史轨迹）传回内存。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. 为什么我们坚持用固定步长的 RK4，而不是把 RK45 搬上 GPU？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;GPU 最喜欢的是成千上万个线程做&lt;strong&gt;完全一样&lt;/strong&gt;的事情。它是典型的单指令多线程架构。&lt;/p&gt;
&lt;p&gt;RK45 的自适应步长里充满了 &lt;code&gt;if (error &amp;gt; tol)&lt;/code&gt; 的条件分支。如果 2500 个双摆中，有 1 个发生了剧烈翻滚需要缩小步长重算，那么显卡为了保持同步，会让另外 2499 个乖乖等待。这种现象叫做&lt;strong&gt;分支发散&lt;/strong&gt;，它会瞬间摧毁 GPU 的并行效率。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. 内存/显存爆了怎么办！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;当然，如果你要计算的边长更大，你可能还要进行分块和手动显卡渲染。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;分块&lt;/strong&gt;，顾名思义，组装 &lt;code&gt;y0_cp&lt;/code&gt; 之前先检查一下有多少组方程被同时计算，如果你的显存承受不了这个量级，那就先进行一次内存搬运，搬出去一批再算另一批，你的内存总不能比显存低吧……是这样吧？如果内存真的还不够的话，那可能要苦一下你的硬盘了，NumPy提供了高效的 &lt;code&gt;.npy&lt;/code&gt; 格式用于存储NumPy数组。记得把你不需要的数据洗出啦丢掉，比如公式中的广义动量。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;手动显卡渲染&lt;/strong&gt;，本章示例代码中提供了基础的CPU色彩渲染，每帧会根据角度动态计算每个色块的颜色，所以用&lt;code&gt;FuncAnimation&lt;/code&gt;播放会很卡。如果把所有帧的颜色数据先用显卡算好，再导出为视频文件，边长上限会更高。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. 精度陷阱：&lt;code&gt;float64&lt;/code&gt; vs &lt;code&gt;float32&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;NumPy 默认使用 &lt;code&gt;float64&lt;/code&gt;（双精度浮点数），而现代消费级游戏显卡（N 卡的 GeForce 系列）为了与专业计算卡（Tesla/Quadro）区分，在硬件层面上人为阉割了 &lt;code&gt;float64&lt;/code&gt; 的计算单元，其 FP64 性能通常只有 FP32（单精度）的 $1/32$ 甚至 $1/64$。&lt;/p&gt;
&lt;p&gt;CuPy 默认也会跟随你的输入类型。如果你发现 GPU 并没有想象中快，检查一下你是不是用了 &lt;code&gt;float64&lt;/code&gt;。但要注意，在求解微分方程时，单精度 &lt;code&gt;float32&lt;/code&gt; 会更快地积累截断误差，在长时间模拟中可能会导致系统崩溃。这是一个必须根据实际物理需求进行权衡的取舍。&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;h2&gt;下回预告&lt;/h2&gt;
&lt;p&gt;至此，我们已经成功利用普通的游戏显卡，完成了一次算力飞跃。&lt;/p&gt;
&lt;p&gt;但在长时间演化的物理系统（如天体力学或分子动力学）中，你会发现双摆的总能量并不守恒，这并不是代码写错了，而是 RK4 的数学基因决定的。&lt;/p&gt;
&lt;p&gt;下一节，我们将重新审视微分方程求解过程，分析更精确的&lt;strong&gt;隐式方法&lt;/strong&gt;和保结构的&lt;strong&gt;辛方法&lt;/strong&gt;。&lt;/p&gt;
</content:encoded></item><item><title>EdgeOne Pages Function+KV存储 简易入门</title><link>https://blog.emumu.xyz/posts/2026-04-11-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-04-11-00/</guid><description>如何快速从EO Pages创建一个API、以及存储一些东西！</description><pubDate>Tue, 14 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;EdgeOne Pages 提供了类似 Cloudflare Workers 的 Serverless 体系。但重要的区别是：EO 只有 KV 存储，没有 D1 数据库和 R2 对象存储。此外，还有不少难以评价的 Bug。·&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;pic1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;截止本文更新，几个严重的bug已经修复了，比如掉dev、返回ok等。我突然发现就在发文当天(2026-04-14 17:19:17)官方就更新了文档。&lt;/p&gt;
&lt;p&gt;Edgeone Pages截至目前仍然是测试阶段。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我们假设你已经有了一个正常上线的 EO Pages 项目，并使用 Git 进行管理。如果没有，请先去&lt;a href=&quot;https://cloud.tencent.com/document/product/1552/127369&quot;&gt;绑定一个空仓库&lt;/a&gt;并初始化一个 TypeScript 项目（没有前端并不影响 Function 的构建）。&lt;/p&gt;
&lt;h2&gt;从AI开始&lt;/h2&gt;
&lt;p&gt;如果你&lt;strong&gt;完全不希望了解一点原理&lt;/strong&gt;，但手头有很多赛博黑奴和马内，可以直接前往官方的&lt;a href=&quot;https://pages.edgeone.ai/zh/document/start-with-ai&quot;&gt;从AI开始&lt;/a&gt;，官方提供了MCP, Skills, &lt;code&gt;.mdc&lt;/code&gt;, &lt;code&gt;llms.txt&lt;/code&gt;。当然，出于我个人对代码的掌控欲，我还是强烈推荐你往下看。&lt;/p&gt;
&lt;h2&gt;EdgeOne CLI&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;本部分参考官方文档&lt;a href=&quot;https://pages.edgeone.ai/zh/document/edgeone-cli&quot;&gt;EdgeOne CLI&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;安装 CLI&lt;/h3&gt;
&lt;p&gt;将 Pages 项目克隆到本地后，使用以下命令全局安装 EdgeOne CLI：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install -g edgeone
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::tip
EdgeOne CLI代替node项目原本的dev。它通过查找项目&lt;code&gt;package.json&lt;/code&gt;中的dev获知原项目本身的dev命令，然后它在启动dev时，同时启动自身(functions)的dev环境和原项目的dev环境。如果你配置了&lt;code&gt;edgeone.json&lt;/code&gt; 中的 &lt;code&gt;devCommand&lt;/code&gt; 参数，它会优先读取。&lt;/p&gt;
&lt;p&gt;官方文档强调：“切记请勿在 edgeone.json 或 package.json 中配置 edgeone pages dev！”。&lt;/p&gt;
&lt;p&gt;不过可以配置别的。比如这个&lt;code&gt;&quot;edev&quot;&lt;/code&gt;。&lt;code&gt;pnpm edev&lt;/code&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// package.json
{
	&quot;private&quot;: true,
	&quot;type&quot;: &quot;module&quot;,
	&quot;scripts&quot;: {
		&quot;dev&quot;: &quot;vite dev --host 0.0.0.0 --port 20090&quot;,
		&quot;edev&quot;: &quot;edgeone pages dev --skip-env-sync true --port 20090&quot;,
		&quot;build&quot;: &quot;vite build&quot;,
		&quot;preview&quot;: &quot;vite preview --host 0.0.0.0 --port 21090&quot;,
		&quot;check&quot;: &quot;biome check&quot;
	},
	// ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--skip-env-sync true&lt;/code&gt; 用于跳过控制台环境变量同步&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--port 20090&lt;/code&gt; 用于重写edgeone自己重写了的端口，它默认使用&lt;code&gt;8088&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;h3&gt;工作流&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;(非必需)&lt;/em&gt; 运行&lt;code&gt;edgeone pages init&lt;/code&gt;初始化项目和实例。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;(必需) 通过&lt;code&gt;edgeone login&lt;/code&gt;登录，你Pages在哪就选哪个站。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;(强烈建议)&lt;/strong&gt; 通过&lt;code&gt;edgeone pages link&lt;/code&gt;绑定Pages项目，这可以同步环境变量，并且允许使用KV存储。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;最后，运行&lt;code&gt;edgeone pages dev&lt;/code&gt;开始本地调试。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;lt;details&amp;gt;
&amp;lt;summary&amp;gt;关于无法启动CLI(包括566)&amp;lt;/summary&amp;gt;&lt;/p&gt;
&lt;p&gt;Edge Functions 调试服务有启动次数限制，因此尽量避免频繁退出启动 dev 服务（dev 服务内热更新不会增加启动次数）。如果多次重启 Dev 导致报错 &lt;code&gt;566&lt;/code&gt;，除开账号抽风，通常就是触发了限制。建议此时去点杯奶茶，冷静一会再回来。&lt;/p&gt;
&lt;p&gt;&amp;lt;/details&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;details&amp;gt;
&amp;lt;summary&amp;gt;关于console不输出&amp;lt;/summary&amp;gt;&lt;/p&gt;
&lt;p&gt;EO CLI环境下，&lt;code&gt;console.log&lt;/code&gt;不通过前后端任意一边控制台输出。不知道什么毛病，出了问题只能放响应里返回。&lt;/p&gt;
&lt;p&gt;&amp;lt;/details&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;details&amp;gt;
&amp;lt;summary&amp;gt;【或已修复】关于返回&quot;ok&quot;但不是真实响应体&amp;lt;/summary&amp;gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;运行时未捕获异常误总会导致API返回plain text &lt;code&gt;script error&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;如果&lt;strong&gt;没有未捕获异常，正常执行成功&lt;/strong&gt;，这种情况可能出自&lt;strong&gt;文件在调试过程中被新创建&lt;/strong&gt;、&lt;strong&gt;调试时间过长&lt;/strong&gt;、&lt;strong&gt;网络中断过&lt;/strong&gt;的情况。&lt;/li&gt;
&lt;li&gt;该问题目前再未出现，或已被修复 (*2026-05-29)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;lt;/details&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;details&amp;gt;
&amp;lt;summary&amp;gt;【新bug】API返回404&amp;lt;/summary&amp;gt;&lt;/p&gt;
&lt;p&gt;刷新任意一个API文件，触发重新编译即可完美解决。&lt;/p&gt;
&lt;p&gt;通常出现于过长时间没修改任意一个云函数文件的情况。&lt;/p&gt;
&lt;p&gt;&amp;lt;/details&amp;gt;&lt;/p&gt;
&lt;h2&gt;Edge Function&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;本部分参考官方文档&lt;a href=&quot;https://pages.edgeone.ai/zh/document/edge-functions&quot;&gt;Edge Functions&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;在仓库根目录创建一个&lt;code&gt;edge-functions/&lt;/code&gt;文件夹。接着创建一个&lt;code&gt;hello.ts&lt;/code&gt;（强烈建议用ts，js有未知Bug）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// /edge-functions/hello.ts
export default function onRequest(context) {
  return new Response(&apos;Hello from Edge Functions!&apos;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这将从网站根目录起的&lt;code&gt;/hello&lt;/code&gt;创建一个API。&lt;/p&gt;
&lt;h3&gt;路由规则&lt;/h3&gt;
&lt;p&gt;Edge Functions 基于 &lt;code&gt;/edge-functions&lt;/code&gt; 目录结构生成访问路由。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;文件路径&lt;/th&gt;
&lt;th&gt;路由&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/edge-functions/index.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;example.com/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/edge-functions/hello-pages.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;example.com/hello-pages&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/edge-functions/helloworld.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;example.com/helloworld&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/edge-functions/api/users/list.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;example.com/api/users/list&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/edge-functions/api/users/geo.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;example.com/api/users/geo&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/edge-functions/api/users/[id].ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;example.com/api/users/1024&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/edge-functions/api/visit/index.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;example.com/api/visit&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/edge-functions/api/[[default]].ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;example.com/api/books/list&lt;/code&gt;、&amp;lt;br&amp;gt;&lt;code&gt;example.com/api/books/1024&lt;/code&gt;、&amp;lt;br&amp;gt;&lt;code&gt;example.com/api/&lt;/code&gt;...&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;:::warning[尾部斜杠的说明]
&lt;strong&gt;官方文档称：&lt;/strong&gt;&lt;em&gt;“路由尾部斜杠 / 是可选……如果与静态资源路由冲突，优先被路由到静态资源。”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;现实情况是：&lt;/strong&gt; 如果你的前端项目包含了同名路由，&lt;code&gt;/hello-pages/&lt;/code&gt; 极有可能被误判为静态资源从而返回 &lt;code&gt;404&lt;/code&gt;。带尾斜杠的行为非常不可控，&lt;strong&gt;强烈建议在请求时永远不要带尾部斜杠&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;同时出于以上问题，无法保证&lt;code&gt;/api/hello/index.ts&lt;/code&gt;和&lt;code&gt;/api/hello.ts&lt;/code&gt;的实际映射，尽管其他框架可能按事实标准分别映射到&lt;code&gt;/api/hello/&lt;/code&gt;和&lt;code&gt;/api/hello&lt;/code&gt;。避免混用 &lt;code&gt;/api/hello/index.ts&lt;/code&gt; 和 &lt;code&gt;/api/hello.ts&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;另外，路由大小写敏感。
:::&lt;/p&gt;
&lt;h3&gt;Function Handlers&lt;/h3&gt;
&lt;p&gt;通过在&lt;code&gt;.ts&lt;/code&gt;文件中&lt;code&gt;export&lt;/code&gt;如下各方法来Handle对应的HTTP请求&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Handlers 方法&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;onRequest(context: EventContext): Response | Promise&amp;lt;Response&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;匹配 HTTP Methods (&lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;PATCH&lt;/code&gt;, &lt;code&gt;PUT&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt;, &lt;code&gt;HEAD&lt;/code&gt;, &lt;code&gt;OPTIONS&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;onRequestGet(context: EventContext): Response | Promise&amp;lt;Response&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;匹配 HTTP Methods (&lt;code&gt;GET&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;onRequestPost(context: EventContext): Response | Promise&amp;lt;Response&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;匹配 HTTP Methods (&lt;code&gt;POST&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;onRequestXxx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;……&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;同时，支持同步和异步方法。注意CPU执行时间(200ms)的限制（无CPU异步如网络请求不算在内）。&lt;/p&gt;
&lt;p&gt;:::note
不导出任何有效Function Handlers的文件仍是项目的一部分，仅会使API不会被创建。
:::&lt;/p&gt;
&lt;p&gt;后续文档里的类型不全不提，有的还混有错误ts语法。我自己总结了一套能用的TS类型定义，可以放在上下文里辅助AI用。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 匹配所有 HTTP Method export
type EOFuncHandler = (context: EventContext) =&amp;gt; Response | Promise&amp;lt;Response&amp;gt;;

export interface EventContext { // 传递给Function Handlers的上下文
	request: Request; // 客户端请求对象 Request。
	params: Record&amp;lt;string, string | any&amp;gt;; // 动态路由 /edge-functions/api/users/[id].js 参数值。
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;KV 存储&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;本部分参考官方文档&lt;a href=&quot;https://pages.edgeone.ai/zh/document/kv-storage&quot;&gt;KV 边缘存储&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;基本概念&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;账户&lt;/strong&gt;：账户是Pages业务中KV用量统计和计费的最小单位。一个EO Pages账户对应一个KV账户，用户在控制台页面开通后创建。&lt;strong&gt;账户存储容量 1GB&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;命名空间&lt;/strong&gt;：数据隔离的唯一容器。一个账户最多10个命名空间。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;键值对&lt;/strong&gt;：键值对是一种用户存储数据的结构，其中每个数据项由两个部分组成：键（Key）和值（Value）。键是唯一的标识符，值是与键相关联的数据。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;变量名&lt;/strong&gt;：你的代码不直接通过“命名空间名”访问数据，而是通过“变量名”访问。在使用命名空间数据之前，需要先将命名空间与EO Pages项目通过变量名进行绑定。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph 项目A [Pages 项目 A]
        KV_A[&quot;变量名: USER&quot;]
    end
    subgraph 项目B [Pages 项目 B]
        KV_B[&quot;变量名: KV_USER&quot;]
        KV_ORDER[&quot;变量名: KV_ORDER&quot;]
    end
    subgraph 项目C [Pages 项目 C]
        KV_EXAMPLE[&quot;变量名: KV&quot;]
    end

    KV_A -- 绑定 --&amp;gt; NS_user
    KV_B -- 绑定 --&amp;gt; NS_user
    KV_EXAMPLE -.-&amp;gt; |可绑定| NS_user
    KV_EXAMPLE -.-&amp;gt; |或绑定| NS_inner_user
    KV_ORDER --&amp;gt; NS_order
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;重点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;虽然官方文档没提，但如cf地，&lt;strong&gt;每个键值对可以独立设置过期时间。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;可以通过前缀列出键。&lt;/li&gt;
&lt;li&gt;无同时操作多个键的API，但可以&lt;code&gt;Promise.all&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;初始化账户的KV存储&lt;/h3&gt;
&lt;p&gt;初始化账户的腾讯云UI操作请查看&lt;a href=&quot;https://pages.edgeone.ai/zh/document/kv-storage#391f1f77-b06f-4b70-838b-c14b8673df36&quot;&gt;#快速开始&lt;/a&gt;。&lt;/p&gt;
&lt;h3&gt;使用KV&lt;/h3&gt;
&lt;p&gt;定义变量名后直接在代码中使用该变量名即可。官方代码大量使用ts ignore掩耳盗铃。此处是我自行总结的类型定义，直接复制下面这段代码即可获得完美的类型提示，&lt;strong&gt;同时还可以供AI辅助理解上下文&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 匹配所有 HTTP Method export
export type EOFuncHandler = (
  context: EventContext,
) =&amp;gt; Response | Promise&amp;lt;Response&amp;gt;;

export interface EventContext {
  // 传递给Function Handlers的上下文
  request: Request; // 客户端请求对象 Request。
  params: Record&amp;lt;string, string | unknown&amp;gt;; // 动态路由如 /edge-functions/api/users/[id].js 的参数值。
}

export interface EO_KV {
  put(
    // 写入 KV 数据，用于创建新的键值对或者更新已有键值对的值。
    key: string,
    // 需要创建或更新的键，长度小于等于 512 B，仅支持数字、字母及下划线。仅支持单个键。
    value: string | ArrayBuffer | ArrayBufferView | ReadableStream,
    // 需要写入的数据，数据长度小于等于 25 MB。
    options?: { expirationTtl?: number },
    // 可以使用 expirationTtl 来指定过期时间，单位为秒，必须大于60s。
  ): Promise&amp;lt;void&amp;gt;; // 返回一个 Promise，需要 await 该 Promise 以验证写入是否成功。
  get(key: string): Promise&amp;lt;string | null&amp;gt;;
  get(key: string, options: { type: &quot;text&quot; }): Promise&amp;lt;string | null&amp;gt;;
  get(key: string, options: { type: &quot;json&quot; }): Promise&amp;lt;object | null&amp;gt;;
  get(
    // 根据特定的 key 读取 KV 中的数据，并根据指定类型返回数据。
    key: string, // 指定获取数据的 key。暂不支持批量获取。
    config?: { type: string }, // 用于指定返回的 value 类型，默认为 text。
    // text：String，将 value 转成 string 的形式返回。
    // json: Object，用于将 json 反序列化为 object 形式返回。
    // arrayBuffer: ArrayBuffer，用于将二进制的 value 转换为 ArrayBuffer 返回。
    // stream：ReadableStream，通常用于 value 较大的场景。
  ): Promise&amp;lt;string | object | ArrayBuffer | ArrayBufferView | ReadableStream&amp;gt;; // 返回一个 Promise。如果 key 不存在或 value 为空时，则返回 null。
  delete(
    // 从 KV 中删除指定的 key。
    key: string, // 需要删除的键值对的 key。
  ): Promise&amp;lt;void&amp;gt;; // 返回一个 Promise，需要 await 该 Promise 以验证删除是否成功。
  list(config: {
    // 用于遍历 KV 中的所有 key。
    prefix?: string; // 用于过滤指定前缀的键。默认为空时，按照字典序排序返回。
    limit?: number; // 返回的 key 的最大数量，用于分页。默认值为 256，上限为 256。
    cursor?: string; // 游标，从指定键开始遍历，用于分页。默认为空。
  }): Promise&amp;lt;null | {
    complete: boolean; // 标记 list 操作是否完成，true 完成，false 未完成。
    cursor: string | null; // 游标，为下一页的第一个 key，当 list 遍历完成时为 null。
    keys?: Array&amp;lt;{
      // 描述每个 key 的 object 数组。如果没有查询到任何 key，keys 为空。
      key: string; // 键值对的 key。
      expirationTtl: number; // 过期时间，单位为秒。
      expiration: number; // 过期时间戳(秒戳)
      meta: string; // ? 未知
    }&amp;gt;;
  }&amp;gt;;
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过以下代码即可定义一个提示，不影响实际运行。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;declare const MY_KV: EO_KV;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中&lt;code&gt;MY_KV&lt;/code&gt;是你绑定到Pages项目的的&lt;strong&gt;变量名&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;另外，测试得&lt;code&gt;expiration&lt;/code&gt;参数似乎不怎么好使。且向options传入任何额外的参数不会报错，此处原因未知、未在文档说明、且疑似近期(26.05)新增功能，建议优先使用&lt;code&gt;expirationTtl&lt;/code&gt;。&lt;/p&gt;
&lt;h3&gt;关于KV N+1查询问题&lt;/h3&gt;
&lt;p&gt;显然，&lt;code&gt;get&lt;/code&gt; 方法只支持传入单个 Key，不支持传入数组进行批量查询。当你使用 &lt;code&gt;list&lt;/code&gt; 获取了一堆 Key 之后，不可避免地会遇到 N+1 查询问题。&lt;/p&gt;
&lt;p&gt;我在&lt;a href=&quot;https://github.com/TencentEdgeOne/pages-templates/blob/5c9ac0487866c8d37fcdd7f1a17740c4216dba9e/examples/functions-kv/functions/kv-list/index.js#L15&quot;&gt;一个官方示例项目(点我传送)&lt;/a&gt;中找到了官方解决方案：强行&lt;code&gt;Promise.all&lt;/code&gt;。我猜测这个KV读取很快:spoiler[(提示：你可以笑)]以至于强大到根本无需一次性拿取所有数据。&lt;/p&gt;
&lt;p&gt;不过这么说，&lt;code&gt;list&lt;/code&gt;上限只有256是不是就有点耐人寻味了？&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const page = await my_kv.list({
  prefix: &apos;&apos;,
  cursor,
  limit: 10,
});
const keys = Array.isArray(page?.keys) ? page.keys : [];
const values = await Promise.all(
  keys.map(async (item) =&amp;gt; {
    const value = await my_kv.get(item.key);
    return {
      key: item.key,
      value,
      ttl: item.ttl,
      meta: item.meta,
    };
  })
);
allItems.push(...values);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;奖励看到最后的你&lt;/h2&gt;
&lt;p&gt;最后，送上一段我个人非常喜欢使用的工具函数，可以大幅简化拼装 Response 和处理跨域的代码，希望你也能喜欢。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// /edge-functions/utils.ts
export const CORS_HEADERS = {
  &apos;Access-Control-Allow-Origin&apos;: &apos;https://你的前端域名.com&apos;, // 建议别写 *
  &apos;Access-Control-Allow-Methods&apos;: &apos;GET, POST, OPTIONS&apos;,
  &apos;Access-Control-Allow-Headers&apos;: &apos;Content-Type, Authorization&apos;,
};

export function createResponse(body: any, status: number = 200, additionalHeaders = CORS_HEADERS) {
  return new Response(JSON.stringify(body), {
    status,
    headers: {
      &apos;Content-Type&apos;: &apos;application/json; charset=utf-8&apos;,
      ...additionalHeaders,
    },
  });
}

// createResponse({&quot;msg&quot;: &quot;Love from blog.emumu.xyz&quot;}, 200, CORS_HEADERS)
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>【学习笔记】数学笔记其二 · 三角函数</title><link>https://blog.emumu.xyz/posts/2026-03-19-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-03-19-00/</guid><description>考研数二的三角各种公式的复习、反三角函数、扩展三角函数、甚至双曲函数</description><pubDate>Thu, 19 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;序：关于整个三角函数及双曲函数的宏观视界&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在考研体系中，三角函数并不是一个孤立的章节，而是像一个高中知识一样贯穿于极限、导数、积分与微分方程的始终。很多同学（包括曾经的我:spoiler[和现在的我]）计算瓶颈，往往是因为底层的三角变形不熟练。这些三角函数也是高中不教大学不教的典型例子。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;普通三角函数&lt;/h2&gt;
&lt;p&gt;这一部分是所有复杂微积分操作的基石，主要考察的是在求极限时的等价代换，以及在求积分时的恒等变形。&lt;/p&gt;
&lt;h3&gt;初高中的公式复习&lt;/h3&gt;
&lt;p&gt;考研中不需要你去解复杂的三角迷宫，但以下几组核心公式必须形成肌肉记忆，它们是积分化简的核心工具：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;平方关系：&lt;/strong&gt; $\sin^2 x + \cos^2 x = 1$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;倍角公式：&lt;/strong&gt;
$$
\begin{align*}
&amp;amp;\sin(2x) = 2\sin x\cos x \
&amp;amp;\cos(2x) = \cos^2 x - \sin^2 x = 2\cos^2 x - 1 = 1 - 2\sin^2 x \
&amp;amp;\sin^2 (2x) = \frac{1-\cos{x}}{2} \
&amp;amp;\cos^2 (2x) = \frac{1+\cos{x}}{2}
\end{align*}
$$
&lt;strong&gt;和差化积与积化和差：&lt;/strong&gt;
$$
\begin{align*}
&amp;amp;\sin x \cos y = \frac{1}{2}[\sin(x+y) + \sin(x-y)] \
&amp;amp;\cos x \cos y = \frac{1}{2}[\cos(x+y) + \cos(x-y)]
\end{align*}
$$
&lt;strong&gt;处理线性组合（辅助角公式）：&lt;/strong&gt;
$$
\begin{align*}
&amp;amp;a\sin x + b\cos x = \sqrt{a^2+b^2}\sin(x+\varphi) \
&amp;amp;\tan\varphi = \frac{b}{a}
\end{align*}
$$&lt;/p&gt;
&lt;h3&gt;导数&lt;/h3&gt;
&lt;p&gt;$\tan{x}$的导数是走近扩展三角函数的起点&lt;/p&gt;
&lt;p&gt;$$(\tan x)&apos; = \sec^2 x$$&lt;/p&gt;
&lt;p&gt;至于怎么起，下一章再说&lt;/p&gt;
&lt;p&gt;&lt;s&gt;什么叫sinx的导数是什么&lt;/s&gt;&lt;/p&gt;
&lt;h3&gt;泰勒展开&lt;/h3&gt;
&lt;p&gt;在求极限时，单纯的等价无穷小（如 $x \to 0$ 时 $\sin x \sim x$）往往不够用。以下是必须背诵的麦克劳林展开式：
$$
\begin{align*}
&amp;amp;\sin x = x - \frac{x^3}{6} + \frac{x^5}{120} - o(x^5) \
&amp;amp;\cos x = 1 - \frac{x^2}{2} + \frac{x^4}{24} - o(x^4) \
&amp;amp;\tan x = x + \frac{x^3}{3} + \frac{2x^5}{15} + o(x^5)
\end{align*}
$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;注意 $\tan x$ 的系数规律性不强，建议手推或死记到三阶即可。五阶应用场景就很少见了。&lt;/li&gt;
&lt;li&gt;另外，sinx和cosx的无限推导虽然很好记，&lt;strong&gt;但不要忘了阶乘就行&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;扩展三角函数&lt;/h2&gt;
&lt;h3&gt;定义&lt;/h3&gt;
&lt;p&gt;定义非常简单，就是普通三角函数的倒数，有同样的周期性。
$$
\begin{align*}
\csc{x} &amp;amp;= \frac{1}{\sin{x}} \quad (\sin{x} \neq 0) \
\sec{x} &amp;amp;= \frac{1}{\cos{x}} \quad (\cos{x} \neq 0) \
\cot{x} &amp;amp;= \frac{1}{\tan{x}} = \frac{\cos{x}}{\sin{x}} \quad (\sin{x} \neq 0, \tan{x} \neq 0)
\end{align*}
$$
反扩展三角函数可以写成如下形式
$$
\begin{align*}
\operatorname{arccsc}{x} &amp;amp;= \arcsin{\frac{1}{x}} \quad (x \neq 0) \
\operatorname{arcsec}{x} &amp;amp;= \arccos{\frac{1}{x}} \quad (x \neq 0) \
\operatorname{arccot}{x} &amp;amp;= \arctan{\frac{1}{x}} = \frac{\pi}{2} - \arctan{x} \quad (x \neq 0)
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;itrif.png&quot; alt=&quot;红-csc, 蓝-sec, 绿-cot&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;从 $d(\tan x) = \sec^2 x dx$ 开始&lt;/h3&gt;
&lt;p&gt;很多同学对 $\sec x$（正割）感到陌生，但我们在积分中遇到它其实非常友好。因为 $(\tan x)&apos; = \sec^2 x$，这意味着在积分式中，只要你凑出了 $\sec^2 x dx$，就可以直接将其打包变成 $d(\tan x)$。这种微分的联动，是解决许多复杂三角积分的突破口。&lt;/p&gt;
&lt;p&gt;同时，由 $\sin^2 x + \cos^2 x = 1$ 两边同除 $\cos^2 x$，我们能得到扩展三角函数最重要的恒等式：
$$1 + \tan^2 x = \sec^2 x$$
同时，此处提及$\sec x$的导数：
$$(\sec x)&apos; = \sec x \tan x$$
这在分部积分中经常作为基础元件出现，因为这是普通三角函数和扩展三角函数的关联入口。&lt;/p&gt;
&lt;h3&gt;处理积分中的 $x^2-1$ 与 $x^2+1$&lt;/h3&gt;
&lt;p&gt;在不定积分和定积分中，当被积函数含有根号下的二次多项式时，三角代换是标准解法。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 遇到 $\sqrt{x^2+1}$ : 使用正切代换&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;令 $x = \tan t$，则 $dx = \sec^2 t dt$。此时 $\sqrt{x^2+1} = \sqrt{\tan^2 t + 1} = \sec t$。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;例题：&lt;/strong&gt; 求 $\int \frac{1}{(x^2+1)^{3/2}} dx$
$$
\begin{align*}
&amp;amp;\text{令}x = \tan t,,dx = \sec^2 t dt \
&amp;amp;\text{原式} = \int \frac{\sec^2 t dt}{(\sec^2 t)^{3/2}} = \int \frac{\sec^2 t}{\sec^3 t} dt = \int \cos t dt = \sin t + C \
&amp;amp;\text{有直角三角形中} \tan{t}=x=\frac{x}{1},\text{斜边为}\sqrt{x^2+1} \
&amp;amp;\text{故}\sin t = \frac{x}{\sqrt{x^2+1}} \
&amp;amp;\text{代回得原式}=\frac{x}{\sqrt{x^2+1}} + C
\end{align*}
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. 遇到 $\sqrt{x^2-1}$ : 使用正割代换&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;令 $x = \sec t$，则 $dx = \sec t \tan t dt$。此时 $\sqrt{x^2-1} = \sqrt{\sec^2 t - 1} = \tan t$。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;例题：&lt;/strong&gt; 求 $\int \frac{\sqrt{x^2-1}}{x} dx$&lt;/p&gt;
&lt;p&gt;结果：$\sqrt{x^2-1} - \arccos\frac{1}{x} + C$。读者自证不难。&lt;/p&gt;
&lt;p&gt;:::note
定义说过，$\operatorname{arcsec}{x} = \arccos{\frac{1}{x}}$。或者用反函数定义互相捯饬一下不难。
:::&lt;/p&gt;
&lt;h3&gt;另外两个兄弟&lt;/h3&gt;
&lt;p&gt;除了 $\sec x$，还有 $\csc x = \frac{1}{\sin x}$（余割）和 $\cot x = \frac{1}{\tan x}$（余切）。在数二的考纲和历年真题中，它们出现的频率极低。你只需要知道它们的存在，以及 $1 + \cot^2 x = \csc^2 x$ 这个关系即可，无需花费大量精力死磕。其基本逻辑其实和$\sin^2x+\cos^2x=1$，$\tan^2x+1=\sec^2x$是三面对称的，有兴趣可以自行探索&lt;/p&gt;
&lt;h3&gt;仍然是不重要的&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;泰勒展开：&lt;/strong&gt; 几乎不会考 $\sec x$ 等扩展三角函数的泰勒展开。如果真在极限题中遇到，千万不要去背它们复杂的展开式，现场利用等价代换（如 $\sec x = \frac{1}{\cos x}$，再用 $\cos x$ 的泰勒展开做除法或广义二项式展开）即可手推。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;反扩展三角函数：&lt;/strong&gt; 虽然理论上存在 $\text{arcsec} x$ 等反扩展三角函数，但遇到需要回代的情况，通常可以用 $\arccos\frac{1}{x}$ 这种形式绕过去。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;导数&lt;/strong&gt;：只要你不主动用$\csc x$和$\cot x$，就几乎都能用倒数糊弄过去。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;反三角函数&lt;/h2&gt;
&lt;p&gt;反三角函数在考研中&lt;strong&gt;极其重要&lt;/strong&gt;，AI总结了几个尤其，但我觉得它在哪都很重要，出现率和三角函数相当。一大原因是它的导数形式很适合到处塞。&lt;/p&gt;
&lt;h3&gt;导数和基本公式&lt;/h3&gt;
&lt;p&gt;反三角函数的导数公式是没有根号和有根号的分水岭，积分时如果看到分母有 $x^2+1$ 或 $\sqrt{1-x^2}$，要立刻条件反射想到：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;函数&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;导数&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;对应积分常考形式&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;$\arcsin x$&lt;/td&gt;
&lt;td&gt;$\frac{1}{\sqrt{1-x^2}}$&lt;/td&gt;
&lt;td&gt;$\int \frac{1}{\sqrt{a^2-x^2}} dx = \arcsin\frac{x}{a} + C$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\arccos x$&lt;/td&gt;
&lt;td&gt;$-\frac{1}{\sqrt{1-x^2}}$&lt;/td&gt;
&lt;td&gt;（考得少，因为可以用 $\arcsin$ 加负号代替）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\arctan x$&lt;/td&gt;
&lt;td&gt;$\frac{1}{1+x^2}$&lt;/td&gt;
&lt;td&gt;$\int \frac{1}{a^2+x^2} dx = \frac{1}{a}\arctan\frac{x}{a} + C$&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;利用图像的对称性，有两个恒等式在化简时能起到奇效：
$$\arcsin x + \arccos x = \frac{\pi}{2}$$
$$\arctan x + \text{arccot} x = \frac{\pi}{2}$$&lt;/p&gt;
&lt;h3&gt;泰勒&lt;/h3&gt;
&lt;p&gt;反三角函数的泰勒展开中，$\arctan x$ 是绝对的重点。它不仅在求极限时大有用处，其特殊形式还与圆周率 $\pi$ 的计算紧密相连。
$$x\to0,,,,\arctan x = x - \frac{x^3}{3} + \frac{x^5}{5} - \frac{x^7}{7} + o(x^7)$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;小拓展：&lt;/strong&gt; 如果令 $x = 1$，由于 $\arctan 1 = \frac{\pi}{4}$，我们就得到了著名的莱布尼茨公式计算 $\pi$：$\frac{\pi}{4} = 1 - \frac{1}{3} + \frac{1}{5} - \frac{1}{7} + \dots$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;至于 $\arcsin x$ 的泰勒展开较为复杂（包含双阶乘），只需知道 $x \to 0$ 时 $\arcsin x \sim x$ 即可。&lt;/p&gt;
&lt;h3&gt;图像及性质&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;atrif.png&quot; alt=&quot;反三角函数&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;$\arcsin x$：&lt;/strong&gt; 定义域 $[-1, 1]$，值域 $[-\frac{\pi}{2}, \frac{\pi}{2}]$。奇函数，单调递增。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;$\arccos x$：&lt;/strong&gt; 定义域 $[-1, 1]$，值域 $[0, \pi]$。非奇非偶函数，单调递减。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;$\arctan x$：&lt;/strong&gt; 定义域 $(-\infty, +\infty)$，值域 $(-\frac{\pi}{2}, \frac{\pi}{2})$。奇函数，单调递增。&lt;strong&gt;注意其水平渐近线：&lt;/strong&gt; $x \to +\infty$ 时 $y \to \frac{\pi}{2}$；$x \to -\infty$ 时 $y \to -\frac{\pi}{2}$。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;双曲函数&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;前言说明：&lt;/strong&gt; 双曲函数在数二的大纲中并不是硬性要求的核心考点，你完全可以用普通三角函数的知识覆盖它。&lt;strong&gt;但是&lt;/strong&gt;，对于学有余力、想要在积分计算上追求速度和准确率的同学来说，双曲函数是一个非常值得扩展的外挂。和高考不同，只要不跳步太多或者太二级结论，一般不会出现超纲解法扣分的情况。&lt;/p&gt;
&lt;p&gt;让我们从一道经典的难题入题：求解 $\int \frac{1}{\sqrt{x^2+1}} dx$&lt;/p&gt;
&lt;p&gt;我们前面讲过，令 $x = \tan t$，原式化为 $\int \sec t dt$。这个积分的结果是 $\ln|\sec t + \tan t| + C$。最后回代，得到 $\ln(x + \sqrt{x^2+1}) + C$。过程较为繁琐，且需要背诵 $\sec t$ 的积分。&lt;/p&gt;
&lt;p&gt;如果引入双曲函数，这道题的推导将变成简单的多项式级别的操作。下面我们来看看这个武器的真面目。&lt;/p&gt;
&lt;h3&gt;定义&lt;/h3&gt;
&lt;p&gt;双曲函数本质上是指数函数 $e^x$ 与 $e^{-x}$ 的线性组合，它们之所以被称为“双曲”，是因为它们的参数方程构成的是双曲线 $x^2 - y^2 = 1$，而不是圆。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;双曲正弦：&lt;/strong&gt; $\sinh x = \frac{e^x - e^{-x}}{2}$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;双曲余弦：&lt;/strong&gt; $\cosh x = \frac{e^x + e^{-x}}{2}$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;双曲正切：&lt;/strong&gt; $\tanh x = \frac{\sinh x}{\cosh x} = \frac{e^x - e^{-x}}{e^x + e^{-x}}$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心恒等式（对应三角的 $\sin^2 x + \cos^2 x = 1$）：&lt;/strong&gt;
$$\cosh^2 x - \sinh^2 x = 1$$
注意中间是减号，这意味着 $\sqrt{x^2+1}$ 如果用 $x = \sinh t$ 代换，直接就变成了 $\sqrt{\sinh^2 t + 1} = \cosh t$。&lt;/p&gt;
&lt;h3&gt;反函数（*重要，不背没法用）&lt;/h3&gt;
&lt;p&gt;如果你能记住反双曲函数的对数表达形式，很多带根号的复杂积分公式就再也不用死记硬背了。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;反双曲正弦：&lt;/strong&gt; $\text{arsinh} x = \ln(x + \sqrt{x^2+1})$&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;反双曲余弦：&lt;/strong&gt; $\text{arcosh} x = \ln(x + \sqrt{x^2-1})$ （$x \ge 1$）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;导数和基本公式&lt;/h3&gt;
&lt;p&gt;双曲函数的求导比三角函数舒适得多，因为没有负号交替：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$(\sinh x)&apos; = \cosh x$&lt;/li&gt;
&lt;li&gt;$(\cosh x)&apos; = \sinh x$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;另外，普通三角函数和双曲函数有一点微妙的关系&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;类别&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;普通三角函数&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;双曲函数&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;记忆点&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;关系&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$\sin^2 x + \cos^2 x = 1$&lt;/td&gt;
&lt;td&gt;$\cosh^2 x - \sinh^2 x = 1$&lt;/td&gt;
&lt;td&gt;双曲是减法&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;二倍角&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$\sin 2x = 2\sin x \cos x$&lt;/td&gt;
&lt;td&gt;$\sinh 2x = 2\sinh x \cosh x$&lt;/td&gt;
&lt;td&gt;完全一致&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;二倍角&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$\cos 2x = \cos^2 x - \sin^2 x$&lt;/td&gt;
&lt;td&gt;$\cosh 2x = \cosh^2 x + \sinh^2 x$&lt;/td&gt;
&lt;td&gt;双曲是加法&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;半角&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$\sin^2 x = \frac{1 - \cos 2x}{2}$&lt;/td&gt;
&lt;td&gt;$\sinh^2 x = \frac{\cosh 2x - 1}{2}$&lt;/td&gt;
&lt;td&gt;双曲相反&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;半角&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$\cos^2 x = \frac{1 + \cos 2x}{2}$&lt;/td&gt;
&lt;td&gt;$\cosh^2 x = \frac{\cosh 2x + 1}{2}$&lt;/td&gt;
&lt;td&gt;完全一致&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;例子&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;回到开头的积分 $I=\int \frac{1}{\sqrt{x^2+1}} dx$：
$$
\begin{align*}
&amp;amp;\text{令}x = \sinh t,,dx = \cosh t dt \
&amp;amp;I = \int \frac{\cosh t}{\sqrt{\sinh^2 t + 1}} dt = \int \frac{\cosh t}{\cosh t} dt = \int 1 dt = t + C \
&amp;amp;\text{回代：}t = \text{arsinh} x = \ln(x + \sqrt{x^2+1}) \
&amp;amp;I = \int \frac{1}{\sqrt{x^2+1}} dx = \ln(x + \sqrt{x^2+1}) + C
\end{align*}
$$
一步到位，同理，$\int \frac{1}{\sqrt{x^2-1}} dx$ 令 $x = \cosh t$ 也能瞬间得出 $\ln|x + \sqrt{x^2-1}| + C$。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;来一道&lt;a href=&quot;/posts/2026-02-17-01/&quot;&gt;上一个笔记&lt;/a&gt;里镇楼的题：$I=\int \sqrt{x^2 - 1} dx$&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;$$
\begin{align*}
&amp;amp;\text{令}x = \cosh t\ (x \geq 1, t \geq 0),,dx = \sinh t dt \
&amp;amp;I = \int \sqrt{\cosh^2 t - 1} \cdot \sinh t dt = \int \sinh t \cdot \sinh t dt = \int \sinh^2 t dt \
&amp;amp;\text{由双曲恒等式：}\sinh^2 t = \frac{\cosh 2t - 1}{2} \
&amp;amp;I = \int \frac{\cosh 2t - 1}{2} dt = \frac{1}{2}\int \cosh 2t dt - \frac{1}{2}\int 1 dt = \frac{1}{4}\sinh 2t - \frac{1}{2}t + C \
&amp;amp;\text{由倍角公式：}\sinh 2t = 2\sinh t \cosh t,\ \text{代入得}= \frac{1}{2}\sinh t \cosh t - \frac{1}{2}t + C \
&amp;amp;\text{回代：}\cosh t = x,\ \sinh t = \sqrt{x^2 - 1},\ t = \text{arcosh} x = \ln(x + \sqrt{x^2 - 1}) \
&amp;amp;I = \int \sqrt{x^2 - 1} dx = \frac{1}{2}x\sqrt{x^2 - 1} - \frac{1}{2}\ln(x + \sqrt{x^2 - 1}) + C
\end{align*}
$$
双曲，爽！&lt;/p&gt;
&lt;h3&gt;图像及性质&lt;/h3&gt;
&lt;p&gt;$\sinh x$：奇函数，穿过原点，形状类似 $y=x^3$ 但增长极快（因为是指数级）。单调递增。&lt;/p&gt;
&lt;p&gt;$\cosh x$：偶函数，图像像一条悬垂的铁链（悬链线），最低点在 $(0, 1)$。在 $x&amp;gt;0$ 单调递增。&lt;/p&gt;
&lt;p&gt;$\tanh x$：奇函数，被夹在 $y=-1$ 和 $y=1$ 两条水平渐近线之间，形状类似 $\arctan x$。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;dhf.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>新建文件夹 (2)</title><link>https://blog.emumu.xyz/posts/2026-03-18-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-03-18-00/</guid><description>点击输入文字</description><pubDate>Wed, 18 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;奥卡姆剃刀原则是越体会越精妙的，这东西简直到处都能解释得通。诡异的是，在提示词工程里恰恰相反。你少说一句，结果就差一句重点，你改成“不要怎样”，反而比“要怎样”更管用。所以提示词工程真的是很恼人的一个工程。至少对我而言。&lt;/p&gt;
&lt;p&gt;前两天有希群有个群友&lt;code&gt;pnpm i&lt;/code&gt;报错，报的是内存溢出的错，内存正常大小，ai支招加改限参数，改环境变量配置，不知道也是不是幻觉出来的配置键，未果。后来说是更新nodejs，也不知果没果。&lt;/p&gt;
&lt;p&gt;我很讨厌完全把工作交给ai的一大要素是ai不懂得“最小改动”和“一劳永逸”之间的平衡，或者类似的处事哲学。举例来说，ai为了在同一上下文留下“处理了xxx情况”这一标志，不惜动用大量代码重复地在调用链的各个位置处理同一个情况。其次，上下文不足的ai通常难以合理地模块化，即使它有模块化的想法，但它无法一锤定音，敲死模块的职责界限，比如在一个实现&lt;strong&gt;XXX依赖职责界限模糊&lt;/strong&gt;的容器且&lt;strong&gt;未大规模引用的模块中&lt;/strong&gt;，一个人类进行引用时合理的做法是在模块中&amp;lt;u&amp;gt;新增注释明确该容器的XXX职责范围，并查找其引用确保所有引用当前是符合规范的&amp;lt;/u&amp;gt;，这将以注释与同事或者未来的自己进行约定。但以上下划线部分完全由经验总结而成的具体行为准则，ai至今不能彻底无师自通（因为这只是大量不同经验场景行动中的一小部分），又不能将其塞进上下文，塞进提示词又琐碎，塞进skills它也不一定会去看。&lt;/p&gt;
&lt;p&gt;于是“冗余”诞生了。&lt;/p&gt;
&lt;p&gt;AI的“对而不好”的操作下，代码行数成了注水的统计指标。一个人干出cloc统计五位数甚至六位数行数的项目，总能给项目带来点面子。我曾经也是这样。前端项目一个人一个月一个AI从零写破万行已不是什么新鲜事。冗余自带指标色彩，而指标一旦成为目标，就不再是好的指标。&lt;/p&gt;
&lt;p&gt;适当的冗余对安全是有好处的。但当冗余过度，大量的无意义修改性注释压倒性地扑灭真正有价值的标记，代码库堆满了完全重复但又有点细节不同的逻辑，重复的轮子遍地跑，性能爆炸不提，bug无法稳定复现，拙劣的局部全局设计模式，外行的需求驱动的编程没有任何原则，在ai自己写出自信的注释里连ai自己也找不出bug在哪，看着代码里的人机聊天记录说是不是你环境有问题，每个边缘情况都被粗暴地打上补丁而非根治。项目维护成本飙升，新人入职光看代码就得半年。不对还看什么代码，当然是继续用ai往里边堆史啊哈哈哈哈😅&lt;/p&gt;
&lt;p&gt;这时，有人会说：既然如此，干脆否定程序员的价值，让Agent全权接管。反正AI能写代码，能修bug，虽然写得冗余，但架不住写得快啊。&lt;/p&gt;
&lt;p&gt;你别说，我无法反驳。谁知道再过两年世界会变成什么样……反正我可不想进这种地方干活。&lt;/p&gt;
&lt;p&gt;给得够另说。扯远了。&lt;/p&gt;
&lt;p&gt;抛开AI底层不谈，现在成品Agent如cc，codex，trae这类产品基本都能在人类不参与下在提示词层做出测试闭环。&lt;/p&gt;
&lt;p&gt;一种思路在闭环中增加关于可维护性、或者说专门用于决策方案合理性的子环在应用层是可行的。&lt;/p&gt;
&lt;p&gt;AI不能很快就做到这一点，它和现在相比半年前已经实现的测试闭环相比不是一个明确的概念，而是几句话不可能解释明白的改动方案甚至注释级别的平衡。而这种平衡本身在世界上也没能统一标准，因为一个改动经常要在解决眼下问题和从长远计划之间做一些选择。当然，这个问题即使是以前程序员来决策也是个问题，只不过学习和代码成本能使其主动下降到最优的方案，原始的懒惰驱动的最优化（？）在AI上不可行，因为AI一大特征就是快，快到可以先全写完再看能不能跑。甚至写完之后就会认为这件事解决了，哪怕没解决也会认为这么多的代码原本就是有用的，抑或是人类根本没发现这个冗余的甚至可能性能代价极大的代码，然后去尝试下一个方案。&lt;/p&gt;
&lt;p&gt;唉，一代人有一代人的屎山。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Mizuki主题存在一个很诡异的《强力滚动保护.js》，三百多行代码是仅用于保护Twikoo评论按钮点击导致的异常滚动问题的。这文件肯定是AI写的，从输出到控制台这事就能看出来。而同期同上游的Firefly主题，通过修改Twikoo源码重新构建从源头解决。从奥卡姆剃刀来看，将问题消除，而非新增解决方案。*但Firefly的问题是twikoo更新还需要再去自己构建，最终源头是解决twikoo，比如新增可选修复项。&lt;/p&gt;
&lt;p&gt;这一点上来说，我可能更注重代码库本身的逻辑量。&lt;em&gt;解决一个库带来的问题成为不可或缺的逻辑&lt;/em&gt;和&lt;em&gt;为了引入这个库，维护这个库的微修改版本&lt;/em&gt;哪个更好，还有待讨论。&lt;/p&gt;
&lt;p&gt;Mizuki正在水深火热重构中。原因是8.3引爆了某个惊天大雷导致样式全炸。后来有希决定拆分，这当然不再是堆史了，不过这个工作上来说仍然是AI可能完成的范围。&lt;/p&gt;
&lt;p&gt;AI同时负责开发和维护使得代码始终人类可读或许也是一种和AI和解的方式？&lt;/p&gt;
</content:encoded></item><item><title>2025年度总结</title><link>https://blog.emumu.xyz/posts/2026-02-17-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-02-17-00/</guid><description>硕果累累。而且还将继续收获一年。</description><pubDate>Tue, 17 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;爆竹声中一岁除，今年或许是我成长得最快的一年，简单回顾一下今年的经历吧&lt;/p&gt;
&lt;p&gt;上大学开始起我有个习惯，任何项目的目录名在前面加上年月当成已完成/已弃置的项目历史记录归档，基于此，下面就是今年的大部分比较有标志性的项目&lt;/p&gt;
&lt;h3&gt;2501地图画noir&lt;/h3&gt;
&lt;p&gt;我有一个mc 1.16.5的存档，在里面造过我最大的建筑也是地图画，今年我&lt;em&gt;应该&lt;/em&gt;是一次都没进过这个存档。我的游戏选择正在多元化，但总时间却在减少。没错，这个地图画自投影创建后就几乎未曾动工。&lt;/p&gt;
&lt;p&gt;起码mc陪了我十年，这个游戏我是不会忘的。希望如此吧，今年所有关于mc的圈名和头像几乎都被我清算了&lt;/p&gt;
&lt;h3&gt;2504 bpuffer.github.io&lt;/h3&gt;
&lt;p&gt;起因是老师让我总结一下我的python自学历程，而我当时恰好窥见博客圈的一角，此前也数次bing进个人博客并成功解决各种问题，本就有强烈建站想法的我便立刻开始了第一次建站，因为有html+css基础和刚刚可以开始解决问题的AI辅助，从零开始的vanilla建站十分顺利，此后又做了个学分自动计算的小页面相当于把js基础补全了。从这个意义上来讲，我建站应该也算有一年了（？）还是按域名算吧（&lt;/p&gt;
&lt;h3&gt;2505关于认证杯论文问题&lt;/h3&gt;
&lt;p&gt;认证杯是一个很特别的数学建模比赛。在他们老掉牙的论坛里，他们会&lt;strong&gt;开放所有人提交的论文&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这次比赛让我切实看到了数学建模中&lt;strong&gt;论文买卖产业&lt;/strong&gt;的基数。一期结果公布后，一群里展开了轰轰烈烈的反作弊风潮，我在其中使用各种工具甚至自行写特征算法查出了几十篇几乎可以确定是换色图的论文，甚至还有一些完全一模一样的论文，是的，&lt;strong&gt;他们完全没做查重&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;不论查重的技术有多高级，但起码获奖的论文该查一下吧？&lt;/p&gt;
&lt;p&gt;最后并非所有那些论文都被查处。不过我也无所谓了。一方面自己的参与奖不可能被翻身，另一方面认识到自己的力量太渺小也是一种成长的过程。国赛（高教社杯）目前仍然是最公平的比赛。我也大概明白小比赛都是什么妖魔鬼怪在获奖了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;rzb.png&quot; alt=&quot;一组出自同一论文商的队伍的对比图&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;2507...-jwgl&lt;/h3&gt;
&lt;p&gt;如&lt;a href=&quot;/posts/2025-10-25-00/&quot;&gt;反向代理的代价&lt;/a&gt;，这个假期我花了几乎所有时间去0.1基础学习vue+flask技术栈。那是我第二充实的假期，昼夜颠倒12小时整，醒了就是VSCode启动，关闭开发服务器倒头就睡。第一次选购服务器、选购域名、第一次工程化地考虑各种技术选型、学习响应式框架和浏览器知识。兴趣驱动居然可以对ADHD实现如此大的抑制，以至于完成后多遍测试我也无法想象自己真的完成了这件事。虽然日后又发现了很多bug，两个月过去也基本没了。非常宝贵的经验。&lt;/p&gt;
&lt;h3&gt;2509LBAS&lt;/h3&gt;
&lt;p&gt;说来也是运气好，我考试之前翻论文正好翻到一个优化算法，随手复刻了发现特异性有点强，今年高教社杯目标题型刚好考到一个优化，恰好传统方法就不行，这个优化方法就行。创新分应该是给了不少，代码也不是从零写的，也是第一次拿到了史高省一，爽。&lt;/p&gt;
&lt;h3&gt;2509typora2paper&lt;/h3&gt;
&lt;p&gt;我再也不会用word排版了。 typora现在是我的御用论文工具，花不少时间养好的css样式完全对齐论文样式。就打印件的可排版性而言，css是word的完全上位替。&lt;/p&gt;
&lt;p&gt;（obsidian还在学)&lt;/p&gt;
&lt;h3&gt;2510blog.tsukimiya.site&lt;/h3&gt;
&lt;p&gt;第一次进入博客圈是被Mizuki的宣传视频吸引进的群，此后了解到了非常多运维的知识，一步步造出了自己的小世界，还是很有成就感的&lt;/p&gt;
&lt;h3&gt;2601emumu.xyz&lt;/h3&gt;
&lt;p&gt;这就是我目前正在使用的新域名。目前正在抽时间开发实验室站lab.~(学React ing)，会包含一些自部署的开源小项目、小玩具什么的，还会有一些外链收集什么的（假期结束前应该会上线）敬请期待awa&lt;/p&gt;
&lt;p&gt;另外，实验室站正式发布后我会制作vanilla的www.~ 个人主页，这也是我目前不怎么积极友链的原因，因为日后还要改。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;以上。十分充实的一年，没提到的就是今年也好好决定了考研目标，可喜可贺。不过毕竟跨考，压力不小。目标不大，存活最好。&lt;/p&gt;
</content:encoded></item><item><title>【学习笔记】数学笔记其一 · 一些常见的积分技巧</title><link>https://blog.emumu.xyz/posts/2026-02-17-01/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-02-17-01/</guid><description>常见有理函数+根号下有理形式的积分解决和一些思路技巧</description><pubDate>Tue, 17 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;$\int \sqrt{x^2-1},\mathrm{dx}$ 看着很简单吧？速逃。别回头。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;众所周知，任何有理函数都可积。但其解法五花八门之严重导致新手入门入了门还在入门，看似简单的函数积出来却两张纸写不下。在题里算错得到，浪费大量时间则更致命（因为很少有非主观题会考特别复杂的积分）&lt;/p&gt;
&lt;p&gt;ps: 扩展了一下。有理+根号下有理的情况也很多，也很重要。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;int_common.jpg&quot; alt=&quot;有理函数积分难度速识（这张图可花了我不少功夫）&quot; /&gt;
图中按难度递进为&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;灰 - 入门/显式积分表&lt;/li&gt;
&lt;li&gt;蓝 - 需要大脑活动参与&lt;/li&gt;
&lt;li&gt;绿 - 要一点小巧思&lt;/li&gt;
&lt;li&gt;黄 - 基础十分坚实&lt;/li&gt;
&lt;li&gt;橙 - 奔最优解法直线走也比较费劲&lt;/li&gt;
&lt;li&gt;红 - 以这张图的范围，再难也难不到解不开的程度……吧？
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;其实是外形骗人的额外恶心分&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;答案（建议中键to新标签页）&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;$\frac{1}{x^2}$&lt;/th&gt;
&lt;th&gt;$\frac{1}{x}$&lt;/th&gt;
&lt;th&gt;$1$&lt;/th&gt;
&lt;th&gt;$x$&lt;/th&gt;
&lt;th&gt;$x^2$&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7B1%7D%7Bx%5E2(x%5E2-c%5E2)%7D&quot;&gt;$\frac{1}{x^2(x^2-c^2)}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7B1%7D%7Bx(x%5E2-c%5E2)%7D&quot;&gt;$\frac{1}{x(x^2-c^2)}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7B1%7D%7Bx%5E2-c%5E2%7D&quot;&gt;$\frac{1}{x^2-c^2}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7Bx%7D%7Bx%5E2-c%5E2%7D&quot;&gt;$\frac{x}{x^2-c^2}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7Bx%5E2%7D%7Bx%5E2-c%5E2%7D&quot;&gt;$\frac{x^2}{x^2-c^2}$&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7B1%7D%7Bx%5E2%5Csqrt%7Bx%5E2+c%5E2%7D%7D&quot;&gt;$\frac{1}{x^2\sqrt{x^2+c^2}}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7B1%7D%7Bx%5Csqrt%7Bx%5E2+c%5E2%7D%7D&quot;&gt;$\frac{1}{x\sqrt{x^2+c^2}}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7B1%7D%7B%5Csqrt%7Bx%5E2+c%5E2%7D%7D&quot;&gt;$\frac{1}{\sqrt{x^2+c^2}}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7Bx%7D%7B%5Csqrt%7Bx%5E2+c%5E2%7D%7D&quot;&gt;$\frac{x}{\sqrt{x^2+c^2}}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7Bx%5E2%7D%7B%5Csqrt%7Bx%5E2+c%5E2%7D%7D&quot;&gt;$\frac{x^2}{\sqrt{x^2+c^2}}$&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7B1%7D%7Bx%5E2%5Csqrt%7Bx%5E2-c%5E2%7D%7D&quot;&gt;$\frac{1}{x^2\sqrt{x^2-c^2}}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7B1%7D%7Bx%5Csqrt%7Bx%5E2-c%5E2%7D%7D&quot;&gt;$\frac{1}{x\sqrt{x^2-c^2}}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7B1%7D%7B%5Csqrt%7Bx%5E2-c%5E2%7D%7D&quot;&gt;$\frac{1}{\sqrt{x^2-c^2}}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7Bx%7D%7B%5Csqrt%7Bx%5E2-c%5E2%7D%7D&quot;&gt;$\frac{x}{\sqrt{x^2-c^2}}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7Bx%5E2%7D%7B%5Csqrt%7Bx%5E2-c%5E2%7D%7D&quot;&gt;$\frac{x^2}{\sqrt{x^2-c^2}}$&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7B1%7D%7Bx%5E2(x+c)%7D&quot;&gt;$\frac{1}{x^2(x+c)}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7B1%7D%7Bx(x+c)%7D&quot;&gt;$\frac{1}{x(x+c)}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7B1%7D%7Bx+c%7D&quot;&gt;$\frac{1}{x+c}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7Bx%7D%7Bx+c%7D&quot;&gt;$\frac{x}{x+c}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7Bx%5E2%7D%7Bx+c%7D&quot;&gt;$\frac{x^2}{x+c}$&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7B1%7D%7Bx%5E2%5Csqrt%7Bx+c%7D%7D&quot;&gt;$\frac{1}{x^2\sqrt{x+c}}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7B1%7D%7Bx%5Csqrt%7Bx+c%7D%7D&quot;&gt;$\frac{1}{x\sqrt{x+c}}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7B1%7D%7B%5Csqrt%7Bx+c%7D%7D&quot;&gt;$\frac{1}{\sqrt{x+c}}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7Bx%7D%7B%5Csqrt%7Bx+c%7D%7D&quot;&gt;$\frac{x}{\sqrt{x+c}}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7Bx%5E2%7D%7B%5Csqrt%7Bx+c%7D%7D&quot;&gt;$\frac{x^2}{\sqrt{x+c}}$&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7B%5Csqrt%7Bx+c%7D%7D%7Bx%5E2%7D&quot;&gt;$\frac{\sqrt{x+c}}{x^2}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7B%5Csqrt%7Bx+c%7D%7D%7Bx%7D&quot;&gt;$\frac{\sqrt{x+c}}{x}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Csqrt%7Bx+c%7D&quot;&gt;$\sqrt{x+c}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=x%5Csqrt%7Bx+c%7D&quot;&gt;$x\sqrt{x+c}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=x%5E2%5Csqrt%7Bx+c%7D&quot;&gt;$x^2\sqrt{x+c}$&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7Bx+c%7D%7Bx%5E2%7D&quot;&gt;$\frac{x+c}{x^2}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7Bx+c%7D%7Bx%7D&quot;&gt;$\frac{x+c}{x}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=x+c&quot;&gt;$x+c$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=x(x+c)&quot;&gt;$x(x+c)$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=x%5E2(x+c)&quot;&gt;$x^2(x+c)$&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7B%5Csqrt%7Bx%5E2-c%5E2%7D%7D%7Bx%5E2%7D&quot;&gt;$\frac{\sqrt{x^2-c^2}}{x^2}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7B%5Csqrt%7Bx%5E2-c%5E2%7D%7D%7Bx%7D&quot;&gt;$\frac{\sqrt{x^2-c^2}}{x}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Csqrt%7Bx%5E2-c%5E2%7D&quot;&gt;$\sqrt{x^2-c^2}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=x%5Csqrt%7Bx%5E2-c%5E2%7D&quot;&gt;$x\sqrt{x^2-c^2}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=x%5E2%5Csqrt%7Bx%5E2-c%5E2%7D&quot;&gt;$x^2\sqrt{x^2-c^2}$&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7B%5Csqrt%7Bx%5E2+c%5E2%7D%7D%7Bx%5E2%7D&quot;&gt;$\frac{\sqrt{x^2+c^2}}{x^2}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7B%5Csqrt%7Bx%5E2+c%5E2%7D%7D%7Bx%7D&quot;&gt;$\frac{\sqrt{x^2+c^2}}{x}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Csqrt%7Bx%5E2+c%5E2%7D&quot;&gt;$\sqrt{x^2+c^2}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=x%5Csqrt%7Bx%5E2+c%5E2%7D&quot;&gt;$x\sqrt{x^2+c^2}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=x%5E2%5Csqrt%7Bx%5E2+c%5E2%7D&quot;&gt;$x^2\sqrt{x^2+c^2}$&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7Bx%5E2-c%5E2%7D%7Bx%5E2%7D&quot;&gt;$\frac{x^2-c^2}{x^2}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=%5Cfrac%7Bx%5E2-c%5E2%7D%7Bx%7D&quot;&gt;$\frac{x^2-c^2}{x}$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=x%5E2-c%5E2&quot;&gt;$x^2-c^2$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=x(x%5E2-c%5E2)&quot;&gt;$x(x^2-c^2)$&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mathdf.com/int/#expr=x%5E2(x%5E2-c%5E2)&quot;&gt;$x^2(x^2-c^2)$&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;这个网站真的很好用，可惜没开源 TAT&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;初学级 - 灰蓝色部分&lt;/h2&gt;
&lt;h3&gt;快速线性换元&lt;/h3&gt;
&lt;p&gt;对于形如 $f(ax+b)$ 的积分，直接利用 $\mathrm{d}x = \frac{1}{a}\mathrm{d}(ax+b)$得&lt;/p&gt;
&lt;p&gt;$$\int{f(ax+b) ,\mathrm{d}x}=\frac{1}{a}F(ax+b)+C$$&lt;/p&gt;
&lt;h3&gt;因式分解与分式裂项&lt;/h3&gt;
&lt;p&gt;就是用初中数学原理翻腾一遍多项式。&lt;/p&gt;
&lt;p&gt;例如：
$$
\begin{aligned}&lt;/p&gt;
&lt;p&gt;\int \frac{1}{x^2-c^2} ,\mathrm{d}x \&lt;/p&gt;
&lt;p&gt;\text{(因式分解)} \quad &amp;amp;= \int \frac{1}{(x-c)(x+c)} ,\mathrm{d}x \&lt;/p&gt;
&lt;p&gt;\text{(分式裂项)} \quad &amp;amp;= \int \frac{1}{2c}\left( \frac{1}{x-c} - \frac{1}{x+c} \right) ,\mathrm{d}x \&lt;/p&gt;
&lt;p&gt;&amp;amp;= \frac{1}{2c}\ln\left| \frac{x-c}{x+c} \right| + C&lt;/p&gt;
&lt;p&gt;\end{aligned}
$$
这个以后会单独出文细说。&lt;/p&gt;
&lt;h3&gt;换元和凑微分&lt;/h3&gt;
&lt;p&gt;处理 $x$ 与 $\sqrt{x+c}$ 或 $x^2$ 关系的入门招式。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;根式换元&lt;/strong&gt;：遇到 $\sqrt{a x+b}$，令 $t = \sqrt{a x+b}$ 往往能化根式为多项式。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;凑微分&lt;/strong&gt;：观察分子是否为分母的导数。例如 $\int \frac{x}{x^2-c^2}\mathrm{dx} = \frac{1}{2}\int \frac{\mathrm{d}(x^2-c^2)}{x^2-c^2}$。
$\frac{x}{(ax^2+b)^n}$形的指定杀器。
:::tip
如果整体匹配上了但系数没匹配上，建立一个直觉，系数是可以随意出入积分号的，这代表外部是可以随意补系数进来的。
:::&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;基础级 - 绿黄色部分&lt;/h2&gt;
&lt;h3&gt;反三角的积分公式&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;$\int \frac{1}{\sqrt{c^2-x^2}}\mathrm{dx} = \arcsin\frac{x}{c} + C$ (没有 $1/c$)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$\int \frac{1}{c^2+x^2}\mathrm{d}x = \frac{1}{c}\arctan\frac{x}{c} + C$ (有 $1/c$)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;分部积分法&lt;/h3&gt;
&lt;p&gt;$$\int u ,\mathrm{d}v = uv - \int v ,\mathrm{d}u$$
或者更直观的“凑微分”的理论形式：
$$\int f(x)g&apos;(x) ,\mathrm{d}x = f(x)g(x) - \int g(x)f&apos;(x) ,\mathrm{d}x$$&lt;/p&gt;
&lt;p&gt;这应该是基本功，但实际上一开始很多人就完全意识不到怎么设u，或者说根本意识不到可以用分部积分法解决。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;LIATE原则&lt;/strong&gt;是一个用于分部积分法的记忆法则，表示选择函数的优先顺序。具体来说，LIATE代表以下顺序：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;L&lt;/strong&gt;: 对数函数 - Logarithmic functions
$$
u=\ln x \quad du=\frac{1}{x}dx
$$
典型应用：$\int \ln x ,\mathrm{d}x$&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;I&lt;/strong&gt;: 反三角函数 - Inverse trigonometric functions
$$
u=\arctan \frac{x}{c} \quad du=\frac{c}{x^2+c^2}dx
$$
典型应用：$\int \arctan x ,\mathrm{d}x$&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A&lt;/strong&gt;: 代数函数 - Algebraic functions
$$
u=x \quad du=dx
$$
典型应用：$\int x \sin x ,\mathrm{d}x$（又称降幂积分，再下面有特别说）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;T&lt;/strong&gt;: 三角函数 - Trigonometric functions
$$
u=\sin x \quad \mathrm{d}u=\cos x ,\mathrm{d}x
$$
典型应用：$\int e^x \sin x ,\mathrm{d}x$（分部两次的循环积分）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;E&lt;/strong&gt;: 指数函数 - Exponential functions
$$
u=e^x \quad \mathrm{d}u=e^x ,\mathrm{d}x
$$
典型应用：（这个还是老老实实当dv吧……）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;优先选择LIATE中靠前的函数作为u，剩余函数作为dv，可以简化计算过程。&lt;/p&gt;
&lt;p&gt;以上典型应用读者自证不难。&lt;/p&gt;
&lt;p&gt;:::caution
LIATE 不是物理定律，只是经验法则。可以优先尝试，切勿奉为圭臬。
:::&lt;/p&gt;
&lt;h3&gt;一条超绝近路&lt;/h3&gt;
&lt;p&gt;$$
\int{\frac{1}{\sqrt{x^2\pm c^2}}\mathrm{d}x}=\ln\left(\left|\sqrt{{x}^{2}\pm{c}^{2}}+x\right|\right)+C
$$
我的建议是直接背诵。遇到 $\frac{1}{\sqrt{x^2+c^2}}$ 或 $\frac{1}{\sqrt{x^2-c^2}}$ 时，直接套用对数形式公式，不需要再走三角代换的老路，也是一些红橙区的基础，能省下大量时间。&lt;/p&gt;
&lt;p&gt;如果实在想弄清楚为什么，可以前往&lt;a href=&quot;/posts/2026-03-19-00/#%E5%8F%8C%E6%9B%B2%E5%87%BD%E6%95%B0&quot;&gt;笔记之二的双曲函数章节&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;到这里你应该已经学会处理这六种情况及其扩展情况了：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;形式&lt;/th&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;结果&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;$\int{\frac{1}{x^2+c^2},\mathrm{d}x}$&lt;/td&gt;
&lt;td&gt;套反三角公式&lt;/td&gt;
&lt;td&gt;$\frac{1}{c} \arctan \frac{x}{c} + C$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\int{\frac{1}{x^2-c^2},\mathrm{d}x}$&lt;/td&gt;
&lt;td&gt;因式分解&lt;/td&gt;
&lt;td&gt;$\frac{1}{2c} \ln \left\vert \frac{x - c}{x + c} \right\vert + C$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\int{\frac{1}{c^2-x^2},\mathrm{d}x}$&lt;/td&gt;
&lt;td&gt;因式分解&lt;/td&gt;
&lt;td&gt;$\frac{1}{2c} \ln \left\vert \frac{c + x}{c - x} \right\vert + C$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\int{\frac{1}{\sqrt{x^2+c^2}},\mathrm{d}x}$&lt;/td&gt;
&lt;td&gt;套积分表&lt;/td&gt;
&lt;td&gt;$\ln \left\vert \sqrt{x^2 + c^2} + x \right\vert + C$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\int{\frac{1}{\sqrt{x^2-c^2}},\mathrm{d}x}$&lt;/td&gt;
&lt;td&gt;套积分表&lt;/td&gt;
&lt;td&gt;$\ln \left\vert \sqrt{x^2 - c^2} + x \right\vert + C$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\int{\frac{1}{\sqrt{c^2-x^2}},\mathrm{d}x}$&lt;/td&gt;
&lt;td&gt;套反三角公式&lt;/td&gt;
&lt;td&gt;$\arcsin \frac{x}{c} + C$&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;毕业级 - 橙红色部分&lt;/h2&gt;
&lt;h3&gt;换元之三角代换&lt;/h3&gt;
&lt;p&gt;当以上路子全部行不通时，根号内平方和/差可以利用三角恒等式尝试消根号：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;遇到 $\sqrt{a^2-x^2}$&lt;/strong&gt;：令 $x = a\sin\theta$，利用 $1-\sin^2\theta = \cos^2\theta$。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;遇到 $\sqrt{a^2+x^2}$&lt;/strong&gt;：令 $x = a\tan\theta$，利用 $1+\tan^2\theta = \sec^2\theta$。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;遇到 $\sqrt{x^2-a^2}$&lt;/strong&gt;：令 $x = a\sec\theta$，利用 $\sec^2\theta-1 = \tan^2\theta$。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;PS: 作者真的很讨厌拓展三角函数。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;:::caution[CAUTION: 男生女生特别扣分的两点]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;积分结束后是 $\theta$ 的函数，回代时可以画出直角三角形，根据边角关系强行还原回$x$，不要尝试手动解决譬如$\tan(\arcsin{x})$的问题，几何法真可以秒杀。&lt;/li&gt;
&lt;li&gt;换元微分项：换元时千万别忘了 $\mathrm{d}x$ 也要变，例如 $x=a\tan\theta \Rightarrow \mathrm{d}x = a\sec^2\theta,\mathrm{d}\theta$。定积分的话上下限也要变。
:::&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;换元之倒代换&lt;/h3&gt;
&lt;p&gt;当分母的 $x$ 次数高于分子，或分母结构为 $x^n\sqrt{\text{二次型}}$ 时，直接换元。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;操作&lt;/strong&gt;：令 $x = \frac{1}{t}$，则 $\mathrm{d}x = -\frac{1}{t^2}\mathrm{d}t$。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;奇效&lt;/strong&gt;：它能把深陷分母的 $x$ 提到分子位置，或将复杂的根式内项转化为容易凑微分的形式。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;典型应用&lt;/strong&gt;：$\int \frac{1}{x^2\sqrt{x^2-c^2}},\mathrm{d}x$。倒代换后，原积分会瞬间坍缩为简单的三角函数积分。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;升降幂积分与回环积分&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;升降幂这个名字是我自己起的。这种技巧似乎没有统一正式常用的名字，但这个方法是实实在在非常常用。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;升降幂积分实际上就是分部积分法的特殊情况，其特殊之特使得我必须拿出来强调一下。他可以处理一个你十分熟悉的函数f(x)的以下两种变体：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;升幂积分&lt;/strong&gt;：
$$\int f(x) ,\mathrm{d}x = x f(x) - \int x f&apos;(x) ,\mathrm{d}x$$
&lt;strong&gt;降幂积分&lt;/strong&gt;：
$$\int x f(x) ,\mathrm{d}x = x F(x) - \int F(x) ,\mathrm{d}x \quad (\text{其中 } F&apos;(x) = f(x))$$&lt;/p&gt;
&lt;p&gt;或者简单点说：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;升幂&lt;/strong&gt;：适用于 $f(x)$ 积不动但导数很简单的函数（如 $\ln x, \arctan x$）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;降幂&lt;/strong&gt;：适用于 $f(x)$ 积得动，但前面的 $x$ 很碍事的情况（如 $x \cos x$）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;针对 $x^2\sqrt{x^2\pm c^2}$ 或 $\sqrt{x^2\pm c^2}$ 这种红区重灾区，可以使用升降幂积分恢复或消耗x因子。又，升降幂积分又经常连接到一类特殊情况：&lt;strong&gt;回环积分&lt;/strong&gt;，名字挺大气，实际上你一看就明白了：
$$
\begin{align}&lt;/p&gt;
&lt;p&gt;\int \sqrt{x^2 + c^2} ,\mathrm{d}x &amp;amp;= x\sqrt{x^2 + c^2} - \int \frac{x^2}{\sqrt{x^2 + c^2}} ,\mathrm{d}x \quad\text{(升幂积分)} \&lt;/p&gt;
&lt;p&gt;&amp;amp;= x\sqrt{x^2 + c^2} - \int \frac{x^2 + c^2 - c^2}{\sqrt{x^2 + c^2}} ,\mathrm{d}x \&lt;/p&gt;
&lt;p&gt;&amp;amp;= x\sqrt{x^2 + c^2} - \int \sqrt{x^2 + c^2} ,\mathrm{d}x + c^2 \int \frac{1}{\sqrt{x^2 + c^2}} ,\mathrm{d}x \&lt;/p&gt;
&lt;p&gt;2\int \sqrt{x^2 + c^2} ,\mathrm{d}x &amp;amp;= x\sqrt{x^2 + c^2} +  c^2 \int \frac{1}{\sqrt{x^2 + c^2}} ,\mathrm{d}x\quad\text{(&amp;lt;-这是上一节的公式)}&lt;/p&gt;
&lt;p&gt;\end{align}
$$
:::tip[恭喜]
你已经能解决了开头的速逃题了。现在上手试试吧？
:::&lt;/p&gt;
&lt;p&gt;:::caution
&lt;strong&gt;非主观题如果真出了红区题，建议还是检查一下之前步骤对不对。所有红区题我几乎没在非主观题里见到实用场景。最大的应用场景是迷途知返检查错误。&lt;/strong&gt;
:::&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;感谢Google Gemini对本文提供的大力支持。眼花缭乱的符号真的很难看清有没有错漏。&lt;/p&gt;
</content:encoded></item><item><title>关于新博客的Banner实现</title><link>https://blog.emumu.xyz/posts/2026-01-27-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-01-27-00/</guid><description>超细节的纯CSS图片视差渐变水波纹效果</description><pubDate>Tue, 27 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;那么我的要求是这样：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Banner中间的文本会挡在图片中的某一固定部分，而且它会随文档流滚动，所以&lt;strong&gt;Banner背景必须拥有滚动视差&lt;/strong&gt;。其中视口视差是较好的方案。鼠标视差比较吃性能，而且几乎不可避免js且不兼容移动端。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;阅读文章的过程中没有背景（即便只有两侧的装饰，并且移动端也有模糊）会十分单调。若分设两个背景，在从Banner展示页（通常是主页）过渡到正文时，全局背景必然早已加载。因此&lt;strong&gt;Banner展示页必须同时拥有两个背景&lt;/strong&gt;，一个banner随机大图，另一个是普通阅读时的装饰背景。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Banner背景与正文背景之间必须以优雅的水波过渡&lt;/strong&gt;。单纯为美观考虑，这种“优雅的水波过渡”可以为以水波为分级分隔的多级渐变。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果不能兼容移动端，采取一个移动端能接受的方式。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;要求提完了，接下来该开始到处碰壁了。&lt;/p&gt;
&lt;h2&gt;实现基本逻辑&lt;/h2&gt;
&lt;h3&gt;H5结构&lt;/h3&gt;
&lt;p&gt;这方面没什么好说的，外面一个方形窗口用来挡住里面的异形轨道，就像录像带的那个窗口，里面的异形轨道接入&lt;code&gt;clip-path&lt;/code&gt;制造波浪以真裁切这个视窗再内部的&lt;code&gt;bg-fixed&lt;/code&gt;图片。&lt;/p&gt;
&lt;h3&gt;外层窗口的限制&lt;/h3&gt;
&lt;p&gt;通过&lt;code&gt;overflow-x-hidden&lt;/code&gt;和&lt;code&gt;width&lt;/code&gt;确定宽度避免撑开，准备承接多个track子元素。&lt;/p&gt;
&lt;p&gt;实际代码中用的是固定宽度是避免不同设备上波浪的频率不同。&lt;/p&gt;
&lt;h3&gt;中部异形轨道的移动&lt;/h3&gt;
&lt;p&gt;采用&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@keyframes banner2-desktop-cycle {
    0% { left: 0; }
    100% { left: calc(-1 * var(--banner-width)); }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;无限线性循环可以使得视窗向左滚动后极限拉回，然后再使用&lt;code&gt;absolute w-[200%]&lt;/code&gt;确定为外层窗口的两倍宽用于无缝衔接。这样做数学上有个bug就是这样频率只能设定为宽度的整除倍，目前没什么好的解决方案。&lt;/p&gt;
&lt;p&gt;使用&lt;code&gt;left&lt;/code&gt;动画是因为&lt;code&gt;translate&lt;/code&gt;动画会导致&lt;code&gt;bg-fixed&lt;/code&gt;失效。这是W3C Recommendation现在&lt;a href=&quot;https://drafts.csswg.org/css-transforms/#transform-rendering&quot;&gt;明文文档建议&lt;/a&gt;级别的。&lt;/p&gt;
&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;被&lt;code&gt;transform&lt;/code&gt;影响的元素，其 &lt;code&gt;background‑attachment: fixed&lt;/code&gt; 渲染时视为 &lt;code&gt;scroll&lt;/code&gt;，计算值不变。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;然而&lt;code&gt;left&lt;/code&gt;终究是布局元素，动这么大的图片是会出事的。在性能一般的手机上多个大图这样移动时会导致闪屏，不得不用&lt;code&gt;translate&lt;/code&gt;替代。&lt;/p&gt;
&lt;p&gt;将各个轨道设置不同的动画时长、&lt;code&gt;clip-path&lt;/code&gt;、透明度就能自定义水波的参数。&lt;code&gt;absolute&lt;/code&gt;叠加即可实现多层水波纹效果。&lt;/p&gt;
&lt;h3&gt;内部图片的固定&lt;/h3&gt;
&lt;p&gt;内部图片，桌面端的纹理自然可以用&lt;code&gt;bg-fixed&lt;/code&gt;直接固定，但手机端因为用了&lt;code&gt;translate&lt;/code&gt;不太好这么做。&lt;/p&gt;
&lt;p&gt;在尝试了包括但不限于&lt;code&gt;sticky&lt;/code&gt;(照样会被&lt;code&gt;translate&lt;/code&gt;杀)、滚动进度动画(实在太新了)等方案，我决定以毒攻毒，用&lt;code&gt;translate&lt;/code&gt;本身抵消&lt;code&gt;translate&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;移动端现在中部使用左循环移动视窗，内部的图片使用右移动抵消左移动，牺牲纵向滚动视差，同时用上了各种优化，好歹是能用了。&lt;/p&gt;
&lt;h3&gt;闪屏的解决方案(26.03.23)&lt;/h3&gt;
&lt;p&gt;闪烁原因是一张张巨大的图片在屏幕上移动同时计算透明度会吃掉移动端本就一般的显卡巨量的性能造成失帧。&lt;/p&gt;
&lt;p&gt;解决方案是优化clippath svg路径使其只处理水波纹部分，就像这样：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;wave.png&quot; alt=&quot;波纹以上的图片被切除了&quot; /&gt;&lt;/p&gt;
&lt;p&gt;然后再添加一张不动，普通的，反而是下面波纹部分被切去的图片：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;static_one.png&quot; alt=&quot;静止的那个&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这项改动并不复杂，但其效果是巨大的（我怎么早没想到）&lt;/p&gt;
&lt;p&gt;这个最低的分割高度应当满足：
$$
\mathrm{SplitHeight}_i = \operatorname{max}_i^n,(H_i + A_i)
$$
即&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 最大的高度+振幅
const maxVbpa = Math.max(...heights.map((h, i) =&amp;gt; {
	return h + amplitudes[i]
}));
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;波浪SVG&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;// 动态的水波层

const wT; // 一宽的循环次数，越大频率越高。经验值桌面3~4移动7~8
const A; // 振幅，单位1=图片高度
const vb; // 高度修正。为正时从底部提高，单位1=图片高度
const maxVbps; // 

const w = 1 / 4 / wT; // 循环节长度
const wc = 4 / 25 / wT; // 二次贝塞尔近似三角函数的控制点经验值
const repeatTimes = Math.ceil(0.4999 / w); // 避免误差ceil到上一级
const wavePath =
`M0,${1 - vb} ` + // 起始点，从左下角开始上升到最低高度，最低高度由此生效
`c${w/2},0,${wc},${-A},${w},${-A} s${wc},${A},${w},${A} ` +
(
	`${wc},${-A},${w},${-A} ` + // 上升段
	`${wc},${A},${w},${A} ` // 下降段
).repeat(repeatTimes - 1) + // 循环，注意忽略第一节（第一节是cs不是ss）
`v${-maxVbps} h-${repeatTimes * 2 * w} z`; // 垂直上升至波峰(v -A) → 水平左移回左侧(h -总宽度) → 闭合路径(z)，形成封闭裁剪区域

// 静态的那个图片

const staticBannerPath = `M0,0 v${1-maxVbps} h1 v${maxVbps-1} z`;

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Code&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;banner2-window&quot;&amp;gt;
	&amp;lt;div class=&quot;banner2-track track-a&quot;&amp;gt;&amp;lt;/div&amp;gt;
	&amp;lt;div class=&quot;banner2-track track-b&quot;&amp;gt;&amp;lt;/div&amp;gt;
	&amp;lt;!-- etc. --&amp;gt;
	&amp;lt;div class=&quot;banner2-track banner2-static-track&quot;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.track-a { animation-duration: 2s; clip-path: url(#clip-path-a); }
.track-b { animation-duration: 3s; clip-path: url(#clip-path-b); }
/* etc. */

.banner2-window {
    --banner-height: 100%;
    position: absolute;
    inset: 0;
    width: var(--banner-width);
    height: var(--banner-height);
    overflow-x: hidden;
}

.banner2-track {
    position: absolute;
    width: 200%;
    height: 100%;
    display: flex;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
    z-index: 2;
}

.banner2-track.banner2-static-track {
	position: absolute;
	left: 0;
	width: 100vw;
	height: 100%;
	display: flex;
	box-sizing: border-box;
	background: no-repeat top / cover;
	background-image: var(--banner2-track-bg);
}

.banner2-track.banner2-static-track::after {
	display: none;
}

.banner2-track::after {
    position: sticky;
    left: 0;
    width: 50%;
    height: 100%;
    content: &apos;&apos;;
    display: block;
    box-sizing: border-box;
    background-image: var(--banner2-track-bg);
    background-repeat: no-repeat;
}

/* 桌面端 */
@media (min-width: 1025px) {
    .banner2-window {
        --banner-width: 2560px;
        left: calc(50% - var(--banner-width) / 2);
    }
    
    .banner2-track {
        animation-name: banner2-desktop-cycle;
    }
    
    .banner2-track::after {
        background: no-repeat fixed center / cover;
    }
}

/* 手机端 */
@media (max-width: 1024px) {
    .banner2-window {
        --banner-width: 1024px;
    }
    
    .banner2-track {
        left: 0;
        animation-name: banner2-mobile-leftcycle;
        transform: translateZ(0);
        will-change: transform;
    }
    
    .banner2-track::after {
        width: 100vw;
        background: no-repeat top / cover;
        animation-name: banner2-mobile-rightcycle;
        animation-timing-function: linear;
        animation-iteration-count: infinite;
        animation-duration: inherit;
        transform: translateZ(0);
        will-change: transform;
    }
}

@keyframes banner2-desktop-cycle {
    0% { left: 0; }
    100% { left: calc(-1 * var(--banner-width)); }
}

@keyframes banner2-mobile-leftcycle {
    0% { transform: translateX(0); }
    100% { transform: translateX(calc(-1 * var(--banner-width))); }
}

@keyframes banner2-mobile-rightcycle {
    0% { transform: translateX(0); }
    100% { transform: translateX(calc(var(--banner-width))); }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>从Autopilot到纯人工：一文读懂AI编程的8种协作模式，掌控你的代码主权</title><link>https://blog.emumu.xyz/posts/2026-01-26-01/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-01-26-01/</guid><description>带你透视每种模式的代码生产、人类理解、可控性与优化程度。无论你是AI重度依赖者还是手写匠人，都能在这里找到自己的坐标，重新思考人与AI的最佳协作边界。</description><pubDate>Mon, 26 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在项目开发与日常学习中，AI的参与方式千差万别，从全自动执行到纯人工编写，其间存在着丰富的协作形态。本文尝试将AI的使用划分为不同层级——从A（自动）到0（无AI）——并非为了排列优劣高下，而是旨在提供一套清晰的认知框架，帮助我们理解自身与AI的协作究竟处于何种模式，从而在效率、控制与学习之间找到恰当的平衡。无论你是希望一键生成结果，还是追求每一行代码的掌控感，或许都能在此找到对应的坐标，进而更清醒、更有效地使用AI。&lt;/p&gt;
&lt;h2&gt;索引&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;模式&lt;/th&gt;
&lt;th&gt;代码生产&lt;/th&gt;
&lt;th&gt;人类代码理解&lt;/th&gt;
&lt;th&gt;代码行为预期&lt;/th&gt;
&lt;th&gt;性能优化程度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;#level-aautopilot%E8%87%AA%E5%8A%A8&quot;&gt;A/自动模式&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;完全自动&lt;/td&gt;
&lt;td&gt;可以不理解&lt;/td&gt;
&lt;td&gt;几乎不可控&lt;/td&gt;
&lt;td&gt;几乎不可控&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;#level-qquestioning%E6%8F%90%E9%97%AE&quot;&gt;Q/提问模式&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;对话方式&lt;/td&gt;
&lt;td&gt;需要初步理解&lt;/td&gt;
&lt;td&gt;难以控制&lt;/td&gt;
&lt;td&gt;难以控制&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;#level-pproductmanager%E4%BA%A7%E5%93%81&quot;&gt;P/产品模式&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;对话方式&lt;/td&gt;
&lt;td&gt;可以不理解&lt;/td&gt;
&lt;td&gt;视PRD详细程度&lt;/td&gt;
&lt;td&gt;视PRD详细程度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;#level-ttester%E6%B5%8B%E8%AF%95&quot;&gt;T/测试模式&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;对话方式&lt;/td&gt;
&lt;td&gt;可以不理解&lt;/td&gt;
&lt;td&gt;视测试细节&lt;/td&gt;
&lt;td&gt;难以控制&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;#level-rreview%E5%AE%A1%E6%A0%B8&quot;&gt;R/审核模式&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;AI生成人类审查&lt;/td&gt;
&lt;td&gt;需要基础理解&lt;/td&gt;
&lt;td&gt;视测试细节&lt;/td&gt;
&lt;td&gt;基本控制&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;#level-ddirector%E4%B8%BB%E7%AC%94&quot;&gt;D/主笔模式&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;人类AI混合&lt;/td&gt;
&lt;td&gt;需要完整理解&lt;/td&gt;
&lt;td&gt;视测试细节&lt;/td&gt;
&lt;td&gt;完全控制&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;#level-sassistant%E8%BE%85%E5%8A%A9&quot;&gt;S/辅助模式&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;人类生成AI审查&lt;/td&gt;
&lt;td&gt;需要完整理解&lt;/td&gt;
&lt;td&gt;视测试细节&lt;/td&gt;
&lt;td&gt;完全控制&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;#level-0&quot;&gt;0/人工模式&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;人类生产&lt;/td&gt;
&lt;td&gt;需要&lt;strong&gt;完备&lt;/strong&gt;理解&lt;/td&gt;
&lt;td&gt;视测试细节&lt;/td&gt;
&lt;td&gt;完全控制&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Level. A/Autopilot/自动&lt;/h2&gt;
&lt;p&gt;在**&lt;a href=&quot;#level-aautopilot%E8%87%AA%E5%8A%A8&quot;&gt;Autopilot模式&lt;/a&gt;**中，AI只需要一个启动按钮就可以自己去做任何事情，一段时间后它会将结果给你。十分省心省力，一站傻瓜式操作，心想事成不过如此。&lt;/p&gt;
&lt;p&gt;这个过程你无需考虑任何上下文，提示词，也没必要知道内部的思考链等。代理本身就是一个应用，由他人设计，你很难控制内部逻辑。输出质量也参差不齐。典型如 jihe520/MathModelAgent。这是一个预设了各种提示词、放进题目文件就能生成结果论文的超级Agent。&lt;/p&gt;
&lt;p&gt;这个模式更适合作为自动化领域中的简单语义接口，比如AI客服，但绝对不应该是AI生成程序。&lt;/p&gt;
&lt;p&gt;优势是绝对傻瓜式操作，缺点也很明显，写出来的代码用户完全不懂，复杂任务里八成是没法直接用的，想改也得找AI改。完全依赖AI。在数学建模里倒是很合适，因为数模的代码既没人看又消耗时间。&lt;/p&gt;
&lt;p&gt;如果你将审阅或者修改，那就不在这个范畴内了。&lt;/p&gt;
&lt;h2&gt;Level. Q/Questioning/提问&lt;/h2&gt;
&lt;p&gt;在**&lt;a href=&quot;#level-qquestioning%E6%8F%90%E9%97%AE&quot;&gt;Questioning模式&lt;/a&gt;**中，你使用LLM的开山功能：对话。&lt;/p&gt;
&lt;p&gt;对话中，你描述问题，复制AI的代码，然后你会遇到各种棘手的问题。然后去尝试理解、学习、最后可能不完美地解决一些问题。这个过程有时会很折磨，因为它本质和老师手把手教你做题没有区别，虽然没有&lt;a href=&quot;#level-aautopilot%E8%87%AA%E5%8A%A8&quot;&gt;A/自动模式&lt;/a&gt;方便快捷，但这个过程的学习效率非常之高，以至于做完即学完，和大学水课形成鲜明对比。虽然既不能精通也不能给出完美作品，但这是我主推的新手学习方式：先照AI的提示上手敲命令行，敲出东西之后，剩下的很快就会以问题的形式出现在脑子里的。&lt;/p&gt;
&lt;p&gt;这个模式唯一的优势只有学习，筑基和理解抽象的编程思想是合适的。在项目中遇到不懂的情况去问一下AI也属于这个模式。不过即使学习也只有技术的入门阶段可以用，并且学习不系统导致细节需要问题导向。如果不是以学习为目的，使用这个模式就是Ctrl CV工程师。那公司还不如充点钱上Cursor什么的了。&lt;/p&gt;
&lt;p&gt;另一个特例是高度拆分模块化中，你确信已经被实现很多遍但特殊场景必须自己实现的一些效果（比如这个博客主页的打字机），在给足接口、合适的Usage、确信代码量不大的情况下使用AI是合适的。&lt;/p&gt;
&lt;p&gt;并不是指提示词工程。当然提示词工程师这个新概念其实也还没稳定。叠甲过。&lt;/p&gt;
&lt;h2&gt;Level. P/ProductManager/产品&lt;/h2&gt;
&lt;p&gt;与&lt;a href=&quot;#level-qquestioning%E6%8F%90%E9%97%AE&quot;&gt;Q/提问模式&lt;/a&gt;相反，如果你铁了心就想让AI按你的想法来，自己坚决不学不碰代码，那么**&lt;a href=&quot;#level-pproductmanager%E4%BA%A7%E5%93%81&quot;&gt;产品经理模式&lt;/a&gt;&lt;strong&gt;是你应该使用的模式。不要让AI猜你的想法，将所有要求&lt;/strong&gt;和不要求**明确给AI来实现吧。&lt;/p&gt;
&lt;p&gt;产品经理模式中，AI需要你给出完整的需求，环境，选型，故事或其他必要的前提条件。其与提示词级不同的是用户必须十分明确了自己想要的东西将以什么方式呈现，并且能够准确地表达出来。有了这些条件，很多现成的vibe coding IDE Agent已经能帮你完成所有工作。Cursor、Claude Code Skills、Trae SOLO(这个也能上桌吗)(国际版据说还行)都采取这个模式与用户交互。&lt;/p&gt;
&lt;p&gt;经常有人说AI没有架构能力。AI确实是这样的，只在它上下文的小规模内写代码，这不代表一旦涉及到从顶到底几个级别规模同时出现的代码就会蒙圈，就我观察，AI的规划能力和代码能力是脱钩的。规划能力过于理想、过于追求标准化、最佳实践化和工程化，很大程度上难以考虑用户的场景级别，取舍也是只有教科书级别的。&lt;/p&gt;
&lt;p&gt;因此，人类自身作为产品经理，了解所有技术栈&lt;strong&gt;的定位&lt;/strong&gt;并准确地把各种接口（包括外部&lt;strong&gt;和内部&lt;/strong&gt;）描述明白是尤为重要的。至于这个一开始的提示词怎么写，我想十分有经验的人应该不少*（但不是我因为我是坚决不全盘托给AI主义者）*。但至少我知道，一两百个字就想一遍跑出有成效又有特色的东西绝对不可能。&lt;/p&gt;
&lt;p&gt;在这点之上通过类型标注/接口/直接定义等方式规定各个方法、函数之间的互相调用是更好的实践，如果能把文档也写清楚就更好了:spoiler[不兑那我和AI岂不是反了？]&lt;/p&gt;
&lt;h2&gt;Level. T/Tester/测试&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;#level-ttester%E6%B5%8B%E8%AF%95&quot;&gt;T/测试模式&lt;/a&gt;&lt;strong&gt;是在&lt;a href=&quot;#level-pproductmanager%E4%BA%A7%E5%93%81&quot;&gt;P/产品模式&lt;/a&gt;之上的模式。如果在产品描述的前提下将AI闭环控制，即写一些测试并在AI修改代码失败后我们或者IDE自动让AI重试，我们就得到了&lt;/strong&gt;测试驱动模式&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;测试驱动模式中，AI需要一个明确的验收标准——你，或者另一个AI来编写测试代码，在可能HIL的闭环系统中让AI通过黑盒测试，与P模式不同，测试代码在保持逻辑不冲突的情况下更强硬地限制了AI的自由发挥。&lt;/p&gt;
&lt;p&gt;与&lt;a href=&quot;#level-pproductManager%E4%BA%A7%E5%93%81&quot;&gt;P/产品模式&lt;/a&gt;中传统的“我看到哪错了告诉AI”不同。这个模式有限地保证了生成代码的逻辑正确，但更大的意义在于能够让AI更加清楚需求，避免挖坑或者省略功能，或者AI思考os“这个明明应该正确的”的现象。同时更强的限制可能导致被动修改时产生更“能用就行”的代码，优化可能难以保证（比如在数据库查询失败完全修改后把原本有的关联表硬生生改回了n+1，别问我描述的怎么这么详细的）&lt;/p&gt;
&lt;p&gt;值得注意的是，AI在几乎必然的测试失败后可能会尝试修改测试、跳过测试或者用针对代码绕过，失败的测试可能是难以测试的环境，更大的问题在于它自己强化的幻觉导致的错误（一些IDE Agent的思考架构已经很大程度上避免了这点）进而导致的AI主动越狱执念。这也是即使测试完善也不能无人值守的重要原因。&lt;/p&gt;
&lt;h2&gt;Level. R/Review/审核&lt;/h2&gt;
&lt;p&gt;如果你有一定代码能力，希望掌控代码，第一步应该是破除AI黑盒，通读所有生成的代码，第二步就是使用**&lt;a href=&quot;#level-rreview%E5%AE%A1%E6%A0%B8&quot;&gt;R/审核模式&lt;/a&gt;**。&lt;/p&gt;
&lt;p&gt;掌握代码不一定意味着真的要写代码。通读了代码之后，你终于获得了项目的基本代码结构。AI使用性能差、非最佳实践埋雷的时候你能够及时发现，同时进行高效学习。现在你可以要求设计模式和算法的优化了。&lt;/p&gt;
&lt;p&gt;另外在大型项目中，让AI定位一个细微问题往往耗时良久，而AI代码的细微问题又往往多如牛毛，如果你有读懂的能力并在有问题的地方自行过目，快速修改，开发速度会高上不少。当然这需要的能力水平其实很高，否则bug半天找不到还不如直接让AI找。当然自己找的过程也是很好的学习。理解了90%的代码，剩下10%如果看了也能立刻明白并学到它的目的。与&lt;a href=&quot;#level-qquestioning%E6%8F%90%E9%97%AE&quot;&gt;Q/提问模式&lt;/a&gt;相对的，这是一种查漏补缺和进阶提升式的学习。但如果走马观花，就会导致断了网，一些细节总是忘。&lt;/p&gt;
&lt;h2&gt;Level. D/Director/主笔&lt;/h2&gt;
&lt;p&gt;你已经准备好写出最高效、最符合工程的代码了。在前端项目中使用统一的CSS变量、后端使用统一的响应格式、每个级别的组件分成一个文件夹、灵活应用各种非常方便的设计模式、包装所有重复代码、用一些冷门好用的小库小技术栈避免重复造轮子……这些AI在上下文驱动下难以设计的优雅模式现在你可以尽情应用。直到这时，你才能大言不惭地说代码未依赖AI生成。&lt;/p&gt;
&lt;p&gt;**&lt;a href=&quot;#level-ddirector%E4%B8%BB%E7%AC%94&quot;&gt;主笔模式&lt;/a&gt;**顾名思义，是你主笔的模式，代码结构不再由你从AI代码中读得，而是全权由你设计。相比&lt;a href=&quot;#level-rreview%E5%AE%A1%E6%A0%B8&quot;&gt;R/审核模式&lt;/a&gt;，主笔模式最大的特点是你现在可以对代码事实负责了。&lt;/p&gt;
&lt;p&gt;代码此时会发生的最大变化是你不希望产生的功能的冗余代码完全消失，取而代之的是明确的可扩展接口或者明确不设计的接口。功能性能可维护性取舍分明，模块职责边界清晰可描述，注释文档更可读而不是好看，不再像AI生成的模棱两可。&lt;strong&gt;当然这一切是否能实现都基于你自身的代码能力。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;AI在此过程中负责补充一些逻辑、找bug或者以类似&lt;a href=&quot;#level-qquestioning%E6%8F%90%E9%97%AE&quot;&gt;Q/提问模式&lt;/a&gt;的形式负责一些接口定义完善的非核心小模块。但与提问模式不同的是，现在你需要白盒审查测试AI的代码。&lt;/p&gt;
&lt;p&gt;这个模式是我今天最常用的开发模式。我无法忍受AI代替我的上限，即使它的上限很多时候比我高，我也必须得相信我不能被AI替代，AI的发展速度一直是惊人的，开发岗或许也会被AI逼得精英化的。扯远了，我们继续。&lt;/p&gt;
&lt;h2&gt;Level. S/aSsistant/辅助&lt;/h2&gt;
&lt;p&gt;**&lt;a href=&quot;#level-sassistant%E8%BE%85%E5%8A%A9&quot;&gt;S/辅助模式&lt;/a&gt;**在&lt;a href=&quot;#level-ddirector%E4%B8%BB%E7%AC%94&quot;&gt;D/主笔模式&lt;/a&gt;之上不再让AI主动编写任何代码。开发工作的主体完全由人类承担。&lt;/p&gt;
&lt;p&gt;从需求分析到代码编写，整个过程由负责的人编写，这并不妨碍过程中有AI辅助的代码补全，因为经过人类实时审查、思考后accept的代码与实人编写相差已经不大。除了代码补全，AI还可以承担Review，提出aissue(AI Issues):spoiler[别再让我看到这种梗了]并由人类解决，当然解决不当的aissue本身也是人类的权利。此外，AI不再负责生成任何代码。这个过程在无AI代码的前提下最大程度地利用AI提升了代码质量，也帮助程序员规避了个人的思维盲区。&lt;/p&gt;
&lt;p&gt;这个模式已经开始激进地排斥AI，一般来说效率会开始降低，如果不是项目或者场景特殊还是建议适当接受AI代码。&lt;/p&gt;
&lt;h2&gt;Level. 0&lt;/h2&gt;
&lt;p&gt;笑话一则：&lt;/p&gt;
&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;我那天在飞机上看见一个人在用笔记本手打代码，没有网络，没有自动补全，没有AI，我的上帝，我不知道他是怎么写下去的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;这是七年前的修炼之道。每一个字符由你亲手敲下，每一个bug都由你在无尽的&lt;code&gt;print&lt;/code&gt;中艰难擒获，每一个算法都由你在A4纸上反复推演。&lt;/p&gt;
&lt;p&gt;在**&lt;a href=&quot;#level-0&quot;&gt;人工模式&lt;/a&gt;**，你获得的是对技术最深层次、最肌肉记忆的理解。你的能力根基被打磨得无比坚实。在AI时代，这种纯粹并非低效的代名词，它更像一种修行。它适用于学习最关键的基础知识，适用于构建那些要求极限性能或极致安全的核心模块，也适用于在面试等需要纯粹展现个人能力的场合。然而，在Transformer时代，完全拒绝AI如同拒绝使用高级编程语言，它代表了一种可敬的匠人精神，但未必是综合效率最高的路径。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;这套模型的意义不在于追求最高的级别，而在于清晰地认知你当下所处的级别，并理解其他使用ai的模式，使用合适的模式提高工作/学习效率。&lt;/p&gt;
&lt;p&gt;我用一系列字母描述AI在编程或其他项目中的参与程度。我最初想用数字编号，但这些等级并没有越高越好或越低越好之分。黑盒智能体确实催生了一些不错的项目，但项目的优劣很大程度依赖着AI本身的智能程度，这实际上也与价格挂钩。人工代码仍然比想象中的广泛，AI代码距离替代人类设计仍有距离，人和AI的沟通在各种视角下都正在开始成为话题。&lt;/p&gt;
&lt;p&gt;本文是我过去文章“你正以何种程度使用AI？”的重写。当时并没有PD(P)模式及以后三种模式的经验。现在有了，也更深刻了，于是便和与时俱进的ai一起与时俱进地把这篇文章重写了。&lt;/p&gt;
</content:encoded></item><item><title>【数模论文】【卡顿警告】结合LBAS算法对烟幕干扰弹投放策略的建模与优化</title><link>https://blog.emumu.xyz/posts/2026-01-26-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-01-26-00/</guid><description>2025高教社杯A 省一打法 不打算改学术了 丢在这供后辈批评</description><pubDate>Mon, 26 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;:::warning
2025高教社杯A 省一打法 不打算改学术了 丢在这供后辈批评&lt;/p&gt;
&lt;p&gt;请遵循CC BY-NC-SA 4.0协议引用，保留本页链接及原作者信息。
:::&lt;/p&gt;
&lt;h1&gt;结合LBAS算法对烟幕干扰弹投放策略的建模与优化&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;摘要&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;本文针对无人机协同投放烟幕干扰弹对来袭导弹进行遮蔽的策略优化问题，建立了一系列精确的运动学与几何遮蔽模型，并设计了一种高效的智能优化算法进行求解，旨在最大化对导弹的有效遮蔽时间。&lt;/p&gt;
&lt;p&gt;针对问题一的标准场景，通过建立导弹、无人机、烟幕弹及烟幕云团的运动方程，并基于真目标圆柱体特性构建了多检查点视线遮蔽判定模型，计算出给定策略的有效遮蔽时间为 &lt;strong&gt;1.392 秒&lt;/strong&gt;，为后续优化提供了基准。&lt;/p&gt;
&lt;p&gt;面对后续问题中参数空间复杂、传统优化算法（如BFGS、差分进化、粒子群等）易陷入局部最优或收敛失败的挑战，本文创新性地引入并改进了&lt;strong&gt;引领者扰动天牛须搜索算法（LBAS）&lt;/strong&gt;。通过引入种群机制、二次进化策略、自适应参数调整与引领者扰动机制，显著提升了算法的全局探索与局部开发能力。改进后的LBAS算法在问题二的单弹优化中，将遮蔽时间显著提升至 &lt;strong&gt;4.587 秒&lt;/strong&gt;，远超传统算法性能。&lt;/p&gt;
&lt;p&gt;基于此，本文进一步构建了多弹、多机、多目标的协同优化模型。对于问题三（单机三弹），通过两阶段优化策略，实现了三枚烟幕弹的时序协同，总遮蔽时间达到 &lt;strong&gt;6.403 秒&lt;/strong&gt;。对于问题四（三机协同），提出了基于空间分布特性的分解协调优化策略，三架无人机分别屏蔽导弹飞行路径的不同区段，总遮蔽时间达到 &lt;strong&gt;11.679 秒&lt;/strong&gt;，验证了协同策略的有效性。最终，针对问题五（五机三弹三目标）这一最具挑战性的全局优化问题，本文设计了分层的资源分配与两阶段优化框架，成功协调5架无人机（最多投放15枚烟幕弹）对3枚导弹的遮蔽任务，最终实现了对M1、M2、M3导弹分别 &lt;strong&gt;15.449 秒&lt;/strong&gt;、&lt;strong&gt;12.164 秒&lt;/strong&gt; 和 &lt;strong&gt;8.578 秒&lt;/strong&gt; 的有效遮蔽。&lt;/p&gt;
&lt;p&gt;本研究结果表明，改进的LBAS算法在解决此类高维、非线性、多约束的优化问题上具有极强的竞争力与优越性。所提出的分层优化与协同策略为复杂战场环境下的智能干扰决策提供了有效的理论依据和算法支撑。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;关键词&lt;/strong&gt;：烟幕干扰；投放策略优化；引领者扰动天牛须搜索算法（LBAS）；协同决策；遮蔽效能评估；多智能体优化；数学建模&lt;/p&gt;
&lt;p&gt;&amp;lt;div style=&quot;page-break-after: always;&quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;h1&gt;一、问题重述&lt;/h1&gt;
&lt;p&gt;烟幕干扰弹在防空干扰系统中具有重要的战术价值，主要通过化学燃烧或爆炸形成烟幕或气溶胶云团，在目标前方特定空域形成遮蔽，干扰敌方导弹，具有成本低、效能高等优点。随着技术的发展，现已能通过无人机等平台实现烟幕干扰弹的定点精确抛撒，并通过时间引信控制起爆时机。在复杂战场环境中，如何根据实时信息判断无人机的投放时机、位置等参数，确保对目标形成有效遮蔽，是一个需要精密计算和高效决策的问题。为此，需建立数学模型并设计高效算法，以指导烟幕干扰弹的投放策略。&lt;/p&gt;
&lt;p&gt;具体问题如下：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题一&lt;/strong&gt;：无人机 FY1 从初始位置 (17800, 0, 1800) 出发，以 120 m/s 的速度等高度朝假目标飞行。受领任务 1.5 秒后投放一枚烟幕干扰弹，间隔 3.6 秒后起爆，形成半径为 10 米、有效遮蔽时间为 20 秒的云团，并以 3 m/s 的速度匀速下沉。导弹 M1 从 (20000, 0, 2000) 出发，以 300 m/s 的速度朝假目标 (0, 0, 0) 飞行。请计算该烟幕云团对 M1 的有效遮蔽时长。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题二&lt;/strong&gt;：在问题一的基础上，优化无人机 FY1 的飞行方向、飞行速度、烟幕干扰弹的投放点和起爆点，使得对 M1 的遮蔽时间尽可能延长。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题三&lt;/strong&gt;：在问题二的基础上，允许无人机 FY1 投放最多三枚烟幕干扰弹。请设计投放策略，以最大化总遮蔽时间，并将结果保存至指定文件。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题四&lt;/strong&gt;：在问题二的基础上，允许三架无人机 FY1、FY2、FY3 各投放一枚烟幕干扰弹，共同对 M1 进行干扰。请设计协同投放策略，并将结果保存至指定文件。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题五&lt;/strong&gt;：在问题二的基础上，允许五架无人机 FY1 至 FY5 各至多投放三枚烟幕干扰弹，同时对三枚来袭导弹 M1、M2、M3 进行干扰。请设计全局投放策略，并将结果保存至指定文件。&lt;/p&gt;
&lt;h1&gt;二、问题分析&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;问题一&lt;/strong&gt;：
该问题可视为单无人机、单烟幕弹、单导弹的标准情形。需建立各实体的运动学模型：无人机、导弹和烟幕云团的运动均可视为线性。烟幕弹脱离无人机后具有无人机的初始速度，并在重力作用下作平抛运动，其轨迹为抛物线；假设烟幕弹起爆后瞬时形成半径为10米的球状云团，该云团以3m/s匀速下沉，且在起爆后20秒内，在其中心10米范围内可提供有效遮蔽；导弹M1沿匀速直线飞向假目标(0,0,0)，并可能在途中探测到位于(0,200,0)的真目标并变动航向，造成不可挽回的损失。结合充分考虑真目标的非质点性，为计算有效遮蔽时长，通过几何方法判断导弹与真目标连线是否穿过烟幕云团球体。在此基础上，通过在时间段内二分查找遮蔽开始和结束的时刻，即可确定有效遮蔽时长。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题二&lt;/strong&gt;：
该问题为优化问题，需确定无人机的航向角、飞行速度、烟幕弹的投放时间与起爆时间，以最大化遮蔽时长。可以构建以遮蔽时间为目标函数的优化模型，并在连续参数空间中寻找最优解。由于目标函数非线性且可能存在多个极值，可采用全局优化算法（如遗传算法、模拟退火等）进行求解，避免陷入局部最优。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题三&lt;/strong&gt;：
在问题二的基础上，允许无人机FY1连续投放三枚烟幕弹。每枚弹的投放时间间隔至少1秒，且各弹的起爆时间独立可控。该问题需同时优化8个参数（无人机航向、速度，以及三枚弹各自的投放时间和起爆时间），目标函数为三枚弹形成的总遮蔽时间（遮蔽可不连续）。由于参数空间增大，且目标函数在绝大部分区域为零（即无遮蔽），可采用基于群体的优化算法（如粒子群优化）或增加扰动策略，以高效探索可行解区域。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题四&lt;/strong&gt;：
在问题二的基础上，该问题扩展至三架无人机（FY1、FY2、FY3）协同干扰同一导弹M1，每架无人机各投放一枚烟幕弹。每架无人机有四个决策变量（航向、速度、投放时间、起爆时间），总参数维度为12维。若直接优化，搜索空间较大。观察三架无人机位置处于低处，可采用分阶段优化策略：先对每架无人机单独优化，获取较优初始解；如果这些解的遮蔽时间是相交的，可以再以这些解为起点，在12维空间中进行协同优化，以提升求解效率和遮蔽效果。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题五&lt;/strong&gt;：
在问题二的基础上，该问题扩展至五架无人机（每架至多投三枚弹）同时干扰三枚导弹（M1、M2、M3）。每架无人机的决策变量包括航向、速度以及每枚弹的投放时间和起爆时间，最多有5×(2+3×2)=40个决策变量。若直接优化，计算代价极高。结合问题四分析，可以采用分阶段优化策略：首先对每架无人机单独优化，确定每架无人机的基本烟幕弹投放策略（即初始解区域）；再在热点解区域内进行退火；最后使用较简单的算法进行全局微调。&lt;/p&gt;
&lt;h1&gt;三、模型假设与符号说明&lt;/h1&gt;
&lt;h2&gt;模型假设&lt;/h2&gt;
&lt;p&gt;为确保模型的合理性与可求解性，本文在严格遵循题目要求的基础上，提出以下假设。&lt;/p&gt;
&lt;h3&gt;题目要求假设&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;导弹运动假设：来袭空地导弹的飞行速度恒为 300 m/s，且其飞行方向始终指向假目标原点 (0, 0, 0)。&lt;/li&gt;
&lt;li&gt;目标特性假设：需要掩护的真目标是一个位于 (0, 200, 0) 的刚性圆柱体，底面半径为 7 米，高度为 10 米。&lt;/li&gt;
&lt;li&gt;无人机运动假设：无人机在受领任务后可瞬时调整飞行方向，随后在恒定高度上以 70~140 m/s 范围内的某一匀速直线飞行，航向与速度一旦确定便不再改变。&lt;/li&gt;
&lt;li&gt;烟幕弹投放假设：每架无人机投放多枚烟幕干扰弹时，相邻两弹的投放时间间隔至少为 1 秒。&lt;/li&gt;
&lt;li&gt;烟幕云特性假设：
&lt;ul&gt;
&lt;li&gt;烟幕云团在起爆后瞬时形成，且为理想球体。&lt;/li&gt;
&lt;li&gt;云团的有效遮蔽半径为 10 米。&lt;/li&gt;
&lt;li&gt;云团以 3 m/s 的速度匀速下沉。&lt;/li&gt;
&lt;li&gt;云团起爆后的 20 秒内为其有效遮蔽时间。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;初始位置假设：所有实体（导弹 M1-M3、无人机 FY1-FY5）的初始位置为题目给定值，在 $t=0$​ 时刻已知且确定。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;以上假设直接源自题目描述，是模型构建的基础约束条件。&lt;/p&gt;
&lt;h3&gt;额外合理假设&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;质点假设：在运动学建模中，将所有实体（导弹、无人机、烟幕弹、烟幕云）视为质点，忽略其形状、尺寸及姿态变化对运动轨迹的影响。&lt;/li&gt;
&lt;li&gt;理想抛体假设：烟幕干扰弹脱离无人机后，仅受重力作用，忽略空气阻力等复杂环境因素的影响，其运动轨迹为理想的平抛运动。&lt;/li&gt;
&lt;li&gt;均匀云团假设：在有效遮蔽半径内，烟幕云的浓度均匀分布，一旦导弹或其视线进入该范围，即认为遮蔽完全有效，否则无效。&lt;/li&gt;
&lt;li&gt;视线遮蔽判断假设：为高效计算导弹是否被遮蔽，采用&lt;strong&gt;有限检查点法&lt;/strong&gt;替代对连续目标体的精确判断。即在真目标圆柱体的顶面和底面圆周上均匀选取 8 个关键点构成检查点集合 $\mathcal{C}$。若烟幕云同时遮蔽了导弹与所有检查点之间的视线，则判定真目标被有效遮蔽。该假设能在保证计算精度的前提下显著提升效率。&lt;/li&gt;
&lt;li&gt;引力常数假设：重力加速度总是取 $g = 9.8 \text{m/s}^2$，方向垂直向下。&lt;/li&gt;
&lt;li&gt;坐标系假设：所有位置、速度、轨迹的计算均在题目给定的三维直角坐标系中进行，其中 $xOy$ 平面为水平面，$z$ 轴正方向为垂直向上。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;符号说明&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;符号&lt;/th&gt;
&lt;th&gt;解释&lt;/th&gt;
&lt;th&gt;单位/备注&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;$\mathbf{M}_{o,i}$&lt;/td&gt;
&lt;td&gt;导弹 $i$ 的初始位置&lt;/td&gt;
&lt;td&gt;m&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\mathbf{M}_i(t)$&lt;/td&gt;
&lt;td&gt;导弹 $i$ 在 $t$ 时刻的位置&lt;/td&gt;
&lt;td&gt;m&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$v_m$&lt;/td&gt;
&lt;td&gt;导弹飞行速度&lt;/td&gt;
&lt;td&gt;m/s, $v_m = 300\text{m/s}$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\mathbf{F}_{o,i}$&lt;/td&gt;
&lt;td&gt;无人机 $i$ 的初始位置&lt;/td&gt;
&lt;td&gt;m&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\mathbf{F}_i(t)$&lt;/td&gt;
&lt;td&gt;无人机 $i$ 在 $t$ 时刻的位置&lt;/td&gt;
&lt;td&gt;m&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$v_i$&lt;/td&gt;
&lt;td&gt;无人机 $i$ 的飞行速度&lt;/td&gt;
&lt;td&gt;m/s, $v \in [70, 140]$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\theta_i$&lt;/td&gt;
&lt;td&gt;无人机 $i$ 的飞行方位角（与x轴正方向夹角）&lt;/td&gt;
&lt;td&gt;rad&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\mathbf{G}_{ij}(t)$&lt;/td&gt;
&lt;td&gt;无人机 $i$ 投放的第 $j$ 枚干扰弹在 $t$ 时刻的位置&lt;/td&gt;
&lt;td&gt;m&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$T_{L,ij}$&lt;/td&gt;
&lt;td&gt;无人机 $i$ 投放第 $j$ 枚干扰弹的时刻&lt;/td&gt;
&lt;td&gt;s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$t_{F,ij}$&lt;/td&gt;
&lt;td&gt;无人机 $i$ 投放的第 $j$ 枚干扰弹的引信时长&lt;/td&gt;
&lt;td&gt;s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$T_{B,ij}$&lt;/td&gt;
&lt;td&gt;无人机 $i$ 投放的第 $j$ 枚干扰弹的起爆时刻&lt;/td&gt;
&lt;td&gt;s, $T_{B,ij} = T_{L,ij} + t_{F,ij}$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\mathbf{S}_{ij}(t)$&lt;/td&gt;
&lt;td&gt;无人机 $i$ 投放的第 $j$ 枚干扰弹形成的烟幕云团在 $t$ 时刻的位置&lt;/td&gt;
&lt;td&gt;m&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\mathbf{v}_s$&lt;/td&gt;
&lt;td&gt;烟幕云团下沉速度向量&lt;/td&gt;
&lt;td&gt;m/s, $\mathbf{v}_s = [0, 0, -3]^T$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$T_s$&lt;/td&gt;
&lt;td&gt;烟幕有效遮蔽时间&lt;/td&gt;
&lt;td&gt;s, $T_s = 20\text{s}$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$R_s$&lt;/td&gt;
&lt;td&gt;烟幕云团有效遮蔽半径&lt;/td&gt;
&lt;td&gt;m, $R_s = 10\text{m}$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\mathcal{C}$&lt;/td&gt;
&lt;td&gt;目标检查点集合&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\mathbf{C}_k$&lt;/td&gt;
&lt;td&gt;目标检查点集合 $\mathcal{C}$ 中的第 $k$ 个点&lt;/td&gt;
&lt;td&gt;m&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$g$&lt;/td&gt;
&lt;td&gt;重力加速度&lt;/td&gt;
&lt;td&gt;m/s², $g \approx 9.8\text{m/s}^2$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\text{is_shielding}(t)$&lt;/td&gt;
&lt;td&gt;$t$ 时刻导弹是否被遮蔽的布尔函数&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$D$&lt;/td&gt;
&lt;td&gt;总有效遮蔽时间（优化目标）&lt;/td&gt;
&lt;td&gt;s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\Delta t_{\text{min}}$&lt;/td&gt;
&lt;td&gt;两枚干扰弹投放最小时间间隔&lt;/td&gt;
&lt;td&gt;s, $\Delta t_{\text{min}} = 1\text{s}$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\mathbf{b}$&lt;/td&gt;
&lt;td&gt;(LBAS中) 天牛须搜索方向向量&lt;/td&gt;
&lt;td&gt;归一化向量&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$d_0$&lt;/td&gt;
&lt;td&gt;(LBAS中) 天牛两须初始距离&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\delta$&lt;/td&gt;
&lt;td&gt;(LBAS中) 天牛搜索步长&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\eta$, $\eta_d$, $\eta_\delta$&lt;/td&gt;
&lt;td&gt;(LBAS中) 距离/步长衰减系数&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$P$&lt;/td&gt;
&lt;td&gt;(LBAS中) 二次进化概率&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$N$&lt;/td&gt;
&lt;td&gt;(LBAS中) 种群大小&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$T_{\text{max}}$&lt;/td&gt;
&lt;td&gt;(LBAS中) 最大迭代次数&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$t$ (算法中)&lt;/td&gt;
&lt;td&gt;(LBAS中) 当前迭代次数&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\boldsymbol{\xi}$&lt;/td&gt;
&lt;td&gt;(LBAS中) 随机扰动向量&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;四、问题一的模型建立与求解&lt;/h1&gt;
&lt;h2&gt;模型构建&lt;/h2&gt;
&lt;h3&gt;构建几何模型&lt;/h3&gt;
&lt;p&gt;构建与题目相同，以假目标为原点的三维直角坐标系，后续模型及分析均基于此坐标系。&lt;/p&gt;
&lt;h3&gt;导弹实体的运动模型&lt;/h3&gt;
&lt;p&gt;将导弹视为质点，其初始位置为 $\mathbf{M}_0 = (20000, 0, 2000)$，以恒定速度 $v_m = 300\text{m/s}$ 沿直线飞向假目标原点。在任意时刻 $t$，导弹的位置可表示为：
$$
\mathbf{M}(t) = \mathbf{M}_0 + \frac{-\mathbf{M}_0}{|\mathbf{M}_0|} \cdot v_m \cdot t \quad (0 \leq t \leq \frac{|\mathbf{M}_0|}{v_m})
$$
当 $t &amp;gt; \frac{|\mathbf{M}_0|}{v_m}$ 时，导弹已到达假目标位置。&lt;/p&gt;
&lt;h3&gt;无人机实体的运动模型&lt;/h3&gt;
&lt;p&gt;无人机FY1初始位置为 $\mathbf{F}_{o1} = (17800, 0, 1800)$，以速度 $v_1 = 120\text{m/s}$ 沿方位角 $\theta_1$ 方向作匀速直线飞行。方位角 $\theta_1$ 定义为从x轴正方向起在xy平面逆时针旋转的弧度。无人机在时刻 $t$ 的位置为：
$$
\mathbf{F}(t) = \mathbf{F}_0 + v \cdot t \cdot
\begin{bmatrix}
\cos\theta \
\sin\theta \
0
\end{bmatrix}
\quad (t \geq 0)
$$
根据问题一条件，无人机朝向假目标方向飞行，因此：&lt;/p&gt;
&lt;p&gt;$$
\theta = \arctan\left(\frac{0 - 0}{0 - 17800}\right) = \pi \text{ rad} = 180^\circ
$$&lt;/p&gt;
&lt;h3&gt;烟幕弹实体的运动模型&lt;/h3&gt;
&lt;p&gt;烟幕弹在 $t = 1.5\text{s}$ 时从无人机投放，引信时长为 $3.6\text{s}$。烟幕弹脱离无人机后，在重力作用下作平抛运动，其运动轨迹为抛物线。在时刻 $t$ ($t \geq T_L = 1.5\text{s}$) 的位置为：
$$
\mathbf{G}(t) = \mathbf{F}(T_L) + \mathbf{v}_u \cdot (t - T_L) - \frac{1}{2}g(t - T_L)^2
\begin{bmatrix}
0 \
0 \
1
\end{bmatrix}
\quad (T_L \leq t \leq T_B)
$$
其中 $\mathbf{v}_u = v \cdot [\cos\theta, \sin\theta, 0]^T$ 为无人机速度向量，$T_B = T_L + t_F = 1.5 + 3.6 = 5.1\text{s}$ 为烟幕弹起爆时刻。&lt;/p&gt;
&lt;h3&gt;烟幕云的运动模型&lt;/h3&gt;
&lt;p&gt;烟幕弹在 $t = T_B = 5.1\text{s}$ 时起爆，瞬时形成半径为 $R_s = 10\text{m}$ 的球状烟幕云团。烟幕云团以 $v_s = 3\text{m/s}$ 的速度匀速下沉，在 $t$ 时刻 ($T_B \leq t \leq T_B + T_s$) 的位置为：&lt;/p&gt;
&lt;p&gt;$$
\mathbf{S}(t) = \mathbf{G}(T_B) + \mathbf{v}_s \cdot (t - T_B)
$$&lt;/p&gt;
&lt;p&gt;其中 $T_s = 20\text{s}$ 为烟幕有效遮蔽时间，$\mathbf{v}_s = [0, 0, -3]^T$。&lt;/p&gt;
&lt;h3&gt;遮蔽判断模型&lt;/h3&gt;
&lt;p&gt;为精确判断导弹是否被烟幕云有效遮蔽，需要考虑导弹与真目标之间连线的遮挡情况。真目标被建模为底面中心在 $(0,200,0)$、半径7m、高10m的直立圆柱体。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;img/5.1.0cps.png&quot; alt=&quot;真目标几何模型与检查点分布&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;center&amp;gt;图4.1  真目标几何模型与检查点分布&amp;lt;/center&amp;gt;&lt;/p&gt;
&lt;p&gt;定义目标检查点集合 $\mathcal{C}$，包含圆柱体顶面和底面圆周上的8个关键点：
$$
\mathcal{C} =
\left{
\begin{aligned}
&amp;amp;(7,200,0), (0,207,0), (-7,200,0), (0,193,0), \
&amp;amp;(7,200,10), (0,207,10), (-7,200,10), (0,193,10)
\end{aligned}
\right}
$$&lt;/p&gt;
&lt;p&gt;导弹在时刻 $t$ 被烟幕云遮蔽的条件为：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;导弹位于烟幕云内部：$|\mathbf{M}(t) - \mathbf{S}(t)| \leq R_s$&lt;/li&gt;
&lt;li&gt;对于所有检查点 $\mathbf{C} \in \mathcal{C}$，烟幕云比导弹更靠近检查点&lt;/li&gt;
&lt;li&gt;对于所有检查点 $\mathbf{C} \in \mathcal{C}$，导弹与检查点连线到烟幕云中心的距离不大于烟幕云半径&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;数学表达为：&lt;/p&gt;
&lt;p&gt;$$
\text{is_shielding}(t) =
\begin{cases}
\text{true} &amp;amp; |\mathbf{M}(t) - \mathbf{S}(t)| \leq R_s \
\text{false} &amp;amp; \exists \mathbf{C} \in \mathcal{C}, |\mathbf{M}(t) - \mathbf{C}| &amp;lt; |\mathbf{S}(t) - \mathbf{C}| \
\text{false} &amp;amp; \exists \mathbf{C} \in \mathcal{C}, \dfrac{|(\mathbf{S}(t) - \mathbf{C}) \times (\mathbf{M}(t) - \mathbf{C})|}{|\mathbf{M}(t) - \mathbf{C}|} &amp;gt; R_s \
\text{true} &amp;amp; \text{otherwise}
\end{cases}
$$&lt;/p&gt;
&lt;h3&gt;有效遮蔽时间计算&lt;/h3&gt;
&lt;p&gt;有效遮蔽时间为烟幕云存在期间 ($T_B \leq t \leq T_B + T_s$) 满足 $\text{is_shielding}(t) = \text{true}$ 的时间区间总长度。由于遮蔽函数可能存在多个不连续区间，采用二分法精确查找遮蔽开始和结束时刻，然后求和：&lt;/p&gt;
&lt;p&gt;$$
T_{\text{shielding}} = \sum_{i} (t_{\text{end},i} - t_{\text{start},i})
$$&lt;/p&gt;
&lt;p&gt;其中 $[t_{\text{start},i}, t_{\text{end},i}]$ 为第 $i$ 个遮蔽时间区间。本研究中暂未发现涉及多个区间的情况。故上式可简化为$T_{\text{shielding}} = t_{\text{end}} - t_{\text{start}}$&lt;/p&gt;
&lt;h2&gt;模型求解&lt;/h2&gt;
&lt;p&gt;基于上述模型，编写Python程序计算有效遮蔽时间：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;定义导弹、无人机、烟幕弹和烟幕云的位置函数&lt;/li&gt;
&lt;li&gt;实现遮蔽判断函数 $\text{is_shielding}(t)$&lt;/li&gt;
&lt;li&gt;在烟幕云存在时间区间 $[T_B, T_B + T_s]$ 内使用二分法查找遮蔽区间&lt;/li&gt;
&lt;li&gt;计算遮蔽区间总长度&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;img/5.1.1shielding.png&quot; alt=&quot;导弹轨迹与烟幕云遮蔽示意图&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;center&amp;gt;图4.2  导弹轨迹与烟幕云遮蔽示意图&amp;lt;/center&amp;gt;&lt;/p&gt;
&lt;h3&gt;计算结果&lt;/h3&gt;
&lt;p&gt;给定参数：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;无人机飞行方向：$180.0^\circ$&lt;/li&gt;
&lt;li&gt;无人机飞行速度：$120\text{m/s}$&lt;/li&gt;
&lt;li&gt;烟幕弹投放时间：$1.5\text{s}$&lt;/li&gt;
&lt;li&gt;烟幕弹引信时间：$3.6\text{s}$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;计算得到有效遮蔽时间为：&lt;/p&gt;
&lt;p&gt;$$
\boxed{T_{\text{shielding}} = 1.391983\text{s}}
$$&lt;/p&gt;
&lt;h3&gt;结果分析&lt;/h3&gt;
&lt;p&gt;烟幕云对导弹的有效遮蔽时间约为1.39秒，这一结果反映了在给定参数下烟幕干扰的效果。&lt;/p&gt;
&lt;h1&gt;五、问题二的模型建立与求解&lt;/h1&gt;
&lt;h2&gt;优化模型建立&lt;/h2&gt;
&lt;p&gt;问题二要求在问题一模型基础上，通过调整无人机飞行参数和烟幕弹投放策略，最大化对导弹M1的有效遮蔽时间。这是一个四维连续优化问题，决策变量包括：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;无人机飞行方向 $\theta$（方位角，弧度）&lt;/li&gt;
&lt;li&gt;无人机飞行速度 $v$（m/s）&lt;/li&gt;
&lt;li&gt;烟幕弹投放时间 $T_L$（s）&lt;/li&gt;
&lt;li&gt;烟幕弹引信时间 $t_F$（s）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;构建优化模型为：
$$
\begin{aligned}
\min_{\theta, v, T_L, t_F} \quad &amp;amp; -T_{\text{shielding}}(\theta, v, T_L, t_F) \
\text{s.t.} \quad &amp;amp; \theta \in [0, 2\pi] \
&amp;amp; v \in [70, 140] \
&amp;amp; T_L \geq 0 \
&amp;amp; t_F \geq 0
\end{aligned}
$$&lt;/p&gt;
&lt;h3&gt;算法比较与分析&lt;/h3&gt;
&lt;p&gt;针对此优化问题，我们尝试了多种优化算法，结果对比如下：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;算法名称&lt;/th&gt;
&lt;th&gt;参数设置&lt;/th&gt;
&lt;th&gt;最优遮蔽时间(s)&lt;/th&gt;
&lt;th&gt;收敛性&lt;/th&gt;
&lt;th&gt;计算效率&lt;/th&gt;
&lt;th&gt;备注&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;BFGS&lt;/td&gt;
&lt;td&gt;默认参数&lt;/td&gt;
&lt;td&gt;收敛失败&lt;/td&gt;
&lt;td&gt;差&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;梯度方法，易陷入局部最优&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;差分进化(DiffEvol)&lt;/td&gt;
&lt;td&gt;NP=50, F=0.5, CR=0.9&lt;/td&gt;
&lt;td&gt;收敛失败&lt;/td&gt;
&lt;td&gt;差&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;td&gt;全局搜索能力不足&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;盆地跳跃(Basinhopping)&lt;/td&gt;
&lt;td&gt;niter=100, T=1.0&lt;/td&gt;
&lt;td&gt;收敛失败&lt;/td&gt;
&lt;td&gt;差&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;td&gt;难以跳出平坦区域&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;粒子群优化(PSO)&lt;/td&gt;
&lt;td&gt;c1=3, c2=1, w=0.99&lt;/td&gt;
&lt;td&gt;2.556160&lt;/td&gt;
&lt;td&gt;一般&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;td&gt;找到局部最优解&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;遗传算法(GA)&lt;/td&gt;
&lt;td&gt;pop_size=200, cxpb=0.5, mutpb=0.2, ngen=100&lt;/td&gt;
&lt;td&gt;1.703871&lt;/td&gt;
&lt;td&gt;一般&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;td&gt;找到较差局部最优&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;传统优化算法在此问题上表现不佳的主要原因包括：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;目标函数存在大量平坦区域（烟雾弹完全无法遮蔽），梯度信息几乎为零&lt;/li&gt;
&lt;li&gt;有效解区域狭窄，传统全局搜索算法难以定位&lt;/li&gt;
&lt;li&gt;参数之间存在复杂耦合关系，局部搜索易陷入次优解&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;引入改进的LBAS算法&lt;/h2&gt;
&lt;h3&gt;BAS（天牛须搜索算法）&lt;/h3&gt;
&lt;p&gt;天牛须搜索算法（Beetle Antennae Search，BAS）是一种受到天牛觅食行为启发的智能优化算法，由Jiang等人在2017年提出^[1]^。该算法模拟了天牛利用触须感知食物气味强度并定向移动的觅食机制。当天牛觅食时，它并不知道食物的具体位置，而是通过比较两只触须感知的气味强度来判断移动方向。若左侧触须感知的气味强度大于右侧，天牛就会向左侧飞行；反之则向右侧飞行。通过这种简单的机制，天牛能够高效地找到食物源。这种仿生学原理为求解复杂优化问题提供了新思路：将待优化函数视为&quot;气味场&quot;，通过模拟天牛的定向移动行为来寻找函数的最优解。^[3]^&lt;/p&gt;
&lt;h3&gt;BAS的基本数学模型&lt;/h3&gt;
&lt;p&gt;将天牛的觅食行为数学化，对于一个n维优化问题，BAS算法的核心步骤如下：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;. 随机生成一个表示天牛朝向的归一化方向向量
$$
\mathbf{b} = \frac{\text{rands}(n, 1)}{|\text{rands}(n, 1)|}
$$
其中$\text{rands}(n, 1)$表示随机生成的n维向量。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;. 计算天牛左右触须的位置
$$
\mathbf{x}_l = \mathbf{x} + d_0 \cdot \frac{\mathbf{b}}{2}, \quad \mathbf{x}_r = \mathbf{x} - d_0 \cdot \frac{\mathbf{b}}{2}
$$
其中$\mathbf{x}$表示天牛当前位置，$d_0$表示两须之间的距离。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;. 根据左右须感知的函数值决定移动方向
$$
\mathbf{x}_{\text{new}} = \mathbf{x} - \delta \cdot \mathbf{b} \cdot \text{sgn}(f(\mathbf{x}_l) - f(\mathbf{x}_r))
$$
其中$\delta$为步长，$\text{sgn}$为取符号函数。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 4&lt;/strong&gt;. 算法采用指数衰减策略更新步长和两须距离以收敛
$$
\delta_{t+1} = \eta \cdot \delta_t, \quad d_{0}^{t+1} = \eta \cdot d_{0}^{t}
$$
其中$\eta$为衰减系数（通常取0.95左右）。&lt;/p&gt;
&lt;p&gt;天牛须算法采用单一个体进行寻优操作。由于单个个体所承载的信息存在局限性，导致其在寻优过程中对位置优劣的判断能力不足，进而常常易于陷入局部最优解。同时，该算法在寻优方向的调整策略上表现得较为单一，这也使得其寻优精度相对较低。^[2]^&lt;/p&gt;
&lt;h3&gt;LBAS（引领者扰动天牛须搜索算法）原理与实现&lt;/h3&gt;
&lt;p&gt;针对基本BAS算法的不足，李辉和殷文明在2025年提出了引领者扰动天牛须算法（Leader Disturbance Beetle Antennae Search Algorithm，LBAS）^[2]^，引入了种群概念、引领者扰动机制、二次进化策略和自适应参数调整等改进措施，显著提升了算法性能。&lt;/p&gt;
&lt;h4&gt;种群机制与排序策略&lt;/h4&gt;
&lt;p&gt;LBAS将单一天牛扩展为&lt;strong&gt;种群&lt;/strong&gt;，模拟多天牛协同觅食的行为。算法将所有天牛按适应度进行排序，令适应度最好的天牛作为“引领者”，随后的天牛随之获得一个“更好”（自己的前一位个体位置）引导和“最佳”（全局最优解位置）引导。&lt;/p&gt;
&lt;h4&gt;惯性系数&lt;/h4&gt;
&lt;p&gt;LBAS引入了惯性权重，该权重可使得个体的进化速度加快。
$$
\boldsymbol{x}^{t}=
\begin{cases}
\text{rand}() \times (\boldsymbol{x}^{t - 1} + \delta^t \boldsymbol{b}), &amp;amp; f(\boldsymbol{x}&lt;em&gt;\text{r}) &amp;gt; f(\boldsymbol{x}&lt;/em&gt;\text{l}), \
\text{rand}() \times (\boldsymbol{x}^{t - 1} - \delta^t \boldsymbol{b}), &amp;amp; f(\boldsymbol{x}&lt;em&gt;\text{r}) &amp;lt; f(\boldsymbol{x}&lt;/em&gt;\text{l}),
\end{cases}
$$
惯性权重的引入可以使得个体加快向最优个体靠拢, 从而提高搜索效率.^[2]^&lt;/p&gt;
&lt;h4&gt;二次进化策略&lt;/h4&gt;
&lt;p&gt;LBAS引入了基于概率的&lt;strong&gt;二次进化机制&lt;/strong&gt;，使个体能够向更优个体和全局最优个体学习。对于每个非最优个体，以概率$P$（默认设为0.5）进行二次进化：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;向排序中前一个个体（更优个体）学习&lt;/li&gt;
&lt;li&gt;向全局最优个体学习&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;数学表达为：
$$
\mathbf{x}&lt;em&gt;{\text{secondary}} = \mathbf{x}&lt;/em&gt;{\text{new}} + 0.5 \cdot (\mathbf{x}&lt;em&gt;{\text{prev}} - \mathbf{x}&lt;/em&gt;{\text{new}}) + 0.5 \cdot (\mathbf{x}&lt;em&gt;{\text{best}} - \mathbf{x}&lt;/em&gt;{\text{new}})
$$
其中$\mathbf{x}&lt;em&gt;{\text{new}}$是第一次进化后的位置，$\mathbf{x}&lt;/em&gt;{\text{prev}}$是排序中前一个更优个体的位置，$\mathbf{x}_{\text{best}}$是全局最优解的位置。&lt;/p&gt;
&lt;p&gt;如果不进行二次进化，该天牛将随机重生至最优解周围。&lt;/p&gt;
&lt;h4&gt;引领者扰动机制&lt;/h4&gt;
&lt;p&gt;为避免算法过早陷入局部最优，LBAS引入了&lt;strong&gt;引领者扰动机制&lt;/strong&gt;。当迭代次数超过初始阶段$t_0$（通常设为30）后，对全局最优解添加随机扰动：&lt;/p&gt;
&lt;p&gt;$$
\mathbf{x}&lt;em&gt;{\text{perturbed}} = \mathbf{x}&lt;/em&gt;{\text{best}} + \boldsymbol{\xi} \cdot \exp\left(-4 \cdot \frac{t}{T_{\text{max}}}\right)
$$
其中$\boldsymbol{\xi}$为随机扰动向量，$t$为当前迭代次数，$T_{\text{max}}$为最大迭代次数。指数衰减项$\exp(-4t/T_{\text{max}})$确保扰动幅度随着迭代进行逐渐减小，符合算法后期需要精细开发的特点。扰动后采用&lt;strong&gt;贪婪选择策略&lt;/strong&gt;决定是否接受扰动解：
$$
\mathbf{x}&lt;em&gt;{\text{best}} = \begin{cases}
\mathbf{x}&lt;/em&gt;{\text{perturbed}} &amp;amp; \text{if } f(\mathbf{x}&lt;em&gt;{\text{perturbed}}) &amp;lt; f(\mathbf{x}&lt;/em&gt;{\text{best}}) \
\mathbf{x}_{\text{best}} &amp;amp; \text{otherwise}
\end{cases}
$$&lt;/p&gt;
&lt;p&gt;若扰动解更优，同时用其替换种群中最差个体，保持种群大小不变：
$$
\mathbf{x}&lt;em&gt;{\text{worst}} = \mathbf{x}&lt;/em&gt;{\text{perturbed}}, \quad f(\mathbf{x}&lt;em&gt;{\text{worst}}) = f(\mathbf{x}&lt;/em&gt;{\text{perturbed}})
$$&lt;/p&gt;
&lt;h3&gt;自适应参数调整&lt;/h3&gt;
&lt;p&gt;LBAS继承了BAS算法的参数衰减机制，但通过&lt;strong&gt;种群搜索&lt;/strong&gt;替代了&lt;strong&gt;个体搜索&lt;/strong&gt;，使参数设置更加稳健：&lt;/p&gt;
&lt;p&gt;$$
d_0^{t+1} = \eta_d \cdot d_0^t, \quad \delta^{t+1} = \eta_\delta \cdot \delta^t
$$
其中$\eta_d$和$\eta_\delta$分别为两须距离和步长的衰减系数（通常取值0.9-0.95）。&lt;/p&gt;
&lt;p&gt;初始步长和两须距离初始化为搜索空间规模的1/2，使其能充分探索空间边界：
$$
\delta_0 = d_0 = \frac{1}{2} (\mathbf{b}&lt;em&gt;{\text{max}} - \mathbf{b}&lt;/em&gt;{\text{min}})
$$
其中$\mathbf{b}&lt;em&gt;{\text{max}}$和$\mathbf{b}&lt;/em&gt;{\text{min}}$分别为搜索空间的上界和下界。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart TD
    A[初始化个体，扰动概率P，两项距离d，初始步长δ、衰减系数、最大迭代次数T和初始阶段迭代次数tt] --&amp;gt; B[评估函数，将个体按适应度从小到大排序，记录最优值]
    B --&amp;gt; C[个体按第五式进行位置更新]
    C --&amp;gt; D{IF r &amp;gt; P?}
    D --&amp;gt;|是| E[个体按第六式进行二次进化]
    D --&amp;gt;|否| F[随机生成新个体，择优代替原个体]
    E --&amp;gt; G
    F --&amp;gt; G[若T &amp;gt; tt，根据第七式对最优个体进行位置扰动]
    G --&amp;gt; H{达到停机条件?}
    H --&amp;gt;|否| B
    H --&amp;gt;|是| I[停机，输出最优值]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;center&amp;gt;图5.1 LBAS算法流程示意图&lt;/p&gt;
&lt;h3&gt;本文对LBAS算法的改进&lt;/h3&gt;
&lt;h4&gt;嗅探前随机化 $d_0$ 的改进&lt;/h4&gt;
&lt;p&gt;在方向向量生成后、计算须位置前，引入随机化因子：&lt;/p&gt;
&lt;p&gt;$$
\mathbf{b} = \frac{\text{rands}(n, 1)}{|\text{rands}(n, 1)|} \cdot r
$$&lt;/p&gt;
&lt;p&gt;其中 $r \sim U(0,1)$ 是随机数。这一改进实际上将固定长度的方向向量变为随机长度的方向向量，使得天牛须的&quot;嗅探&quot;行为更加多样化。&lt;/p&gt;
&lt;h4&gt;二次进化距离的随机化改进&lt;/h4&gt;
&lt;p&gt;引入随机因子 $r \sim U(0,1)$，使二次进化的步长具有随机性：&lt;/p&gt;
&lt;p&gt;$$
\mathbf{x}&lt;em&gt;{\text{secondary}} = \mathbf{x}&lt;/em&gt;{\text{new}} + r \cdot \left[0.5 \cdot (\mathbf{x}&lt;em&gt;{\text{prev}} - \mathbf{x}&lt;/em&gt;{\text{new}}) + 0.5 \cdot (\mathbf{x}&lt;em&gt;{\text{best}} - \mathbf{x}&lt;/em&gt;{\text{new}})\right]
$$&lt;/p&gt;
&lt;p&gt;随机因子 $r$ 的引入使得二次进化步骤具有了自适应步长调整的能力，平衡了探索与开发，针对本问题能够特别有效地搜索变量空间。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;img/lbassnapshot.png&quot; alt=&quot;图5.2 改进的LBAS算法的二次进化过程&quot; /&gt;&lt;/p&gt;
&lt;p&gt;图5.2 展示了改进的LBAS算法的二次进化过程，其中灰色虚线为触角、红线为天牛个体主动移动，五角星为最优记录，蓝色点线为更优引导，橙色点划线为最优引导，棕线为最终二次进化路线。&lt;/p&gt;
&lt;h2&gt;模型求解&lt;/h2&gt;
&lt;h3&gt;LBAS算法参数设置&lt;/h3&gt;
&lt;p&gt;针对本问题，LBAS算法的参数设置如下：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;参数&lt;/th&gt;
&lt;th&gt;符号&lt;/th&gt;
&lt;th&gt;值&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;种群大小&lt;/td&gt;
&lt;td&gt;$N$&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;平衡计算量与多样性&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;二次进化概率&lt;/td&gt;
&lt;td&gt;$P$&lt;/td&gt;
&lt;td&gt;0.5&lt;/td&gt;
&lt;td&gt;平衡开发与探索&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;初始步长&lt;/td&gt;
&lt;td&gt;$\delta_0$&lt;/td&gt;
&lt;td&gt;1.0&lt;/td&gt;
&lt;td&gt;基于参数范围标准化&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;初始两须距离&lt;/td&gt;
&lt;td&gt;$d_0$&lt;/td&gt;
&lt;td&gt;1.0&lt;/td&gt;
&lt;td&gt;基于参数范围标准化&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;步长衰减系数&lt;/td&gt;
&lt;td&gt;$\eta_\delta$&lt;/td&gt;
&lt;td&gt;0.95&lt;/td&gt;
&lt;td&gt;控制收敛速度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;距离衰减系数&lt;/td&gt;
&lt;td&gt;$\eta_d$&lt;/td&gt;
&lt;td&gt;0.95&lt;/td&gt;
&lt;td&gt;控制搜索精度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;最大迭代次数&lt;/td&gt;
&lt;td&gt;$T_{\text{max}}$&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;确保充分收敛&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;初始阶段迭代次数&lt;/td&gt;
&lt;td&gt;$t_0$&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;控制扰动开始时&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;优化结果&lt;/h3&gt;
&lt;p&gt;使用改进的LBAS算法求解问题二，得到最优参数组合：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;参数&lt;/th&gt;
&lt;th&gt;最优值&lt;/th&gt;
&lt;th&gt;单位&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;飞行方向&lt;/td&gt;
&lt;td&gt;4.993674°&lt;/td&gt;
&lt;td&gt;°&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;飞行速度&lt;/td&gt;
&lt;td&gt;124.169252&lt;/td&gt;
&lt;td&gt;m/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;投放时间&lt;/td&gt;
&lt;td&gt;0.907518&lt;/td&gt;
&lt;td&gt;s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;引信时间&lt;/td&gt;
&lt;td&gt;0.137133&lt;/td&gt;
&lt;td&gt;s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;最大遮蔽时间&lt;/td&gt;
&lt;td&gt;4.587493&lt;/td&gt;
&lt;td&gt;s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;最优投放点坐标：$(17912.26, 9.81, 1800.00)\text{m}$&lt;br /&gt;
最优起爆点坐标：$(17929.22, 11.29, 1799.91)\text{m}$&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;img/5.2.1covplus.png&quot; alt=&quot;各算法收敛曲线对比&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;center&amp;gt;图5.3 各算法收敛曲线对比&amp;lt;/center&amp;gt;&lt;/p&gt;
&lt;h1&gt;六、问题三的模型建立与求解&lt;/h1&gt;
&lt;h2&gt;优化模型建立&lt;/h2&gt;
&lt;p&gt;问题三要求在单无人机FY1上投放3枚烟幕干扰弹，实施对导弹M1的干扰，目标是最大化总有效遮蔽时间。这是一个8维优化问题，决策变量包括：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;无人机飞行方向 $\theta$（方位角）&lt;/li&gt;
&lt;li&gt;无人机飞行速度 $v$（m/s）&lt;/li&gt;
&lt;li&gt;第一枚烟幕弹投放时间 $T_{L1}$（s）c&lt;/li&gt;
&lt;li&gt;第一枚烟幕弹引信时间 $t_{F1}$（s）&lt;/li&gt;
&lt;li&gt;第二枚烟幕弹相对投放间隔 $\Delta T_{L2}$（s）&lt;/li&gt;
&lt;li&gt;第二枚烟幕弹引信时间 $t_{F2}$（s）&lt;/li&gt;
&lt;li&gt;第三枚烟幕弹相对投放间隔 $\Delta T_{L3}$（s）&lt;/li&gt;
&lt;li&gt;第三枚烟幕弹引信时间 $t_{F3}$（s）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;$$
\max_{\theta, v, T_{L1}, t_{F1}, \Delta T_{L2}, t_{F2}, \Delta T_{L3}, t_{F3}} T_{\text{total}} = \sum_{i=1}^{3} I_{\text{shielding},i}(\theta, v, T_{Li}, t_{Fi})
$$&lt;/p&gt;
&lt;p&gt;其中 $T_{L2} = T_{L1} + 1 + \Delta T_{L2}$，$T_{L3} = T_{L2} + 1 + \Delta T_{L3}$。$I_{\text{shielding}}$为求区间函数。$\sum$为重叠区间求和。&lt;/p&gt;
&lt;p&gt;基于对FY1位置和导弹轨迹的分析，我们提出以下建模策略：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;由于FY1位置相对靠后，导弹会快速越过无人机，因此烟雾弹必须在短时间内迅速投放。将投放时间和引信时间上限设为5秒，大幅缩减搜索空间。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;通过将投放间隔表示为&quot;最小间隔+增量&quot;的形式处理投放间隔约束：
$$
T_{L2} = T_{L1} + 1 + \Delta T_{L2}, \quad T_{L3} = T_{L2} + 1 + \Delta T_{L3}
$$
其中 $\Delta T_{L2}, \Delta T_{L3} \geq 0$，确保满足至少1秒间隔的要求。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;两阶段优化策略&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第一阶段：添加无效烟雾弹惩罚，引导算法找到三个烟雾弹都有效的解区域&lt;/li&gt;
&lt;li&gt;第二阶段：取消惩罚，在可行解附近进行精细优化，找到全局最优解&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;模型求解&lt;/h2&gt;
&lt;p&gt;针对8维高维优化问题，对LBAS算法进行以下改进：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;增大种群规模：从30增加到300，增强全局探索能力&lt;/li&gt;
&lt;li&gt;$d_{\eta} = \delta_{\eta} = 0.97$，减缓参数衰减速度&lt;/li&gt;
&lt;li&gt;$P = 0.6$，增强学习能力&lt;/li&gt;
&lt;li&gt;方位角搜索范围扩大到 $[0, \frac{5\pi}{2}]$，避免最优空间在角度上割裂。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;通过两阶段LBAS优化，得到的最优结果为：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;飞行方向/rad&lt;/th&gt;
&lt;th&gt;飞行速度/(m/s)&lt;/th&gt;
&lt;th&gt;投放时间/s&lt;/th&gt;
&lt;th&gt;引信时间/s&lt;/th&gt;
&lt;th&gt;独立遮蔽时间&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0.087371&lt;/td&gt;
&lt;td&gt;138.259364&lt;/td&gt;
&lt;td&gt;0.00&lt;/td&gt;
&lt;td&gt;0.00&lt;/td&gt;
&lt;td&gt;2.556160&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.087371&lt;/td&gt;
&lt;td&gt;138.259364&lt;/td&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;0.00&lt;/td&gt;
&lt;td&gt;4.336823&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.087371&lt;/td&gt;
&lt;td&gt;138.259364&lt;/td&gt;
&lt;td&gt;2.00&lt;/td&gt;
&lt;td&gt;0.00&lt;/td&gt;
&lt;td&gt;0.000000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;总遮蔽时间：6.403160&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;img/timeline3.png&quot; alt=&quot;图6.1 问题三优化结果的各烟雾弹有效遮蔽时序图&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;七、问题四的模型建立与求解&lt;/h1&gt;
&lt;h2&gt;模型分析与猜想&lt;/h2&gt;
&lt;p&gt;问题四要求利用FY1、FY2、FY3三架无人机各投放1枚烟幕干扰弹，实施对导弹M1的协同干扰。通过对三架无人机初始位置的空间分析：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FY1位置：(17800, 0, 1800) m&lt;/li&gt;
&lt;li&gt;FY2位置：(12000, 1400, 1400) m&lt;/li&gt;
&lt;li&gt;FY3位置：(6000, -3000, 700) m&lt;/li&gt;
&lt;li&gt;M1位置：(20000, 0, 2000) m&lt;/li&gt;
&lt;li&gt;假目标位置：(0, 0, 0) m&lt;/li&gt;
&lt;li&gt;真目标位置：(0, 200, 0) m&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;基于三架无人机的初始位置分析，三架无人机分布在导弹飞行路径的不同区段，且彼此间距较大。基于此，可以提出以下猜想：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;猜想7.1&lt;/strong&gt;：由于三架无人机空间分布差异显著，各自的最优遮蔽策略相互独立，协同优化可分解为三个独立的子优化问题。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;img/spacestruct.png&quot; alt=&quot;图7.1 遮蔽不连续假设的空间结构&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;猜想7.2&lt;/strong&gt;：三架无人机的最优投放时间存在先后顺序，与各自空间位置相关，形成时序不连续的遮蔽效果。预测三架无人机的遮蔽时间段不会重合，每架无人机负责导弹飞行路径的不同区段，形成分段遮蔽策略。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;img/relpos.png&quot; alt=&quot;图7.2 三无人机与导弹的相对位置分布&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;增强奖励函数&lt;/h2&gt;
&lt;p&gt;与问题二不同，该问题中F2,F3无人机的投放和引信时间变量空间更大，无法限制范围，解集更加稀疏。标准遮蔽时间函数 $T_{\text{shielding}}$ 在优化过程中存在明显缺陷：当烟雾弹完全未遮蔽导弹时，函数值为零，无法提供梯度信息，导致优化算法在平坦区域陷入停滞。为此可以设计一个增强的奖励函数，对于完全未遮蔽的情况下给予额外惩罚。为此，我们设计增强奖励函数，其数学表达式为：&lt;/p&gt;
&lt;p&gt;$$
R(\theta, v, T_L, t_F) =
\begin{cases}
T_{\text{shielding}}(\theta, v, T_L, t_F) &amp;amp; \text{if } T_{\text{shielding}} &amp;gt; 0 \
-\dfrac{d_{\text{smoke-to-route}}}{|\mathbf{M}(t_m) - \mathbf{C}_0|} \cdot \gamma &amp;amp; \text{otherwise}
\end{cases}
$$&lt;/p&gt;
&lt;p&gt;其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$t_m = T_L + t_F + \dfrac{T_s}{2}$ 为评估中点时刻&lt;/li&gt;
&lt;li&gt;$d_{\text{smoke-to-route}} = \dfrac{|(\mathbf{S}(t_m) - \mathbf{C}_0) \times (\mathbf{M}(t_m) - \mathbf{C}_0)|}{|\mathbf{M}(t_m) - \mathbf{C}_0|}$ 为烟雾云到导弹航线的距离&lt;/li&gt;
&lt;li&gt;$\mathbf{C}_0 = (0, 200, 5)$ 为目标中心点&lt;/li&gt;
&lt;li&gt;$\gamma = \begin{cases} 2 &amp;amp; \text{if } |\mathbf{M}(t_m) - \mathbf{C}_0| &amp;lt; |\mathbf{S}(t_m) - \mathbf{C}_0| \ 1 &amp;amp; \text{otherwise} \end{cases}$ 为导弹不及时惩罚因子&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;增强奖励函数在未遮蔽区域仍能提供有意义的梯度信息，引导算法向有效解方向搜索。同时针对不及时造成的惩罚加倍，引导算法使无人机朝更早方向探索。&lt;/p&gt;
&lt;h2&gt;优化模型建立与求解&lt;/h2&gt;
&lt;p&gt;基于空间独立性猜想，我们将原问题分解为三个子问题：&lt;/p&gt;
&lt;p&gt;$$
\max \sum_{i=1}^{3} R_i(\theta_i, v_i, T_{Li}, t_{Fi})
$$&lt;/p&gt;
&lt;p&gt;其中 $R_i$ 为第 $i$ 架无人机的增强奖励函数。特殊地，在猜想之上，关于无人机FY1的结果可以直接沿用问题二的结果。&lt;/p&gt;
&lt;p&gt;采用增强奖励函数和分解协调策略，得到的最优结果为：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;无人机&lt;/th&gt;
&lt;th&gt;飞行方向/rad&lt;/th&gt;
&lt;th&gt;飞行速度/(m/s)&lt;/th&gt;
&lt;th&gt;投放时间/s&lt;/th&gt;
&lt;th&gt;引信时间/s&lt;/th&gt;
&lt;th&gt;遮蔽时间/s&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;FY1&lt;/td&gt;
&lt;td&gt;0.0872&lt;/td&gt;
&lt;td&gt;124.1693&lt;/td&gt;
&lt;td&gt;0.9075&lt;/td&gt;
&lt;td&gt;0.1371&lt;/td&gt;
&lt;td&gt;4.5875&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FY2&lt;/td&gt;
&lt;td&gt;5.0761&lt;/td&gt;
&lt;td&gt;140.0000&lt;/td&gt;
&lt;td&gt;5.0650&lt;/td&gt;
&lt;td&gt;5.3108&lt;/td&gt;
&lt;td&gt;3.9433&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FY3&lt;/td&gt;
&lt;td&gt;1.2901&lt;/td&gt;
&lt;td&gt;140.0000&lt;/td&gt;
&lt;td&gt;22.9527&lt;/td&gt;
&lt;td&gt;0.0000&lt;/td&gt;
&lt;td&gt;3.1484&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;总遮蔽时间&lt;/strong&gt;：11.6792 s&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;img/timeline4.png&quot; alt=&quot;图7.3 问题四优化结果的各烟雾弹有效遮蔽时序图&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;猜想验证与讨论&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;验证猜想7.1&lt;/strong&gt;：三架无人机的最优参数差异显著，且各自遮蔽时间接近独立优化时的最大值，证实了空间独立性猜想的正确性。无人机间的最优策略确实相互独立，协同效应主要体现在有效遮蔽时间段的分离上。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;验证猜想7.2&lt;/strong&gt;：三架无人机的投放时间呈现明显的时间序列：FY1(0.91s) → FY2(10.50s) → FY3(29.91s)，这与各自空间位置吻合：距离导弹起点最近的FY1最先投放，距离最远的FY3最后投放。&lt;/p&gt;
&lt;h1&gt;八、问题五的模型建立与求解&lt;/h1&gt;
&lt;h2&gt;问题描述与建模思路&lt;/h2&gt;
&lt;h3&gt;问题复杂性分析&lt;/h3&gt;
&lt;p&gt;问题五要求利用5架无人机（FY1-FY5）各投放至多3枚烟幕干扰弹，实施对3枚来袭导弹（M1-M3）的协同干扰。这是一个高度复杂的优化问题。每架无人机有8个决策变量（方位角、速度、3枚烟雾弹的投放时间和引信时间），5架无人机共40个决策变量。需要同时优化对3枚导弹的遮蔽效果，目标间存在竞争关系。且存在烟雾弹投放给不适宜的导弹导致无法达到最优解（如第3或第2、3枚烟雾弹屏蔽到第1或第1、2个导弹的情形）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;img/5f3mbjt.png&quot; alt=&quot;图8.1 五无人机三导弹布局图&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;center&amp;gt;&amp;lt;/center&amp;gt;&lt;/p&gt;
&lt;p&gt;图8.1中，M1~M3为导弹位置，F1~F5为无人机位置，T为真目标位置。红线表示烟雾弹需要遮蔽的导弹探测视线。&lt;/p&gt;
&lt;h3&gt;分层优化策略&lt;/h3&gt;
&lt;p&gt;基于问题复杂性，我们提出分层优化策略：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第一层：单无人机多导弹优化&lt;/strong&gt;（问题五子问题）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;扩展至单无人机对多导弹遮蔽&lt;/li&gt;
&lt;li&gt;采用&quot;一弹一目标&quot;分配策略，避免“烟雾弹错位遮蔽”&lt;/li&gt;
&lt;li&gt;使用问题四优化的奖励函数，惩罚烟雾弹未有效遮蔽的情形，辅助快速收敛到解集密集区。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;第二层：多无人机多导弹优化&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;整合各无人机优化结果&lt;/li&gt;
&lt;li&gt;全局协调微调&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;资源分配策略&lt;/h3&gt;
&lt;p&gt;基于各无人机位置特征，制定如下资源分配方案：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;无人机&lt;/th&gt;
&lt;th&gt;烟雾弹1目标&lt;/th&gt;
&lt;th&gt;烟雾弹2目标&lt;/th&gt;
&lt;th&gt;烟雾弹3目标&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;FY1&lt;/td&gt;
&lt;td&gt;M1&lt;/td&gt;
&lt;td&gt;M1&lt;/td&gt;
&lt;td&gt;M1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FY2&lt;/td&gt;
&lt;td&gt;M2&lt;/td&gt;
&lt;td&gt;M1&lt;/td&gt;
&lt;td&gt;M3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FY3&lt;/td&gt;
&lt;td&gt;M3&lt;/td&gt;
&lt;td&gt;M1&lt;/td&gt;
&lt;td&gt;M2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FY4&lt;/td&gt;
&lt;td&gt;M2&lt;/td&gt;
&lt;td&gt;M1&lt;/td&gt;
&lt;td&gt;M3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FY5&lt;/td&gt;
&lt;td&gt;M3&lt;/td&gt;
&lt;td&gt;M1&lt;/td&gt;
&lt;td&gt;M2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;该分配方案基于以下几何考虑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FY1位置最靠前，难以在M2和M3之前再布置烟雾弹。故可专注于遮蔽路线最近的M1&lt;/li&gt;
&lt;li&gt;FY2、FY4位置偏北，优先遮蔽M2和M1&lt;/li&gt;
&lt;li&gt;FY3、FY5位置偏南，优先遮蔽M3和M1&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;优化模型建立&lt;/h2&gt;
&lt;p&gt;对于每架无人机，定义其目标函数为对分配导弹的总遮蔽奖励：&lt;/p&gt;
&lt;p&gt;全局目标函数为各无人机目标函数的和：
$$
\begin{equation*}
\begin{aligned}
&amp;amp;\min_{\substack{\theta_i, v_i, T_{Lij}, t_{Fij} \ i=1,\dots,5; , j=1,2,3}} \quad J = \sum_{i=1}^{5} R_i \[8pt]
&amp;amp;\text{s.t.} \quad
\begin{cases}
R_i(\theta_i, v_i, \mathbf{T}&lt;em&gt;{Li}, \mathbf{t}&lt;/em&gt;{Fi}) = \sum_{j=1}^{3} R(\theta_i, v_i, T_{Lij}, t_{Fij}, M_{ij}) &amp;amp; \forall i, \[4pt]
\theta_i \in [0, 2\pi], \quad v_i \in [70, 140] &amp;amp; \forall i, \[4pt]
T_{Li1} \geq 0, \quad T_{Lij} \geq T_{Li(j-1)} + 1 &amp;amp; \forall i; , j=2,3, \[4pt]
t_{Fij} \geq 0, \quad t_{Fij} \leq T_{\text{max}} - T_{Lij} &amp;amp; \forall i; , j=1,2,3, \[4pt]
\min_{k} | \mathbf{S}&lt;em&gt;{ij}(t) - \mathbf{S}&lt;/em&gt;{kl}(t) | \geq R_{\text{min}} &amp;amp; \forall i \neq k; , j,l=1,2,3.
\end{cases}
\end{aligned}
\end{equation*}
$$&lt;/p&gt;
&lt;p&gt;其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$M_{ij}$ 为第$i$架无人机第$j$枚烟雾弹分配的导弹目标&lt;/li&gt;
&lt;li&gt;$R$ 为增强的奖励函数。采用问题四中设计的增强奖励函数：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;$$
R(\theta, v, T_L, t_F, M) =
\begin{cases}
T_{\text{shielding}} &amp;amp; \text{if } T_{\text{shielding}} &amp;gt; 0 \
d_{\text{smoke-to-route}} \cdot \gamma &amp;amp; \text{otherwise}
\end{cases}
$$&lt;/p&gt;
&lt;h2&gt;两阶段优化流程&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;第一阶段：增强奖励函数优化&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用增强奖励函数快速找到解集密集区&lt;/li&gt;
&lt;li&gt;获得初始解 $\mathbf{x}^{(0)}$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;第二阶段：标准目标函数优化&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用标准计算重复时间区间的方法进行精细优化&lt;/li&gt;
&lt;li&gt;以 $\mathbf{x}^{(0)}$ 为初始点，寻找全局最优解&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;优化结果与分析&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;导弹&lt;/th&gt;
&lt;th&gt;总遮蔽时间&lt;/th&gt;
&lt;th&gt;FA1独立遮蔽&lt;/th&gt;
&lt;th&gt;FA2独立遮蔽&lt;/th&gt;
&lt;th&gt;FA3独立遮蔽&lt;/th&gt;
&lt;th&gt;FA4独立遮蔽&lt;/th&gt;
&lt;th&gt;FA5独立遮蔽&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;M1&lt;/td&gt;
&lt;td&gt;15.4487&lt;/td&gt;
&lt;td&gt;6.4032&lt;/td&gt;
&lt;td&gt;3.1346&lt;/td&gt;
&lt;td&gt;2.4081&lt;/td&gt;
&lt;td&gt;0.0000&lt;/td&gt;
&lt;td&gt;3.5028&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;M2&lt;/td&gt;
&lt;td&gt;12.1635&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;2.9866&lt;/td&gt;
&lt;td&gt;2.6288&lt;/td&gt;
&lt;td&gt;3.3043&lt;/td&gt;
&lt;td&gt;3.2438&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;M3&lt;/td&gt;
&lt;td&gt;8.5784&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;0.0000&lt;/td&gt;
&lt;td&gt;2.3375&lt;/td&gt;
&lt;td&gt;2.7562&lt;/td&gt;
&lt;td&gt;3.4846&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;img src=&quot;img/timeline.png&quot; alt=&quot;图8.2 问题五优化结果的各烟雾弹有效遮蔽时序图&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;结论与启示&lt;/h2&gt;
&lt;p&gt;通过问题五的建模与求解，我们得到以下结论：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;改进的LBAS算法在解决此类高维、非线性、多约束的几何优化问题上展现出显著优势。&lt;/li&gt;
&lt;li&gt;如图8.2所示，本文提出的两阶段优化流程在实际应用中表现出色。针对生效时机相近的F2、F4、F5在M2导弹上的屏蔽展现了明显的优化偏移痕迹。&lt;/li&gt;
&lt;li&gt;通过三维运动学分析发现，F2和F4无法对第三枚导弹形成有效遮蔽并非算法局限，而是物理约束下的最优选择。以F2为例，如图8.3所示：&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;img/xwgc.png&quot; alt=&quot;图8.3 F2在接近导弹航线时的行为观察&quot; /&gt;&lt;/p&gt;
&lt;p&gt;图8.3中，红色为导弹位置与轨迹，蓝色为无人机位置与轨迹，黑色为烟雾弹位置及轨迹，绿色为导弹的探测视线。此图中，烟雾弹1和2均在导弹越过无人机之前被遮挡，而当烟雾弹3到达其遮挡的导弹之前、遮挡已经结束。F2的速度已达到140m/s的上限，但在此速度下仍然无法有效地在到达M1之前使烟雾弹达到M1视线附近。故抛弃对此导弹屏蔽在全局范围内是具有策略性的&lt;/p&gt;
&lt;h1&gt;九、模型优缺点&lt;/h1&gt;
&lt;h2&gt;模型的优点&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;本研究提出的改进LBAS算法在多个方面展现创新性：&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;种群机制改进&lt;/strong&gt;：引入排序分组和角色划分，将单一天牛搜索扩展为群体协同搜索，全局搜索能力大幅提升。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;二次进化策略&lt;/strong&gt;：通过向更优个体和引领者学习，有效在控制迭代次数总是不高于300次的情况下找到全局最优。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自适应扰动机制&lt;/strong&gt;：有效避免早熟收敛，在多种算法中收敛表现优异。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;模型采用&lt;strong&gt;两阶段分解协调策略&lt;/strong&gt;，将40维问题降维处理，实时性能表现优异。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;模型的缺点&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;模型基于以下简化假设，在实际应用中可能存在偏差：&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;忽略空气阻力&lt;/strong&gt;：烟幕弹运动采用理想抛体模型，实际弹道可能因空气阻力产生偏移，结合研究中常见的滞空时间（约5s），使用优化的烟幕弹弹身设计，预计最大偏差可能达到8-12%&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;图9.1展示了大型烟幕弹(m=10kg,C=0.02,v0=100.0m/s)的平抛运动下是否加入空气阻力的理论影响。其中理论为有空气阻力，理想为无空气阻力。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;img/5.0.0faeff.png&quot; alt=&quot;图9.1 平抛烟幕弹是否计算空气阻力在短时间内的动力学分析&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;图8.3展示了无人机的部分烟幕弹无法到达部分导弹，但未尝试使用这枚烟幕弹屏蔽其他导弹的情形。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;lt;div style=&quot;page-break-after: always;&quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;h1&gt;十一、参考文献&lt;/h1&gt;
&lt;p&gt;[1] Jiang, X., &amp;amp; Li, S. (2018). BAS: beetle antennae search algorithm for optimization problems. International Journal of Robotics and Control.&lt;/p&gt;
&lt;p&gt;[2] 李辉,殷文明.引领者扰动天牛须算法及其应用J.数学建模及其应用,2025,14(02):20-27.&lt;/p&gt;
&lt;p&gt;[3] 廖列法,杨红. 天牛须搜索算法研究综述 [J]. 计算机工程与应用, 2021, 57 (12): 54-64.&lt;/p&gt;
&lt;p&gt;&amp;lt;div style=&quot;page-break-after: always;&quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;h1&gt;附录&lt;/h1&gt;
&lt;h2&gt;支撑材料列表&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;img/list.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;LBAS算法实现代码&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&quot;&quot;&quot;
算法来自论文
李辉,殷文明.引领者扰动天牛须算法及其应用[J].数学建模及其应用,2025,14(02):20-27.
有修改
&quot;&quot;&quot;

import time
import kawaiitb.autoload

from matplotlib.animation import FuncAnimation
import numpy as np
import matplotlib.pyplot as plt
from tqdm import trange

plt.rcParams[&apos;font.sans-serif&apos;] = [&apos;Microsoft YaHei&apos;]
plt.rcParams[&apos;axes.unicode_minus&apos;] = False

feature_config = {
    # 是否禁用在特定迭代次数后开始扰动最优点
	&apos;disable_turbulent&apos;: False,

    # 是否禁用在未二次进化时重新roll点
    # True时更偏向每个个体自己的探索。让每个个体自行在P概率下移动到最优。
	&apos;disable_regenerate&apos;: False,  # 30维球测试条件可证明禁用更好，高维不敏感

    # 是否只通过引领者进行进化。
    # 待测试：使个体要么往最优方向，要么往上位方向。指向性最好强一点
	&apos;only_forward_best&apos;: False,  # 似乎对结果不明显。
    
    # 手动复现论文的公式(6)的bug
	&apos;recurrent_bug_from_raw_paper&apos;: False,  # 任何情况禁用都更好。

    # 二次进化的距离是否使用随机数。论文没提但意思应该是那样的
    # 使用固定值会导致随机性很低的向优趋势。
    &apos;secondary_evolution_use_random&apos;: True,

    # 是否在“嗅探”前就立刻地随机化d0。论文里公式这里不这么做，但退火时这样是反直觉且梯度强假设的
    &apos;randomly_tester_d0&apos;: True,
}

# 引领者扰动天牛须算法 (LBAS) 实现
class LBAS:
    def __init__(self, obj_func, pop_size, bounds, max_iter, init_x=None,
                 seed=None,

                 # 超参数
                 P=None,  # 更大时有更大机会二次进化，朝更优者和引领者方向移动，否则重生。
                 d0=None, 
                 delta0=None, 
                 d0_init_ratio=0.5, 
                 delta0_init_ratio=0.5, 
                 d_eta=0.95, 
                 delta_eta=0.95, 
                 tol=1e-10, 

                 with_plot=False, 
                 tqdm=False, 
                 history_per_iter: int|None = 100):
        # 优化算法参数
        self.obj_func = obj_func  # 优化目标
        bounds = np.array(bounds)
        self.dim = len(bounds)  # 问题维度
        self.pop_size = pop_size  # 种群大小
        self.bounds = np.array(bounds)  # 搜索边界 [[min, max], ...]
        self.availd_domain = bounds[:, 1] - bounds[:, 0]
        self.max_iter = max_iter  # 最大迭代次数
        self.tol = tol  # 早停阈值
        self.best_history = []  # 记录每代最佳适应度
        self.seed = seed or int(time.time())
        self.rng = np.random.default_rng(self.seed)

        # 可视化选项和历史
        self.tqdm = tqdm
        self.history_per_iter = history_per_iter
        self.with_plot = with_plot
        if with_plot:
            if dim != 2:
                raise ValueError(&quot;2维问题才能绘制动画&quot;)
            self.with_plot = True
            self.positions_history = []
            self.onframe_lines = []
        
        # 天牛须算法参数
        self.d0 = d0 if d0 is not None else (
            (self.availd_domain) * d0_init_ratio
        )  # 初始两须距离
        self.delta0 = delta0 if delta0 is not None else (
            (self.availd_domain) * delta0_init_ratio
        )  # 初始步长
        self.d_eta = d_eta  # 距离衰减系数
        self.delta_eta = delta_eta  # 步长衰减系数
        
        # LBAS特定参数
        self.P = P or 0.5  # 二次进化概率
        self.t0 = 30  # 初始阶段迭代次数（之后开始扰动）
        self.reducing = 1  # 用于记录衰减系数
        
        # 初始化种群
        self.population = self.init_population(init_x)
        self.fitness = np.array([self.obj_func(ind) for ind in self.population])
        
        # 记录最佳解
        self.best_idx = np.argmin(self.fitness)
        self.best_solution = self.population[self.best_idx].copy()
        self.best_fitness = self.fitness[self.best_idx]
        
        # 记录收敛过程
        self.convergence = []
        self.iteration = 0
    
    def init_population(self, init_x=None):
        &quot;&quot;&quot;初始化种群&quot;&quot;&quot;
        
        population = self.rng.uniform(
            low=self.bounds[:, 0],
            high=self.bounds[:, 1],
            size=(self.pop_size, self.dim)
        )
        
        if init_x != None:
            if len(init_x) != self.dim:
                raise ValueError(&quot;init_x的维度必须与问题维度一致&quot;)
            population[0] = self.clip(init_x)
        
        return population

    def clip(self, x):
        &quot;&quot;&quot;确保解在有效域内&quot;&quot;&quot;
        return np.clip(x, self.bounds[:, 0], self.bounds[:, 1])

    def iterate(self):
        &quot;&quot;&quot;执行一次迭代&quot;&quot;&quot;
        thisframe_lines = []
        self.iteration += 1
        if self.with_plot:
            self.positions_history.append(self.population.copy())
        # 对种群按适应度排序
        sorted_indices = np.argsort(self.fitness)
        sorted_population = self.population[sorted_indices]
        sorted_fitness = self.fitness[sorted_indices]
        
        # 更新全局最优
        if sorted_fitness[0] &amp;lt; self.best_fitness:
            self.best_fitness = sorted_fitness[0]
            self.best_solution = sorted_population[0].copy()
        
        self.best_history.append((self.best_solution.copy(), self.best_fitness))
        
        # 对每个个体进行更新
        for i in range(self.pop_size):
            # 当前个体
            x = self.population[i].copy()
            
            # 1. 生成随机方向向量
            b = self.rng.uniform(-1, 1, self.dim)
            b = b / np.linalg.norm(b)  # 单位化
            if feature_config.get(&apos;randomly_tester_d0&apos;, False):
                b = b * self.rng.random()  # 随机化
            
            # 2. 计算左右须位置
            x_left = x - self.d0 * b
            x_right = x + self.d0 * b
            
            # 确保在边界内
            x_left = self.clip(x_left)
            x_right = self.clip(x_right)
            
            # 3. 计算适应度
            f_left = self.obj_func(x_left)
            f_right = self.obj_func(x_right)
            
            # 4. 决定移动方向并应用惯性权重
            inertia = self.delta0 * b
            # 如果在计算时已经随机化步长，那现在就不随机化了
            if not feature_config.get(&apos;randomly_tester_d0&apos;, False):
                inertia = inertia * self.rng.random()
            if f_right &amp;gt; f_left:  # 向左移动
                x_new = x - inertia
            else:  # 向右移动
                x_new = x + inertia
            if self.with_plot:
                thisframe_lines.append((x_left, x_right, {  # 天牛须
                    &apos;color&apos;: &apos;black&apos;,
                    &apos;linestyle&apos;: &apos;--&apos;,
                    &apos;linewidth&apos;: 1
                }))
                thisframe_lines.append((x, x_new, {  # 天牛主动行动
                    &apos;color&apos;: &apos;red&apos;,
                    &apos;linestyle&apos;: &apos;-&apos;,
                    &apos;linewidth&apos;: 4
                }))
            
            # 确保在边界内
            x_new = self.clip(x_new)
            f_new = self.obj_func(x_new)
            
            # 5. 按概率P进行二次进化
            idx_in_sorted = np.where(sorted_indices == i)[0][0]
            if idx_in_sorted &amp;gt; 0:  # 如果不是最优个体
                # 找到排在当前个体前面的个体
                if self.rng.random() &amp;lt; self.P:
                    # 获取前一个个体和全局最优个体
                    x_prev = sorted_population[idx_in_sorted - 1]
                    x_best = self.best_solution
                    
                    # 二次进化：向更优个体和全局最优个体学习
                    # 使用正确的公式，基于上一次的位置
                    dx_secondary = 0.5 * (x_prev - x_new) + 0.5 * (x_best - x_new)
                    if feature_config.get(&apos;only_forward_best&apos;, False):
                        dx_secondary = 0 * (x_prev - x_new) + 1 * (x_best - x_new)
                    
                    use_rand = self.rng.random() if feature_config.get(&apos;secondary_evolution_use_random&apos;, False) else 1
                    x_secondary = x_new + dx_secondary * use_rand
                    if feature_config.get(&apos;recurrent_bug_from_raw_paper&apos;, False):
                        x_secondary = dx_secondary * use_rand
                    
                    if self.with_plot:
                        thisframe_lines.append((x_new, x_prev, {  # 二次进化，向更优个体学习
                            &apos;color&apos;: &apos;cyan&apos;,
                            &apos;linestyle&apos;: &apos;:&apos;,
                            &apos;linewidth&apos;: 2
                        }))
                        thisframe_lines.append((x_new, x_best, {  # 二次进化，向全局最优学习
                            &apos;color&apos;: &apos;salmon&apos;,
                            &apos;linestyle&apos;: &apos;-.&apos;,
                            &apos;linewidth&apos;: 2
                        }))
                        thisframe_lines.append((x_new, x_new + dx_secondary, {  # 二次进化总方向
                            &apos;color&apos;: &apos;brown&apos;,
                            &apos;linestyle&apos;: &apos;-&apos;,
                            &apos;linewidth&apos;: 2
                        }))
                        thisframe_lines.append((x_new, x_secondary, {  # 完整二次进化
                            &apos;color&apos;: &apos;brown&apos;,
                            &apos;linestyle&apos;: &apos;-&apos;,
                            &apos;linewidth&apos;: 4
                        }))
                    
                    x_secondary = self.clip(x_secondary)
                    f_secondary = self.obj_func(x_secondary)
                    
                    # 选择较好的解
                    if f_secondary &amp;lt; f_new:
                        x_new = x_secondary
                        f_new = f_secondary
                elif not feature_config.get(&apos;disable_regenerate&apos;, False):
                    # 未进行二次进化时，生成随机新个体
                    # 从最优个体开始往随机方向前进当前的两须长度再带个随机量
                    random_direction = self.rng.uniform(-1, 1, self.dim)
                    # 归一化方向向量
                    norm = np.linalg.norm(random_direction)
                    if norm &amp;gt; 0:
                        random_direction = random_direction / norm
                    
                    # 前进距离
                    step_length = self.delta0 * self.rng.random()  # 随机量设为0到d之间的值
                    
                    # 生成新个体
                    x_random = self.best_solution + random_direction * step_length
                    x_random = self.clip(x_random)
                    f_random = self.obj_func(x_random)
                    
                    # 如果新个体更优则接受
                    if f_random &amp;lt; f_new:
                        x_new = x_random
                        f_new = f_random
            

            # 6. 更新个体
            self.population[i] = x_new
            self.fitness[i] = f_new
        
        # 7. 对最优个体进行扰动（如果超过初始阶段）
        if (not feature_config.get(&apos;disable_turbulent&apos;, False)) and self.iteration &amp;gt; self.t0:
            # 对最优个体添加扰动
            perturbation = self.rng.uniform(-1, 1, self.dim) * self.availd_domain * np.exp(-4 * self.iteration / self.max_iter)
            x_perturbed = self.best_solution + perturbation
            x_perturbed = self.clip(x_perturbed)
            f_perturbed = self.obj_func(x_perturbed)
            
            # 如果扰动后的解更好，则替换最优解
            if f_perturbed &amp;lt; self.best_fitness:
                self.best_solution = x_perturbed
                self.best_fitness = f_perturbed
                
                # 也用扰动后的解替换种群中最差的个体
                worst_idx = np.argmax(self.fitness)
                self.population[worst_idx] = x_perturbed
                self.fitness[worst_idx] = f_perturbed
        
        # 早停
        # if self.best_fitness &amp;lt; self.tol:
        #     return True
        
        # 8. 更新步长和两须距离
        self.reducing = self.reducing * self.d_eta
        self.d0 = self.d_eta * self.d0
        self.delta0 = self.delta_eta * self.delta0
        
        # 记录当前最优适应度
        self.convergence.append(self.best_fitness)
        if self.with_plot:
            self.onframe_lines.append(thisframe_lines)
        return False
    
    def optimize(self):
        &quot;&quot;&quot;执行优化过程&quot;&quot;&quot;
        if self.with_plot:
            self.positions_history = []
        self.convergence = []
        iters = trange if self.tqdm else range
        for self.iteration in iters(self.max_iter):
            if self.iterate():
                break
            if self.history_per_iter is not None and self.iteration % self.history_per_iter == 0:
                print(f&quot;I{self.iteration:&amp;lt;6} | Fit={self.best_fitness:.4e}, rdc={self.reducing:.2e}&quot;)
        
        return self.best_solution, self.best_fitness, self.convergence
        
    def create_contour_plot(self):
        &quot;&quot;&quot;创建等高线图&quot;&quot;&quot;
        x = np.linspace(self.bounds[0][0], self.bounds[0][1], 100)
        y = np.linspace(self.bounds[1][0], self.bounds[1][1], 100)
        X, Y = np.meshgrid(x, y)
        Z = np.zeros_like(X)
        
        for i in range(X.shape[0]):
            for j in range(X.shape[1]):
                Z[i, j] = self.obj_func(np.array([X[i, j], Y[i, j]]))
        
        plt.figure(figsize=(12, 10))
        contour = plt.contour(X, Y, Z, 50, cmap=&apos;viridis&apos;, alpha=0.6)
        plt.colorbar(contour, label=&apos;Function Value&apos;)
        plt.xlabel(&apos;X&apos;)
        plt.ylabel(&apos;Y&apos;)
        plt.title(&apos;LBAS Optimization Process&apos;)
        plt.grid(True, alpha=0.3)
        
        return plt.gca(), X, Y, Z
    
    def animate_optimization(self):
        &quot;&quot;&quot;创建优化过程动画&quot;&quot;&quot;
        fig, ax = plt.subplots(figsize=(12, 10))
        ax: plt.Axes  # type: ignore
        
        # 创建等高线
        x = np.linspace(self.bounds[0][0], self.bounds[0][1], 100)
        y = np.linspace(self.bounds[1][0], self.bounds[1][1], 100)
        X, Y = np.meshgrid(x, y)
        Z = np.zeros_like(X)
        
        for i in range(X.shape[0]):
            for j in range(X.shape[1]):
                Z[i, j] = self.obj_func(np.array([X[i, j], Y[i, j]]))
        
        contour = ax.contour(X, Y, Z, 30, cmap=&apos;viridis&apos;, alpha=0.6)
        plt.colorbar(contour, ax=ax, label=&apos;Function Value&apos;)
        
        # 初始化图形元素
        beetles_scatter = ax.scatter([], [], c=&apos;blue&apos;, s=30, label=&apos;Beetles&apos;)
        best_beetle_scatter = ax.scatter([], [], c=&apos;red&apos;, s=100, marker=&apos;*&apos;, label=&apos;Best Beetle&apos;)
        antennae_lines = [ax.plot([], [], &apos;k-&apos;, alpha=0.5)[0] for _ in range(self.pop_size)]
        prev_lines = 100
        move_lines = [ax.plot([], [], &apos;r-&apos;, alpha=0.5)[0] for _ in range(prev_lines)]
        
        # 添加文本框显示迭代信息
        iter_text = ax.text(0.02, 0.95, &apos;&apos;, transform=ax.transAxes, fontsize=12,
                           bbox=dict(facecolor=&apos;white&apos;, alpha=0.7))
        best_text = ax.text(0.02, 0.88, &apos;&apos;, transform=ax.transAxes, fontsize=10,
                           bbox=dict(facecolor=&apos;white&apos;, alpha=0.7))
        
        ax.set_xlim(self.bounds[0])
        ax.set_ylim(self.bounds[1])
        ax.set_xlabel(&apos;X&apos;)
        ax.set_ylabel(&apos;Y&apos;)
        ax.set_title(&apos;Leader Disturbance Beetle Antennae Search Algorithm&apos;)
        ax.legend()
        ax.grid(True, alpha=0.3)

        # 动画更新函数
        def update(frame):
            if frame &amp;lt; len(self.positions_history) - 1:  # 最后一帧有位置但没动作，索性全都不更新
                positions = self.positions_history[frame]
                best_pos, best_fit = self.best_history[frame]
                going_arrows: list[tuple[np.ndarray, np.ndarray, dict]] = self.onframe_lines[frame]
                
                # 更新天牛位置
                beetles_scatter.set_offsets(positions)
                
                # 更新最优天牛位置
                best_beetle_scatter.set_offsets([best_pos])
                
                # 更新移动箭头
                # for i, arrow in enumerate(going_arrows):
                #     start, end = arrow
                #     move_lines[i].set_data([start[0], end[0]], [start[1], end[1]])
                for line, arrow in zip(move_lines, going_arrows + [((-9999, -9999), (-9999, -9999), {})] * prev_lines):
                    start, end, style = arrow
                    line.set_data([start[0], end[0]], [start[1], end[1]])
                    line.set_color(style.get(&apos;color&apos;, &apos;black&apos;))
                    line.set_linestyle(style.get(&apos;linestyle&apos;, &apos;-&apos;))
                    line.set_linewidth(style.get(&apos;linewidth&apos;, 1))

                # 更新文本信息
                iter_text.set_text(f&apos;Iteration: {frame+1}/{self.max_iter}&apos;)
                best_text.set_text(f&apos;Best Fitness: {best_fit:.6f}\nBest Position: ({best_pos[0]:.4f}, {best_pos[1]:.4f})&apos;)
            
            return beetles_scatter, best_beetle_scatter, *antennae_lines, iter_text, best_text
        
        ani = FuncAnimation(fig, update, frames=len(self.positions_history), 
                          interval=200, blit=True)
        return ani
# 测试算法
if __name__ == &quot;__main__&quot;:
    
    from pprint import pprint

    pprint(feature_config)
    def sphere_function(x):
        def function(x):
            return np.sum(x**2)
        return function, (-100, 100)
    # 参数设置
    center = 0
    test_function = sphere_function
    obj, func_bound = test_function(center)
    dim = 2  # 问题维度
    bounds = np.array([func_bound] * dim)  # 求解范围
    pop_size = 3  # 种群大小
    max_iter = 50  # 最大迭代次数
    
    # 创建并运行算法
    eta = 0.9
    lbas = LBAS(obj, pop_size, bounds, max_iter,
                d_eta=eta, delta_eta=eta, tol=1e-5, with_plot=True)
    best_solution, best_fitness, convergence = lbas.optimize()
    
    print()
    print(f&quot;Test params: {dim=},{center=},{test_function.__name__=},{bounds=},&quot;)
    print(f&quot;Algorithm params: {pop_size=},{max_iter=}&quot;)
    print(f&quot;solution: {best_solution}&quot;)
    print(f&quot;fitness: {best_fitness:.6e}&quot;)
    print(f&quot;error: {np.linalg.norm(best_solution - center)}&quot;)
    print(f&quot;iter: {lbas.iteration} / {lbas.max_iter}&quot;)
    
    # 绘制收敛曲线
    # plt.figure(figsize=(10, 6))
    # plt.semilogy(convergence)
    # plt.title(&apos;Convergence Curve&apos;)
    # plt.xlabel(&apos;Iteration&apos;)
    # plt.ylabel(&apos;Best Fitness (log scale)&apos;)
    # plt.grid(True)
    # plt.savefig(f&apos;fig/fig{time.time()}.png&apos;)
    # plt.show()

    ani = lbas.animate_optimization()
    ani.save(&apos;lbas_optimization.gif&apos;, writer=&apos;pillow&apos;, fps=1)
    print(&quot;动画已保存为 &apos;lbas_optimization.gif&apos;&quot;)
    ani.event_source.stop()
    del ani
    plt.close()

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;问题一的模型代码&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;from functools import lru_cache
from math import sin, cos
import numpy as np
from warnings import warn

from utils import bool_func_singularity, calc_total_true_length, total_interval_sum

g = 9.8  # 重力加速度(m/s^2)
TARGET_POSITION = np.array([0, 200, 0])  # 真目标位置
GRENADE_MIN_INTERVAL = 1  # 烟雾弹最小间隔(s)

# 真目标检查点
TARGET_CHECKPOINTS = [
    TARGET_POSITION + np.array([7,  0,  0]),
    TARGET_POSITION + np.array([0,  7,  0]),
    TARGET_POSITION + np.array([-7, 0,  0]),
    TARGET_POSITION + np.array([0, -7,  0]),
    TARGET_POSITION + np.array([7,  0, 10]),
    TARGET_POSITION + np.array([0,  7, 10]),
    TARGET_POSITION + np.array([-7, 0, 10]),
    TARGET_POSITION + np.array([0, -7, 10]),
]

DECOY_POSITION = np.array([0, 0, 0])  # 假目标位置
MISSILE_VELOCITY = 300  # 导弹飞行速度(m/s)
SMOKE_SHIELDING_TIME = 20  # 烟雾云屏蔽时间(s)
SMOKE_VELOCITY = [0, 0, -3]  # 烟雾云速度(m/s)
SMOKE_RADIUS = 10  # 烟雾云半径(m)

def missile_coord(M, t):
    &quot;&quot;&quot;
    计算导弹在t时刻的位置
    M: 导弹初始位置
    t: 时间(s)
    &quot;&quot;&quot;
    M = np.array(M)
    assert M.shape == (3,), f&quot;M的形状必须为(3,), 实际为{M.shape}&quot;
    # 导弹飞向假目标(0,0,0)
    direction = DECOY_POSITION - M
    distance = np.linalg.norm(direction)
    unit_vector = direction / distance
    
    # 导弹以300m/s的速度飞行
    flight_distance = MISSILE_VELOCITY * t
    if flight_distance &amp;gt;= distance:
        warn(&quot;导弹到达假目标&quot;)
        return DECOY_POSITION
    else:
        return M + unit_vector * flight_distance

def uav_coord(FA, theta, v, t):
    &quot;&quot;&quot;
    计算无人机在t时刻的位置
    FA: 无人机初始位置
    theta: 朝向
    v: 飞行速度(m/s)
    t: 时间(s)
    &quot;&quot;&quot;
    # 无人机朝向azimuth飞行
    vector = np.array([cos(theta), sin(theta), 0])  # 模长为1
    
    # 无人机以恒定速度飞行
    return FA + vector * v * t

def grenade_coord(FA, theta, v, t_launch, t_fuse, t):
    &quot;&quot;&quot;
    计算烟幕弹在t时刻的位置
    FA: 无人机初始位置
    azimuth: 朝向假目标方向
    speed: 飞行速度(m/s)
    t_launch: 投放时间(s)
    t_fuse: 引信时间(s)(从投放后算起)
    t: 时间(s)
    &quot;&quot;&quot;
    # 投放时刻无人机的位置和速度
    launch_pos = uav_coord(FA, theta, v, t_launch)
    
    # 无人机速度向量
    uav_velocity = np.array([np.cos(theta), np.sin(theta), 0]) * v
    
    # 爆炸时刻
    t_burst = t_launch + t_fuse
    
    if t &amp;gt; t_burst:
        warn(&quot;计算烟幕弹位置时发现烟幕弹已爆炸&quot;)
        t = t_burst
    if t &amp;lt; t_launch:
        warn(&quot;计算烟幕弹位置时发现烟幕弹未投放&quot;)
        t = t_launch
    
    # 平抛运动
    delta_t = t - t_launch
    dH = uav_velocity * delta_t
    dZ = np.array([0, 0, -0.5 * g * delta_t**2])  # 负号在这
    return launch_pos + dH + dZ

def smoke_coord(FA, theta, v, t_launch, t_fuse, t):
    &quot;&quot;&quot;
    计算烟雾云在t时刻的位置
    FA: 无人机初始位置
    azimuth: 朝向假目标方向
    speed: 飞行速度(m/s)
    t_launch: 投放时间(s)
    t_fuse: 引信时间(s)(从投放后算起)
    t: 时间(s)
    &quot;&quot;&quot;
    t_burst = t_launch + t_fuse
    if t &amp;lt; t_burst:
        warn(&quot;计算烟雾云位置时发现烟雾弹未爆炸&quot;)
        t = t_burst
    if t &amp;gt; t_burst + SMOKE_SHIELDING_TIME:
        warn(&quot;计算烟雾云位置时发现烟雾弹已爆炸&quot;)
        t = t_burst + SMOKE_SHIELDING_TIME
    grenade_pos = grenade_coord(FA, theta, v, t_launch, t_fuse, t_launch + t_fuse)
    return grenade_pos + np.array(SMOKE_VELOCITY) * (t - t_burst)  # 烟雾云高度100m

def is_shielding(smoke_coord, missile_coord):
    &quot;&quot;&quot;
    判断导弹是否被烟雾云遮蔽
    1. 判断导弹是否在烟雾云内部，返回True
    2. 判断导弹是否比烟雾云更快，返回False
    3. 判断导弹与目标的直线与烟雾云的距离是否大于烟雾云半径，返回False
    返回True
    smoke_coord: 烟雾云位置
    missile_coord: 导弹位置
    &quot;&quot;&quot;
    # 1. 判断导弹在烟雾云内部
    if np.linalg.norm(missile_coord - smoke_coord) &amp;lt;= SMOKE_RADIUS:
        return True
    
    for checkpoint in TARGET_CHECKPOINTS:
        ms2cp = missile_coord - checkpoint
        cp2sc = checkpoint - smoke_coord
        # 2. 判断导弹是否比烟雾云更快
        distance_to_checkpoint = np.linalg.norm(ms2cp)
        distance_to_smoke = np.linalg.norm(cp2sc)
        if distance_to_checkpoint &amp;lt; distance_to_smoke:
            return False
        # 3. 判断导弹与目标的直线与烟雾云的距离是否大于烟雾云半径
        d_smoke_to_route = np.linalg.norm(np.cross(cp2sc, ms2cp)) / distance_to_checkpoint
        if d_smoke_to_route &amp;gt; SMOKE_RADIUS:
            return False
    
    return True

def shielding_para(FA, M, azimuth, speed, launch_time, fuse_time):
    &quot;&quot;&quot;
    计算有效遮蔽时间
    FA: 无人机初始位置
    M: 导弹初始位置
    azimuth: 朝向假目标方向
    speed: 飞行速度(m/s)
    launch_time: 投放时间(s)
    fuse_time: 引信时间(s)
    &quot;&quot;&quot;
    # 计算有效遮蔽时间
    t_burst = launch_time + fuse_time
    interval = (t_burst, t_burst + SMOKE_SHIELDING_TIME)
    shielding_paras = bool_func_singularity(
        lambda t: is_shielding(
            smoke_coord(FA, azimuth, speed, launch_time, fuse_time, t), 
            missile_coord(M, t)
        ),
        interval, tol=1e-6, max_depth=6
    )
    return shielding_paras

def para_start_end(para):
    &quot;&quot;&quot;
    计算有效遮蔽时间
    &quot;&quot;&quot;
    leftval, n_point, points, interval = para
    if leftval and n_point == 0:
        return interval[0], interval[1]
    if not leftval and n_point == 0:
        return interval[0], interval[0]
    elif leftval and n_point == 1:
        return interval[0], points[0]
    elif not leftval and n_point == 1:
        return points[0], interval[1]
    elif leftval and n_point == 2:
        raise ValueError(&quot;不预期的两次遮挡&quot;)
    elif not leftval and n_point == 2:
        return points[0], points[1]
    else:
        raise ValueError(f&quot;不预期的参数 {para}&quot;)

def shielding_time(FA, M, azimuth, speed, launch_time, fuse_time):
    &quot;&quot;&quot;
    计算有效遮蔽时间
    FA: 无人机初始位置
    M: 导弹初始位置
    azimuth: 朝向假目标方向
    speed: 飞行速度(m/s)
    launch_time: 投放时间(s)
    fuse_time: 引信时间(s)
    &quot;&quot;&quot;
    t_shielding = calc_total_true_length(*shielding_para(FA, M, azimuth, speed, launch_time, fuse_time))
    return t_shielding

def sum_of_shielding_times(*para_groups):
    &quot;&quot;&quot;
    计算总有效遮蔽时间
    &quot;&quot;&quot;
    intervals = [para_start_end(para) for para in para_groups]
    return total_interval_sum(intervals)

def shielding_reward(FA, M, azimuth, speed, launch_time, fuse_time, assert_no_shielding=False):
    &quot;&quot;&quot;
    计算导弹被烟雾云遮蔽的奖励。**此函数为最大化函数**
    1. 判断导弹是否实际被烟雾云遮蔽，返回原始屏蔽时长作为奖励
    获取烟雾弹爆炸开始至消散的平均位置与导弹当时的平均位置
    2. 计算导弹航线与烟雾云的距离，返回基于此距离的惩罚。
    3. 计算是否是导弹更靠近检查点，如果是则遮蔽不到，惩罚加倍
    &quot;&quot;&quot;
    # 1. 判断是否被烟雾云遮蔽
    if not assert_no_shielding:
        T_shielding = shielding_time(FA, M, azimuth, speed, launch_time, fuse_time)
        if T_shielding &amp;gt; 0:
            return T_shielding
    
    smoke_pos = smoke_coord(FA, azimuth, speed, launch_time, fuse_time, launch_time + fuse_time + SMOKE_SHIELDING_TIME / 2)
    missile_pos = missile_coord(M, launch_time + fuse_time + SMOKE_SHIELDING_TIME / 2)

    target_center = TARGET_POSITION + np.array([0,  0,  5])
    cp2ms = missile_pos - target_center
    sk2cp = target_center - smoke_pos
    # 2. 计算导弹航线与烟雾云的距离
    d_missile_target = np.linalg.norm(cp2ms)
    d_target_smoke = np.linalg.norm(sk2cp)
    d_smoke_to_route = np.linalg.norm(np.cross(sk2cp, cp2ms)) / d_missile_target
    penalty = -d_smoke_to_route
    # 3. 判断导弹是否比烟雾云更快
    if d_missile_target &amp;lt; d_target_smoke:
        return penalty * 2
    return penalty

# 问题1参数
FA = np.array([17800, 0, 1800])  # FY1初始位置
M1 = np.array([20000, 0, 2000])  # M1初始位置
azimuth = np.arctan2(DECOY_POSITION[1] - FA[1], DECOY_POSITION[0] - FA[0])
speed = 120  # 飞行速度(m/s)
launch_time = 1.5  # 投放时间(s)
fuse_time = 3.6  # 引信时间(s)

if __name__ == &quot;__main__&quot;:
    # 解决问题1
    print(&quot;问题一计算结果：&quot;)
    print(f&quot;飞行方向：{np.degrees(azimuth)}°&quot;)
    print(f&quot;飞行速度：{speed} m/s&quot;)
    print(f&quot;投放时间：{launch_time} s&quot;)
    print(f&quot;引信时间：{fuse_time} s&quot;)
    effective_time = shielding_time(FA, M1, azimuth, speed, launch_time, fuse_time)
    print(f&quot;遮蔽时间: {effective_time:.6f}秒&quot;)



if __name__ == &quot;__main__1&quot;:  # 测试函数评估速度，即可优化性
    import timeit
    repeats = 5
    number_per_repeat = 20
    def test_shielding_time():
        return shielding_time(FA, M1, azimuth, speed, launch_time, fuse_time)
    
    times = timeit.repeat(test_shielding_time, number=number_per_repeat, repeat=repeats)
    
    print(f&quot;重复测试 {repeats} 次，每次 {number_per_repeat} 轮&quot;)
    for i, time_taken in enumerate(times, 1):
        average_time = time_taken / number_per_repeat
        print(f&quot;第 {i} 次测试 - 平均时间: {average_time:.6f} 秒&quot;)
    
    best_time = min(times) / number_per_repeat
    worst_time = max(times) / number_per_repeat
    avg_time = sum(times) / (repeats * number_per_repeat)
    
    print(f&quot;\n最佳执行时间: {best_time:.6f} 秒&quot;)
    print(f&quot;最差执行时间: {worst_time:.6f} 秒&quot;)
    print(f&quot;平均执行时间: {avg_time:.6f} 秒&quot;)
    
    # 运行一次获取结果
    result = test_shielding_time()
    print(f&quot;有效遮蔽时长: {result:.6f} 秒&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;问题二的模型代码&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;import numpy as np
from q1 import TARGET_POSITION, shielding_time, uav_coord, grenade_coord
from scipy.optimize import minimize

from lbas_opt import LBAS

def solve_q2(method=&apos;lbas&apos;):
    &quot;&quot;&quot;
    解决问题2
    &quot;&quot;&quot;

    # 问题2参数
    FA = np.array([17800, 0, 1800])  # FY1初始位置
    M = np.array([20000, 0, 2000])  # M1初始位置
    
    # 定义目标函数
    def objective(params):
        azimuth, speed, launch_time, fuse_time = params
        for i, (param, (lower, upper)) in enumerate(zip(params, bounds)):
            if param &amp;lt; lower or param &amp;gt; upper:
                print(f&quot;参数 {i} 超出边界: {param} 不在 [{lower}, {upper}] 范围内&quot;)
                return float(&apos;inf&apos;)  # 返回一个很大的值表示无效解
        return -shielding_time(FA, M, azimuth, speed, launch_time, fuse_time)
    
    # 参数边界约束
    bounds = [
        (0, 2 * np.pi),        # theta: 无人机方位角，0到2π弧度
        (70, 140),             # v: 无人机速度，70-140 m/s
        (0, 60),                # launch_time: 投下时间，0秒之后投放
        (0, 60)                # fuse_time: 引线时间，0秒之后起爆
    ]
    
    # 初始猜测值，基于问题1的参数
    x0 = [
        np.pi,  # 朝向假目标方向
        120,      # 速度120 m/s
        1.5,      # 投放时间1.5秒
        3.6       # 引信时间3.6秒
    ]
    
    opt_azimuth, opt_speed, opt_launch, opt_fuse, max_shielding_time = [0] * 5
    convergence = []
    # 执行优化
    if method == &apos;lbas&apos;:
        lbas = LBAS(
            # 最优化参数
            obj_func=objective,
            pop_size=50,
            bounds=bounds,
            max_iter=100,
            init_x=x0,

            # 超参数
            d_eta=0.97,
            delta_eta=0.97,

            # 可视化
            history_per_iter=10,
        )
        best_solution, best_fitness, convergence = lbas.optimize()
        opt_azimuth, opt_speed, opt_launch, opt_fuse = best_solution
        max_shielding_time = -best_fitness
    
    elif method == &apos;bfgs&apos;:
        result = minimize(
            objective,          # 目标函数
            x0,                 # 初始猜测
            bounds=bounds,      # 参数边界
            method=&apos;L-BFGS-B&apos;,  # 选择支持边界约束的优化方法
            options={
                &apos;maxiter&apos;: 100,  # 最大迭代次数
                &apos;disp&apos;: True     # 显示优化过程信息
            }
        )
        opt_azimuth, opt_speed, opt_launch, opt_fuse = result.x
        max_shielding_time = -result.fun
        convergence = [result.fun] * result.nit
    
    elif method == &apos;diff_evol&apos;:
        from scipy.optimize import differential_evolution
        result = differential_evolution(
            objective,
            bounds,
            strategy=&apos;best1bin&apos;,
            maxiter=100,
            popsize=20,
            tol=0.01,
            mutation=(0.5, 1),
            recombination=0.7,
            seed=42,
            callback=None,
            disp=True
        )
        opt_azimuth, opt_speed, opt_launch, opt_fuse = result.x
        max_shielding_time = -result.fun
        convergence = [result.fun] * result.nit

    elif method == &apos;basinhopping&apos;:
        from scipy.optimize import basinhopping
        minimizer_kwargs = {&quot;method&quot;: &quot;L-BFGS-B&quot;, &quot;bounds&quot;: bounds}
        result = basinhopping(
            objective,
            x0,
            niter=100,
            minimizer_kwargs=minimizer_kwargs,
            stepsize=0.5,
            T=1.0,
            disp=True
        )
        opt_azimuth, opt_speed, opt_launch, opt_fuse = result.x
        max_shielding_time = -result.fun
        convergence = [result.fun] * result.nit

    elif method == &apos;pso&apos;:
        import pyswarms as ps
        
        # 包装目标函数以处理PSO的输入格式
        def objective_pso(params_array):
            # params_array 是二维数组，形状为 (n_particles, 4)
            # 我们需要对每个粒子计算目标函数值
            n_particles = params_array.shape[0]
            results = np.zeros(n_particles)
            
            for i in range(n_particles):
                # 提取单个粒子的参数
                azimuth, speed, launch_time, fuse_time = params_array[i]
                # 计算目标函数值
                results[i] = objective([azimuth, speed, launch_time, fuse_time])
            
            return results
        
        # 设置PSO参数
        options = {&apos;c1&apos;: 3, &apos;c2&apos;: 1, &apos;w&apos;: 1.8}
        # 创建边界矩阵
        bounds_matrix = np.array(bounds).T
        # 初始化优化器
        optimizer = ps.single.GlobalBestPSO(
            n_particles=100, 
            dimensions=4, 
            options=options, 
            bounds=bounds_matrix
        )
        # 执行优化
        cost, pos = optimizer.optimize(objective_pso, iters=100)
        opt_azimuth, opt_speed, opt_launch, opt_fuse = pos
        max_shielding_time = -cost
        convergence = optimizer.cost_history

    elif method == &apos;ga&apos;:
        from deap import base, creator, tools, algorithms
        import random
        
        # 创建适应度类和个体类
        creator.create(&quot;FitnessMin&quot;, base.Fitness, weights=(-1.0,))
        creator.create(&quot;Individual&quot;, list, fitness=creator.FitnessMin)  # type: ignore
        
        # 初始化工具箱
        toolbox = base.Toolbox()
        
        # 定义属性生成函数
        def random_attribute(i):
            return random.uniform(bounds[i][0], bounds[i][1])
        
        # 注册个体和种群生成函数
        toolbox.register(&quot;attr_0&quot;, random_attribute, 0)
        toolbox.register(&quot;attr_1&quot;, random_attribute, 1)
        toolbox.register(&quot;attr_2&quot;, random_attribute, 2)
        toolbox.register(&quot;attr_3&quot;, random_attribute, 3)
        toolbox.register(&quot;individual&quot;, tools.initCycle, creator.Individual,   # type: ignore
                        (toolbox.attr_0, toolbox.attr_1, toolbox.attr_2, toolbox.attr_3), n=1)  # type: ignore
        toolbox.register(&quot;population&quot;, tools.initRepeat, list, toolbox.individual)  # type: ignore
        
        # 注册评估、交叉、变异和选择函数
        toolbox.register(&quot;evaluate&quot;, lambda ind: (objective(ind),))
        toolbox.register(&quot;mate&quot;, tools.cxBlend, alpha=0.5)
        toolbox.register(&quot;mutate&quot;, tools.mutGaussian, mu=0, sigma=1, indpb=0.2)
        toolbox.register(&quot;select&quot;, tools.selTournament, tournsize=3)
        
        # 创建初始种群
        pop = toolbox.population(n=200)  # type: ignore
        
        # 运行遗传算法
        hof = tools.HallOfFame(1)
        stats = tools.Statistics(lambda ind: ind.fitness.values)
        stats.register(&quot;avg&quot;, np.mean)
        stats.register(&quot;min&quot;, np.min)
        
        pop, log = algorithms.eaSimple(
            pop, toolbox, 
            cxpb=0.5, mutpb=0.2, ngen=100, 
            stats=stats, halloffame=hof, verbose=False
        )
        
        # 获取最优解
        best_individual = hof[0]
        opt_azimuth, opt_speed, opt_launch, opt_fuse = best_individual
        max_shielding_time = -best_individual.fitness.values[0]
        convergence = [log[i][&apos;min&apos;] for i in range(len(log))]


    # 计算最优投放点和起爆点
    launch_point = uav_coord(FA, opt_azimuth, opt_speed, opt_launch)
    burst_point = grenade_coord(FA, opt_azimuth, opt_speed, opt_launch, opt_fuse, opt_launch + opt_fuse)
    
    # 结果
    print(&quot;问题2优化结果:&quot;)
    print(f&quot;最优飞行方向: {np.degrees(opt_azimuth):.6f}°&quot;)
    print(f&quot;最优飞行速度: {opt_speed:.6f} m/s&quot;)
    print(f&quot;最优投放时间: {opt_launch:.6f} s&quot;)
    print(f&quot;最优引信时间: {opt_fuse:.6f} s&quot;)
    print(f&quot;最大遮蔽时间: {max_shielding_time:.6f} s&quot;)
    print()
    print(f&quot;最优投放点坐标: ({launch_point[0]:.2f}, {launch_point[1]:.2f}, {launch_point[2]:.2f}) m&quot;)
    print(f&quot;最优起爆点坐标: ({burst_point[0]:.2f}, {burst_point[1]:.2f}, {burst_point[2]:.2f}) m&quot;)
    print(&quot;=&quot; * 50)

    # # 绘制收敛曲线
    # import matplotlib.pyplot as plt
    # import time
    # plt.figure(figsize=(10, 6))
    # plt.plot(convergence)
    # plt.title(&apos;Convergence Curve&apos;)
    # plt.xlabel(&apos;Iteration&apos;)
    # plt.ylabel(&apos;Best Fitness&apos;)
    # plt.grid(True)
    # plt.show()
    
    return {
        &apos;azimuth&apos;: opt_azimuth,
        &apos;speed&apos;: opt_speed,
        &apos;launch_time&apos;: opt_launch,
        &apos;fuse_time&apos;: opt_fuse,
        &apos;投放点&apos;: launch_point,
        &apos;起爆点&apos;: burst_point,
        &apos;遮蔽时间&apos;: max_shielding_time,
        &apos;convergence&apos;: convergence,
    }

def plot_convergence_curves():
    methods = [&apos;lbas&apos;, &apos;bfgs&apos;, &apos;diff_evol&apos;, &apos;basinhopping&apos;, &apos;pso&apos;, &apos;ga&apos;]
    convergence_data = {}
    
    for method in methods:
        result = solve_q2(method)
        convergence_data[method] = result[&apos;convergence&apos;]
    
    import matplotlib.pyplot as plt
    plt.rcParams[&apos;font.sans-serif&apos;] = [&apos;SimHei&apos;]
    plt.rcParams[&apos;axes.unicode_minus&apos;] = False

    plt.figure(figsize=(12, 8))
    
    for method, data in convergence_data.items():
        plt.plot(data, label=method)
    
    plt.title(&apos;&apos;)
    plt.xlabel(&apos;迭代次数&apos;)
    plt.ylabel(&apos;最优遮挡时间(最小化，取负)&apos;)
    plt.legend()
    plt.grid(True)
    plt.show()

if __name__ == &quot;__main__&quot;:
    # solve_q2(&apos;ga&apos;)
    plot_convergence_curves()
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;问题三的模型代码&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;import time
import numpy as np
from q1 import TARGET_POSITION, para_start_end, shielding_para, shielding_reward, shielding_time, sum_of_shielding_times, uav_coord, grenade_coord, GRENADE_MIN_INTERVAL
from scipy.optimize import minimize
from utils import calc_total_true_length

from lbas_opt import LBAS

def solve_q3(method=&apos;lbas&apos;):
    &quot;&quot;&quot;
    解决问题3
    &quot;&quot;&quot;

    # 与问题2参数相同
    FA = np.array([17800, 0, 1800])  # FY1初始位置
    M = np.array([20000, 0, 2000])  # M1初始位置

    x0 = [  # 初始猜测
        np.deg2rad(5.005980),   # 无人机方位角
        138.259364,     # 无人机速度

        0,      # 烟雾弹1投下时间
        0,      # 烟雾弹1引线时间
        1 - 1,  # 烟雾弹2间隔时间
        0,      # 烟雾弹2引线时间
        2 - 2,  # 烟雾弹3间隔时间
        0,      # 烟雾弹3引线时间
    ]
    
    # 定义目标函数
    def fitness(params):
        (azimuth, speed, 
         lc1, 
         fs1, 
         dlc2, 
         fs2, dlc3, fs3) = params
        lc2 = lc1 + GRENADE_MIN_INTERVAL + dlc2  # 至少间隔一秒
        lc3 = lc2 + GRENADE_MIN_INTERVAL + dlc3
        shield1 = shielding_para(FA, M, azimuth, speed, lc1, fs1)
        shield2 = shielding_para(FA, M, azimuth, speed, lc2, fs2)
        shield3 = shielding_para(FA, M, azimuth, speed, lc3, fs3)
        t_shield = sum_of_shielding_times(shield1, shield2, shield3)
        return t_shield

    def objective(params):
        (azimuth, speed, 
         lc1, 
         fs1, 
         dlc2, 
         fs2, 
         dlc3, fs3) = params
        lc2 = lc1 + GRENADE_MIN_INTERVAL + dlc2  # 至少间隔一秒
        lc3 = lc2 + GRENADE_MIN_INTERVAL + dlc3
        shield1 = shielding_para(FA, M, azimuth, speed, lc1, fs1)
        shield2 = shielding_para(FA, M, azimuth, speed, lc2, fs2)
        shield3 = shielding_para(FA, M, azimuth, speed, lc3, fs3)
        t_shield = sum_of_shielding_times(shield1, shield2, shield3)
        t_1 = calc_total_true_length(*shield1)
        t_2 = calc_total_true_length(*shield2)
        t_3 = calc_total_true_length(*shield3)
        imbalance_penalty = (
            (25 if t_1 == 0 else 0) +
            (25 if t_2 == 0 else 0) +
            (25 if t_3 == 0 else 0)
        )
        # imbalance_penalty = np.var([t_1, t_2, t_3]) ** 3
        # imbalance_penalty = 0

        return - t_shield + imbalance_penalty
    
    def objective_reward(params):
        (azimuth, speed, 
         lc1, 
         fs1, 
         dlc2, 
         fs2, 
         dlc3, fs3) = params
        lc2 = lc1 + GRENADE_MIN_INTERVAL + dlc2  # 至少间隔一秒
        lc3 = lc2 + GRENADE_MIN_INTERVAL + dlc3
        shield1 = shielding_para(FA, M, azimuth, speed, lc1, fs1)
        shield2 = shielding_para(FA, M, azimuth, speed, lc2, fs2)
        shield3 = shielding_para(FA, M, azimuth, speed, lc3, fs3)
        return -sum_of_shielding_times(shield1, shield2, shield3)
        reward1 = shielding_reward(FA, M, azimuth, speed, lc1, fs1)
        reward2 = shielding_reward(FA, M, azimuth, speed, lc2, fs2)
        reward3 = shielding_reward(FA, M, azimuth, speed, lc3, fs3)

        # imbalance_penalty = np.var([t_1, t_2, t_3]) ** 3
        # imbalance_penalty = 0

        return -sum([reward1, reward2, reward3])
    
    # 参数边界约束
    bounds = [
        (0, 5 * np.pi/2),        # theta: 无人机方位角，π/2到5π/2弧度。旋转90度避免无法进入热点区
        (70, 140),             # v:   无人机速度，70-140 m/s
        
        (0, 10),              # lc1:  烟雾弹1投下时间，0秒之后投放
        (0, 10),              # fs1:  烟雾弹1引线时间，0秒之后起爆
        (0, 10),              # dlc2: 烟雾弹2间隔时间，1+0秒之后投放
        (0, 10),              # fs2:  烟雾弹2引线时间，0秒之后起爆
        (0, 10),              # dlc3: 烟雾弹3间隔时间，1+0秒之后投放
        (0, 10)               # fs3:  烟雾弹3引线时间，0秒之后起爆
    ]

    opt_azimuth, opt_speed, opt_lc1, opt_fs1, opt_dlc2, opt_fs2, opt_dlc3, opt_fs3, max_shielding_time = [0] * 9
    # 执行优化
    seed = int(time.time())
    if method == &apos;lbas&apos;:
        lbas = LBAS(
            # 最优化参数
            obj_func=objective_reward,
            pop_size=20,
            bounds=bounds,
            max_iter=10,
            init_x=x0,

            # 超参数
            d_eta=0.92,
            delta_eta=0.92,
            P=0.6,

            # 可视化
            history_per_iter=5,

            # 杂项
            seed=seed,
        )
        best_solution, best_fitness, convergence = lbas.optimize()
        (opt_azimuth, opt_speed, 
         opt_lc1, 
         opt_fs1, 
         opt_dlc2, 
         opt_fs2, opt_dlc3, opt_fs3) = best_solution
        max_shielding_time = fitness(best_solution)
    elif method == &apos;pso&apos;:
        pass

    # 整理各种参数
    opt_lc2 = opt_lc1 + GRENADE_MIN_INTERVAL + opt_dlc2
    opt_lc3 = opt_lc2 + GRENADE_MIN_INTERVAL + opt_dlc3
    lc1_point = uav_coord(FA, opt_azimuth, opt_speed, opt_lc1)
    lc2_point = uav_coord(FA, opt_azimuth, opt_speed, opt_lc2)
    lc3_point = uav_coord(FA, opt_azimuth, opt_speed, opt_lc3)
    burst1_point = grenade_coord(FA, opt_azimuth, opt_speed, opt_lc1, opt_fs1, opt_lc1 + opt_fs1)
    burst2_point = grenade_coord(FA, opt_azimuth, opt_speed, opt_lc2, opt_fs2, opt_lc2 + opt_fs2)
    burst3_point = grenade_coord(FA, opt_azimuth, opt_speed, opt_lc3, opt_fs3, opt_lc3 + opt_fs3)

    shield_single1 = shielding_time(FA, M, opt_azimuth, opt_speed, opt_lc1, opt_fs1)
    shield_single2 = shielding_time(FA, M, opt_azimuth, opt_speed, opt_lc2, opt_fs2)
    shield_single3 = shielding_time(FA, M, opt_azimuth, opt_speed, opt_lc3, opt_fs3)
    interval_1 = para_start_end(shielding_para(FA, M, opt_azimuth, opt_speed, opt_lc1, opt_fs1))
    interval_2 = para_start_end(shielding_para(FA, M, opt_azimuth, opt_speed, opt_lc2, opt_fs2))
    interval_3 = para_start_end(shielding_para(FA, M, opt_azimuth, opt_speed, opt_lc3, opt_fs3))

    # 结果
    print(&quot;问题3优化结果:&quot;)
    print(f&quot;最优飞行方向: {np.degrees(opt_azimuth):.6f}°&quot;)
    print(f&quot;最优飞行速度: {opt_speed:.6f} m/s&quot;)
    print(f&quot;最大遮蔽时间: {max_shielding_time:.6f} s&quot;)

    print(&quot;烟雾弹1&quot;)
    print(f&quot;- 投放, 引信: {opt_lc1:.6f} s, {opt_fs1:.6f} s&quot;)
    print(f&quot;- 投放点坐标: ({lc1_point[0]:.2f}, {lc1_point[1]:.2f}, {lc1_point[2]:.2f}) m&quot;)
    print(f&quot;- 起爆点坐标: ({burst1_point[0]:.2f}, {burst1_point[1]:.2f}, {burst1_point[2]:.2f}) m&quot;)
    print(f&quot;- 独立遮蔽时间: {shield_single1:.6f} s&quot;)
    print(f&quot;- 遮蔽时间区间: {interval_1}&quot;)
    
    print(&quot;烟雾弹2&quot;)
    print(f&quot;- 投放, 引信: {opt_lc2:.6f} s, {opt_fs2:.6f} s&quot;)
    print(f&quot;- 投放点坐标: ({lc2_point[0]:.2f}, {lc2_point[1]:.2f}, {lc2_point[2]:.2f}) m&quot;)
    print(f&quot;- 起爆点坐标: ({burst2_point[0]:.2f}, {burst2_point[1]:.2f}, {burst2_point[2]:.2f}) m&quot;)
    print(f&quot;- 独立遮蔽时间: {shield_single2:.6f} s&quot;)
    print(f&quot;- 遮蔽时间区间: {interval_2}&quot;)
    
    print(&quot;烟雾弹3&quot;)
    print(f&quot;- 投放, 引信: {opt_lc3:.6f} s, {opt_fs3:.6f} s&quot;)
    print(f&quot;- 投放点坐标: ({lc3_point[0]:.2f}, {lc3_point[1]:.2f}, {lc3_point[2]:.2f}) m&quot;)
    print(f&quot;- 起爆点坐标: ({burst3_point[0]:.2f}, {burst3_point[1]:.2f}, {burst3_point[2]:.2f}) m&quot;)
    print(f&quot;- 独立遮蔽时间: {shield_single3:.6f} s&quot;)
    print(f&quot;- 遮蔽时间区间: {interval_3}&quot;)

    print(f&quot;本次种子: {seed}&quot;)



if __name__ == &apos;__main__&apos;:
    solve_q3(&apos;lbas&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;问题四的模型代码&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;from functools import partial
import time
import numpy as np
from q1 import TARGET_POSITION, para_start_end, shielding_para, shielding_time, sum_of_shielding_times, uav_coord, grenade_coord, GRENADE_MIN_INTERVAL, shielding_reward
from scipy.optimize import minimize
from utils import calc_total_true_length

from lbas_opt import LBAS

def solve_q2_1(Fi, M, seed=int(time.time())):
    &quot;&quot;&quot;
    解决类问题2问题，但空间扩展，使用新的目标函数
    &quot;&quot;&quot;
    # 定义目标函数
    def objective_step1(F, params):
        azimuth, speed, launch_time, fuse_time = params
        grenade_nearing_reward = shielding_reward(F, M, azimuth, speed, launch_time, fuse_time)
        return -grenade_nearing_reward-speed
    # 约束
    bounds_step1 = [
        (0, 2 * np.pi),# theta: 无人机方位角，0到2π弧度，略微扩展以避免可能的最优区割裂
        (70, 140),     # v: 无人机速度，70-140 m/s
        (0, 60),       # launch_time: 投下时间，0秒之后投放
        (0, 60)        # fuse_time: 引线时间，0秒之后起爆
    ]
    lbas = LBAS(
        # 最优化参数
        obj_func=partial(objective_step1, Fi),
        pop_size=300,
        bounds=bounds_step1,
        max_iter=50,
        seed=seed,
        # 超参数
        P=1,
        d_eta=0.95,
        delta_eta=0.95,
        # 可视化
        history_per_iter=5,
    )
    best_solution, best_fitness, convergence = lbas.optimize()
    return best_solution


def solve_q4(method=&apos;lbas&apos;):
    &quot;&quot;&quot;
    解决问题4
    &quot;&quot;&quot;
    seed = int(time.time())

    # 各投放一个烟雾弹
    F1 = np.array([17800,     0, 1800])  # FY1初始位置
    F2 = np.array([12000,  1400, 1400])  # FY2初始位置
    F3 = np.array([ 6000, -3000,  700])  # FY3初始位置
    M  = np.array([20000,     0, 2000])  # M1初始位置

    # 一阶段：各自为战，找到解集密集区
    # 优化
    part_solutions = [[0,0,0,0] for _ in range(3)]
    for i, Fi in enumerate([F1, F2, F3]):
        print(f&apos;正在优化 F{i+1}&apos;)
        if i == 0:
            &quot;&quot;&quot;
            问题2优化结果:
            最优飞行方向:4.993674 °
            最优飞行速度:124.169252 m/s
            最优投放时间:0.907518 s
            最优引信时间:0.137133 s
            &quot;&quot;&quot;
            opt_azimuth = np.deg2rad(4.993674)
            opt_speed   = 124.169252
            opt_launch  = 0.907518
            opt_fuse    = 0.137133
            best_solution = opt_azimuth, opt_speed, opt_launch, opt_fuse
        else:
            best_solution = solve_q2_1(Fi, M, seed=seed)
            opt_azimuth, opt_speed, opt_launch, opt_fuse = best_solution
        
        max_shielding_time = shielding_time(Fi, M, opt_azimuth, opt_speed, opt_launch, opt_fuse)

        print(f&apos;F{i+1} 最优解: &apos;)
        print(f&apos;θ = {opt_azimuth:.4f} rad; v = {opt_speed:.4f} m/s&apos;)
        print(f&apos;TL= {opt_launch:.4f} s  ; TF= {opt_fuse:.4f} s&apos;)
        print(f&apos;最大遮蔽时间={max_shielding_time:.4f}&apos;)
        print()
        if max_shielding_time == 0:
            raise ValueError(f&quot;F{i+1} 未找到解&quot;)
        part_solutions[i] = best_solution
    
    # 二阶段：不用二阶段了。这三个无人机的遮挡段是分离的
    a1, v1, lc1, fs1 = part_solutions[0]
    a2, v2, lc2, fs2 = part_solutions[1]
    a3, v3, lc3, fs3 = part_solutions[2]

    shield1 = shielding_para(F1, M, a1, v1, lc1, fs1)
    shield2 = shielding_para(F2, M, a2, v2, lc2, fs2)
    shield3 = shielding_para(F3, M, a3, v3, lc3, fs3)
    t_shield = sum_of_shielding_times(shield1, shield2, shield3)
    print(f&quot;总时间：{t_shield}&quot;)
    # 计算投放点和起爆点坐标
    lc1_point = uav_coord(F1, a1, v1, lc1)
    burst1_point = grenade_coord(F1, a1, v1, lc1, fs1, lc1 + fs1)
    lc2_point = uav_coord(F2, a2, v2, lc2)
    burst2_point = grenade_coord(F2, a2, v2, lc2, fs2, lc2 + fs2)
    lc3_point = uav_coord(F3, a3, v3, lc3)
    burst3_point = grenade_coord(F3, a3, v3, lc3, fs3, lc3 + fs3)
    
    # 计算独立遮蔽时间
    shield_single1 = shielding_time(F1, M, a1, v1, lc1, fs1)
    shield_single2 = shielding_time(F2, M, a2, v2, lc2, fs2)
    shield_single3 = shielding_time(F3, M, a3, v3, lc3, fs3)
    interval_1 = para_start_end(shielding_para(F1, M, a1, v1, lc1, fs1))
    interval_2 = para_start_end(shielding_para(F2, M, a2, v2, lc2, fs2))
    interval_3 = para_start_end(shielding_para(F3, M, a3, v3, lc3, fs3))
    
    print(&quot;烟雾弹1&quot;)
    print(f&quot;- 投放, 引信: {lc1:.6f} s, {fs1:.6f} s&quot;)
    print(f&quot;- 投放点坐标: ({lc1_point[0]:.2f}, {lc1_point[1]:.2f}, {lc1_point[2]:.2f}) m&quot;)
    print(f&quot;- 起爆点坐标: ({burst1_point[0]:.2f}, {burst1_point[1]:.2f}, {burst1_point[2]:.2f}) m&quot;)
    print(f&quot;- 独立遮蔽时间: {shield_single1:.6f} s&quot;)
    print(f&quot;- 遮蔽时间段: {interval_1}&quot;)
    
    print(&quot;烟雾弹2&quot;)
    print(f&quot;- 投放, 引信: {lc2:.6f} s, {fs2:.6f} s&quot;)
    print(f&quot;- 投放点坐标: ({lc2_point[0]:.2f}, {lc2_point[1]:.2f}, {lc2_point[2]:.2f}) m&quot;)
    print(f&quot;- 起爆点坐标: ({burst2_point[0]:.2f}, {burst2_point[1]:.2f}, {burst2_point[2]:.2f}) m&quot;)
    print(f&quot;- 独立遮蔽时间: {shield_single2:.6f} s&quot;)
    print(f&quot;- 遮蔽时间段: {interval_2}&quot;)
    
    print(&quot;烟雾弹3&quot;)
    print(f&quot;- 投放, 引信: {lc3:.6f} s, {fs3:.6f} s&quot;)
    print(f&quot;- 投放点坐标: ({lc3_point[0]:.2f}, {lc3_point[1]:.2f}, {lc3_point[2]:.2f}) m&quot;)
    print(f&quot;- 起爆点坐标: ({burst3_point[0]:.2f}, {burst3_point[1]:.2f}, {burst3_point[2]:.2f}) m&quot;)
    print(f&quot;- 独立遮蔽时间: {shield_single3:.6f} s&quot;)
    print(f&quot;- 遮蔽时间段: {interval_3}&quot;)

if __name__ == &apos;__main__&apos;:
    solve_q4()
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;问题五的模型代码&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;import time
import numpy as np
from q1 import para_start_end, shielding_para, shielding_time, sum_of_shielding_times, uav_coord, grenade_coord, GRENADE_MIN_INTERVAL, shielding_reward
from scipy.optimize import minimize

from lbas_opt import LBAS
from utils import total_interval_sum

seed=int(time.time())

# 5 架无人机的位置信息分别为 FY1(17800,0,1800)、FY2(12000,1400,1400)、FY3(6000,−3000,700)、FY4(11000,2000,1800)、FY5(13000,−2000,1300)。
F1 = np.array([17800, 0, 1800])
F2 = np.array([12000, 1400, 1400])
F3 = np.array([6000, -3000, 700])
F4 = np.array([11000, 2000, 1800])
F5 = np.array([13000, -2000, 1300])

# 3 枚导弹 M1、M2、M3分别位于 (20000,0,2000)、(19000,600,2100)、(18000,−600,1900)；
M1 = np.array([20000, 0, 2000])
M2 = np.array([19000, 600, 2100])
M3 = np.array([18000, -600, 1900])
def m_name(m):
    if m[2] == 2000:
        return &quot;M1&quot;
    elif m[2] == 2100:
        return &quot;M2&quot;
    elif m[2] == 1900:
        return &quot;M3&quot;
    else:
        raise ValueError

def solve_q5_1f3m_d(Fi, M4g1, M4g2, M4g3, x0=None, method=&apos;lbas&apos;):
    &quot;&quot;&quot;
    解决问题5的子问题 - 一无人机、三烟雾弹、三导弹情况
    需要一个无人机使用固定的角度和速度，投放三枚烟雾弹，分别屏蔽三个导弹
    在目标函数中，每个没找到自己导弹的烟雾弹都应该受到惩罚。
    M4gi: Missile for grenade i
    &quot;&quot;&quot;
    # 定义目标函数
    def fitness(params):
        azimuth, speed, lc1, fs1, dlc2, fs2, dlc3, fs3 = params
        lc2 = lc1 + GRENADE_MIN_INTERVAL + dlc2  # 至少间隔一秒
        lc3 = lc2 + GRENADE_MIN_INTERVAL + dlc3
        time_g1 = shielding_time(Fi, M4g1, azimuth, speed, lc1, fs1)
        time_g2 = shielding_time(Fi, M4g2, azimuth, speed, lc2, fs2)
        time_g3 = shielding_time(Fi, M4g3, azimuth, speed, lc3, fs3)
        return time_g1, time_g2, time_g3

    def objective(params):
        azimuth, speed, lc1, fs1, dlc2, fs2, dlc3, fs3 = params
        lc2 = lc1 + GRENADE_MIN_INTERVAL + dlc2
        lc3 = lc2 + GRENADE_MIN_INTERVAL + dlc3
        shielding_reward_g1 = shielding_reward(Fi, M4g1, azimuth, speed, lc1, fs1)
        shielding_reward_g2 = shielding_reward(Fi, M4g2, azimuth, speed, lc2, fs2)
        shielding_reward_g3 = shielding_reward(Fi, M4g3, azimuth, speed, lc3, fs3)
        if shielding_reward_g1 &amp;lt; 0:
            shielding_reward_g1 *= 100
        if shielding_reward_g2 &amp;lt; 0:
            shielding_reward_g2 *= 100
        if shielding_reward_g3 &amp;lt; 0:
            shielding_reward_g3 *= 100
        return -(shielding_reward_g1 + shielding_reward_g2 + shielding_reward_g3)
    
    def objective_n(params):
        time_g1, time_g2, time_g3 = fitness(params)
        return -(time_g1 + time_g2 + time_g3)
    
    bounds = [
        (0, 2*np.pi + np.pi/6),  # 方位角
        (70, 140),  # 速度
        (0, 40),  # lc1
        (0, 18),  # fs1
        (0, 40),  # dlc2
        (0, 18),  # fs2
        (0, 40),  # dlc3
        (0, 18),  # fs3
    ]
    if method == &apos;lbas&apos;:
        lbas = LBAS(
            # 最优化参数
            obj_func=objective_n,
            pop_size=30,
            bounds=bounds,
            max_iter=300,
            seed=seed,
            init_x=x0,
            # 超参数
            P=0.5,
            d_eta=0.95,
            delta_eta=0.95,
            # 可视化
            history_per_iter=30,
        )
        best_solution, best_fitness, convergence = lbas.optimize()
    else:
        raise ValueError(f&quot;Unknown method: {method}&quot;)


    return best_solution, fitness(best_solution)

def get_q5_1f3m(Fi, M4g1, M4g2, M4g3, x0, method=&apos;lbas&apos;):
    print(f&quot;Fi: {Fi}&quot;)
    if x0:
        azimuth, speed, lc1, fs1, dlc2, fs2, dlc3, fs3 = x0
        lc2 = lc1 + GRENADE_MIN_INTERVAL + dlc2  # 至少间隔一秒
        lc3 = lc2 + GRENADE_MIN_INTERVAL + dlc3
        time_g1 = shielding_time(Fi, M4g1, azimuth, speed, lc1, fs1)
        time_g2 = shielding_time(Fi, M4g2, azimuth, speed, lc2, fs2)
        time_g3 = shielding_time(Fi, M4g3, azimuth, speed, lc3, fs3)
        print(f&quot;当前最优：{time_g1:.3f} s, {time_g2:.3f} s, {time_g3:.3f} s&quot;)
    best_solution, (time_m1, time_m2, time_m3) = solve_q5_1f3m_d(Fi, M4g1, M4g2, M4g3, x0, method)
    opt_azimuth, opt_speed, opt_lc1, opt_fs1, opt_dlc2, opt_fs2, opt_dlc3, opt_fs3 = best_solution

    # 整理各种参数
    opt_lc2 = opt_lc1 + GRENADE_MIN_INTERVAL + opt_dlc2
    opt_lc3 = opt_lc2 + GRENADE_MIN_INTERVAL + opt_dlc3
    lc1_point = uav_coord(Fi, opt_azimuth, opt_speed, opt_lc1)
    lc2_point = uav_coord(Fi, opt_azimuth, opt_speed, opt_lc2)
    lc3_point = uav_coord(Fi, opt_azimuth, opt_speed, opt_lc3)
    burst1_point = grenade_coord(Fi, opt_azimuth, opt_speed, opt_lc1, opt_fs1, opt_lc1 + opt_fs1)
    burst2_point = grenade_coord(Fi, opt_azimuth, opt_speed, opt_lc2, opt_fs2, opt_lc2 + opt_fs2)
    burst3_point = grenade_coord(Fi, opt_azimuth, opt_speed, opt_lc3, opt_fs3, opt_lc3 + opt_fs3)

    shield_g1m1 = shielding_time(Fi, M1, opt_azimuth, opt_speed, opt_lc1, opt_fs1)
    shield_g1m2 = shielding_time(Fi, M2, opt_azimuth, opt_speed, opt_lc1, opt_fs1)
    shield_g1m3 = shielding_time(Fi, M3, opt_azimuth, opt_speed, opt_lc1, opt_fs1)
    shield_g2m1 = shielding_time(Fi, M1, opt_azimuth, opt_speed, opt_lc2, opt_fs2)
    shield_g2m2 = shielding_time(Fi, M2, opt_azimuth, opt_speed, opt_lc2, opt_fs2)
    shield_g2m3 = shielding_time(Fi, M3, opt_azimuth, opt_speed, opt_lc2, opt_fs2)
    shield_g3m1 = shielding_time(Fi, M1, opt_azimuth, opt_speed, opt_lc3, opt_fs3)
    shield_g3m2 = shielding_time(Fi, M2, opt_azimuth, opt_speed, opt_lc3, opt_fs3)
    shield_g3m3 = shielding_time(Fi, M3, opt_azimuth, opt_speed, opt_lc3, opt_fs3)


    # 结果
    print(&quot;问题5-1f3m优化结果:&quot;)
    print(f&quot;最优飞行方向: {np.degrees(opt_azimuth):.6f}°&quot;)
    print(f&quot;最优飞行速度: {opt_speed:.6f} m/s&quot;)
    print(f&quot;各导弹被遮蔽时间: {time_m1:.3f} s, {time_m2:.3f} s, {time_m3:.3f} s&quot;)

    print(&quot;烟雾弹1&quot;)
    print(f&quot;- 投放, 引信: {opt_lc1:.6f} s, {opt_fs1:.6f} s&quot;)
    print(f&quot;- 投放点坐标: ({lc1_point[0]:.2f}, {lc1_point[1]:.2f}, {lc1_point[2]:.2f}) m&quot;)
    print(f&quot;- 起爆点坐标: ({burst1_point[0]:.2f}, {burst1_point[1]:.2f}, {burst1_point[2]:.2f}) m&quot;)
    print(f&quot;- 独立遮蔽时间: {shield_g1m1:.3f} s, {shield_g1m2:.3f} s, {shield_g1m3:.3f} s&quot;)
    
    print(&quot;烟雾弹2&quot;)
    print(f&quot;- 投放, 引信: {opt_lc2:.6f} s, {opt_fs2:.6f} s&quot;)
    print(f&quot;- 投放点坐标: ({lc2_point[0]:.2f}, {lc2_point[1]:.2f}, {lc2_point[2]:.2f}) m&quot;)
    print(f&quot;- 起爆点坐标: ({burst2_point[0]:.2f}, {burst2_point[1]:.2f}, {burst2_point[2]:.2f}) m&quot;)
    print(f&quot;- 独立遮蔽时间: {shield_g2m1:.3f} s, {shield_g2m2:.3f} s, {shield_g2m3:.3f} s&quot;)
    
    print(&quot;烟雾弹3&quot;)
    print(f&quot;- 投放, 引信: {opt_lc3:.6f} s, {opt_fs3:.6f} s&quot;)
    print(f&quot;- 投放点坐标: ({lc3_point[0]:.2f}, {lc3_point[1]:.2f}, {lc3_point[2]:.2f}) m&quot;)
    print(f&quot;- 起爆点坐标: ({burst3_point[0]:.2f}, {burst3_point[1]:.2f}, {burst3_point[2]:.2f}) m&quot;)
    print(f&quot;- 独立遮蔽时间: {shield_g3m1:.3f} s, {shield_g3m2:.3f} s, {shield_g3m3:.3f} s&quot;)
    
    print(&quot;数据观测参数&quot;)
    print(f&quot;&quot;&quot;
        azimuth = [{opt_azimuth}]
        speed = [{opt_speed}]
        grenades = [[({opt_lc1}, {opt_fs1}), ({opt_lc2}, {opt_fs2}), ({opt_lc3}, {opt_fs3})]]&quot;&quot;&quot;)
    print()
    print(&quot;迭代参数&quot;)
    print(f&quot;{list(best_solution)}&quot;)

f2init = [3.5798407960319683, 139.95150489308995, 10.239036512780858, 7.79331074493688, 1.8456855553958122, 9.80941768962815, 5.145235179158354, 10.069753943152957]

f3init = [1.4879409512940358, 98.29814399927496, 26.799930909799667, 2.026032510520734, 0.26826783438157636, 2.9253834084706805, 3.3739514012844323, 0.7678129206747897]

f4init = [3.743304686999795, 140.0, 8.151067146947158, 13.087409075180682, 1.135142049497204, 14.085924273751292, 3.0130271555181456, 14.083224883703947]

f5init = [2.3573542031237005, 140.0, 12.167079798942705, 4.415470449657926, 1.1171071707140803, 6.165828622284752, 3.58671333288304, 4.8576695724368175]

def solve_q5_5f3m_enumeratly(method=&apos;lbas&apos;):
    # get_q5_1f3m(F1, [np.deg2rad(366.312771), 122.199967, 0, 0, 0, 0, 0, 0])

    prev = [
        (&apos;F2&apos;, F2, M2, M1, M3, f2init),
        (&apos;F3&apos;, F3, M3, M1, M2, f3init),
        (&apos;F4&apos;, F4, M2, M1, M3, f4init),
        (&apos;F5&apos;, F5, M3, M1, M2, f5init),
    ]
    for name, f, m1, m2, m3, x0 in prev:
        print(&apos;\n\n&apos;)
        print(f&quot;{name:=^30}&quot;)
        get_q5_1f3m(f, m1, m2, m3, x0, method=method)
        

def solve_q5_a3m():
    &quot;&quot;&quot;
    协同所有参数同时进行高维优化
    &quot;&quot;&quot;
    prevs = [
        (&apos;F2&apos;, F2, M2, M1, M3, f2init),
        (&apos;F3&apos;, F3, M3, M1, M2, f3init),
        (&apos;F4&apos;, F4, M2, M1, M3, f4init),
        (&apos;F5&apos;, F5, M3, M1, M2, f5init),
    ]
    x0 = [
        *f2init,
        *f3init,
        *f4init,
        *f5init,
    ]
    def objective_a3m(params):
        (
            f2a, f2v, f2lc1, f2fs1, f2dlc2, f2fs2, f2dlc3, f2fs3,
            f3a, f3v, f3lc1, f3fs1, f3dlc2, f3fs2, f3dlc3, f3fs3,
            f4a, f4v, f4lc1, f4fs1, f4dlc2, f4fs2, f4dlc3, f4fs3,
            f5a, f5v, f5lc1, f5fs1, f5dlc2, f5fs2, f5dlc3, f5fs3,
        ) = params
        params_fi = {
            &quot;F2&quot;: (f2a, f2v, f2lc1, f2fs1, f2dlc2, f2fs2, f2dlc3, f2fs3),
            &quot;F3&quot;: (f3a, f3v, f3lc1, f3fs1, f3dlc2, f3fs2, f3dlc3, f3fs3),
            &quot;F4&quot;: (f4a, f4v, f4lc1, f4fs1, f4dlc2, f4fs2, f4dlc3, f4fs3),
            &quot;F5&quot;: (f5a, f5v, f5lc1, f5fs1, f5dlc2, f5fs2, f5dlc3, f5fs3),
        }
        intervals_fi = {
            &quot;M1&quot;: [],
            &quot;M2&quot;: [],
            &quot;M3&quot;: [],
        }
        total_fi = {
            &quot;M1&quot;: 0.0,
            &quot;M2&quot;: 0.0,
            &quot;M3&quot;: 0.0,
        }
        for name, f, m4g1, m4g2, m4g3, x0 in prevs:
            params_i = params_fi[name]
            a, v, lc1, fs1, dlc2, fs2, dlc3, fs3 = params_i
            lc2 = lc1 + GRENADE_MIN_INTERVAL + dlc2
            lc3 = lc2 + GRENADE_MIN_INTERVAL + dlc3
            m4g1_name = m_name(m4g1)
            m4g2_name = m_name(m4g2)
            m4g3_name = m_name(m4g3)
            intervals_fi[m4g1_name].append(para_start_end(shielding_para(f, m4g1, a, v, lc1, fs1)))
            intervals_fi[m4g2_name].append(para_start_end(shielding_para(f, m4g2, a, v, lc2, fs2)))
            intervals_fi[m4g3_name].append(para_start_end(shielding_para(f, m4g3, a, v, lc3, fs3)))
        for fi, intervals in intervals_fi.items():
            total_fi[fi] = total_interval_sum(intervals)
        
        return total_fi
    
    def objective_a3m_fitness(params):
        total_fi = objective_a3m(params)
        return -sum(total_fi.values())
    
    bounds = [
        (0, 5 * np.pi / 2), (70, 140), (0, 60), (0, 60), (0, 60), (0, 60), (0, 60), (0, 60),
        (0, 5 * np.pi / 2), (70, 140), (0, 60), (0, 60), (0, 60), (0, 60), (0, 60), (0, 60),
        (0, 5 * np.pi / 2), (70, 140), (0, 60), (0, 60), (0, 60), (0, 60), (0, 60), (0, 60),
        (0, 5 * np.pi / 2), (70, 140), (0, 60), (0, 60), (0, 60), (0, 60), (0, 60), (0, 60),
    ]

    # res = minimize(objective_a3m, init_x0, method=&apos;L-BFGS-B&apos;, bounds=bounds)
    lbas = LBAS(
        # 最优化参数
        obj_func=objective_a3m_fitness,
        pop_size=20,
        bounds=bounds,
        max_iter=300,
        seed=seed,
        init_x=x0,
        # 超参数
        P=0.5,
        d_eta=0.98,
        delta_eta=0.98,
        
        d0_init_ratio=1e-2,
        delta0_init_ratio=1e-2,

        # 可视化
        history_per_iter=30,
        tqdm=True,
    )
    best_solution, best_fitness, convergence = lbas.optimize()
    print(&quot;最佳结果&quot;, objective_a3m(best_solution))
    (
        f2a, f2v, f2lc1, f2fs1, f2dlc2, f2fs2, f2dlc3, f2fs3,
        f3a, f3v, f3lc1, f3fs1, f3dlc2, f3fs2, f3dlc3, f3fs3,
        f4a, f4v, f4lc1, f4fs1, f4dlc2, f4fs2, f4dlc3, f4fs3,
        f5a, f5v, f5lc1, f5fs1, f5dlc2, f5fs2, f5dlc3, f5fs3,
    ) = best_solution
    for name, paras in [(&apos;F2&apos;, (f2a, f2v, f2lc1, f2fs1, f2dlc2, f2fs2, f2dlc3, f2fs3)),
                        (&apos;F3&apos;, (f3a, f3v, f3lc1, f3fs1, f3dlc2, f3fs2, f3dlc3, f3fs3)),
                        (&apos;F4&apos;, (f4a, f4v, f4lc1, f4fs1, f4dlc2, f4fs2, f4dlc3, f4fs3)),
                        (&apos;F5&apos;, (f5a, f5v, f5lc1, f5fs1, f5dlc2, f5fs2, f5dlc3, f5fs3))]:
        print(name)
        a, v, lc1, fs1, dlc2, fs2, dlc3, fs3 = paras
        lc2 = lc1 + GRENADE_MIN_INTERVAL + dlc2
        lc3 = lc2 + GRENADE_MIN_INTERVAL + dlc3

        _, F, M4g1, M4g2, M4g3, _ = next(prev for prev in prevs if prev[0] == name)
        
        # 计算遮蔽参数
        shield1 = shielding_para(F, M4g1, a, v, lc1, fs1)
        shield2 = shielding_para(F, M4g2, a, v, lc2, fs2)
        shield3 = shielding_para(F, M4g3, a, v, lc3, fs3)
        t_shield = sum_of_shielding_times(shield1, shield2, shield3)
        print(f&quot;总时间：{t_shield}&quot;)
        
        # 计算投放点和起爆点坐标
        lc1_point = uav_coord(F, a, v, lc1)
        burst1_point = grenade_coord(F, a, v, lc1, fs1, lc1 + fs1)
        lc2_point = uav_coord(F, a, v, lc2)
        burst2_point = grenade_coord(F, a, v, lc2, fs2, lc2 + fs2)
        lc3_point = uav_coord(F, a, v, lc3)
        burst3_point = grenade_coord(F, a, v, lc3, fs3, lc3 + fs3)
        
        # 计算独立遮蔽时间
        shield_single1 = shielding_time(F, M4g1, a, v, lc1, fs1)
        shield_single2 = shielding_time(F, M4g2, a, v, lc2, fs2)
        shield_single3 = shielding_time(F, M4g3, a, v, lc3, fs3)
        interval_1 = para_start_end(shielding_para(F, M4g1, a, v, lc1, fs1))
        interval_2 = para_start_end(shielding_para(F, M4g2, a, v, lc2, fs2))
        interval_3 = para_start_end(shielding_para(F, M4g3, a, v, lc3, fs3))
        
        print(f&quot;烟雾弹1&quot;)
        print(f&quot;- 投放, 引信: {lc1:.6f} s, {fs1:.6f} s&quot;)
        print(f&quot;- 投放点坐标: ({lc1_point[0]:.2f}, {lc1_point[1]:.2f}, {lc1_point[2]:.2f}) m&quot;)
        print(f&quot;- 起爆点坐标: ({burst1_point[0]:.2f}, {burst1_point[1]:.2f}, {burst1_point[2]:.2f}) m&quot;)
        print(f&quot;- 独立遮蔽时间: {shield_single1:.6f} s&quot;)
        print(f&quot;- 遮蔽时间段: {interval_1}&quot;)
        print()
        
        print(f&quot;烟雾弹2&quot;)
        print(f&quot;- 投放, 引信: {lc2:.6f} s, {fs2:.6f} s&quot;)
        print(f&quot;- 投放点坐标: ({lc2_point[0]:.2f}, {lc2_point[1]:.2f}, {lc2_point[2]:.2f}) m&quot;)
        print(f&quot;- 起爆点坐标: ({burst2_point[0]:.2f}, {burst2_point[1]:.2f}, {burst2_point[2]:.2f}) m&quot;)
        print(f&quot;- 独立遮蔽时间: {shield_single2:.6f} s&quot;)
        print(f&quot;- 遮蔽时间段: {interval_2}&quot;)
        print()
        
        print(f&quot;烟雾弹3&quot;)
        print(f&quot;- 投放, 引信: {lc3:.6f} s, {fs3:.6f} s&quot;)
        print(f&quot;- 投放点坐标: ({lc3_point[0]:.2f}, {lc3_point[1]:.2f}, {lc3_point[2]:.2f}) m&quot;)
        print(f&quot;- 起爆点坐标: ({burst3_point[0]:.2f}, {burst3_point[1]:.2f}, {burst3_point[2]:.2f}) m&quot;)
        print(f&quot;- 独立遮蔽时间: {shield_single3:.6f} s&quot;)
        print(f&quot;- 遮蔽时间段: {interval_3}&quot;)
        print()

        print(f&quot;{name} 完整参数: {list(paras)}&quot;)




if __name__ == &apos;__main__&apos;:
    # solve_q5_5f3m_enumeratly(&apos;lbas&apos;)

    solve_q5_a3m()
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;重要工具函数代码&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;from typing import Callable, Tuple


def number_bfs(max_depth):
    it = 1.0
    depth = 0
    while depth &amp;lt; max_depth:
        base = it / 2
        while True:
            yield base
            base += it
            if base &amp;gt;= 1:
                break
        it /= 2
        depth += 1


def __bool_func_singularity_single(func, interval, tol=1e-6):
    &quot;&quot;&quot;
    找到布尔函数在区间内的唯一突变点，二分法
    函数区间的左右必定不同，且必定存在一个突变点
    &quot;&quot;&quot;
    a, b = interval
    left_val = func(a)
    while b - a &amp;gt; tol:
        mid = (a + b) / 2.0
        if func(mid) == left_val:
            a = mid
        else:
            b = mid
    return (a + b) / 2.0

def bool_func_singularity(func: Callable[[float], bool], interval: tuple[float, ...], max_depth=6, tol=1e-6) -&amp;gt; Tuple[bool, int, list[float], Tuple[float, ...]]:
    &quot;&quot;&quot;
    找到布尔函数在区间内的突变点
    二分搜索。忽略1/64 interval的区间。最多检查2个突变点
    检查左右阈限
        如果相同：
            BFS地检查子区间位置，直至找到一个不同的值
            如果找到：
                记录位置
                分别对左侧和右侧的变异点二分搜索
            如果未找到：
                返回无突变点
        如果不同：
            二分搜索突变点
    
    返回:
    函数区间左侧值，突变点个数，突变点位置列表，区间
    &quot;&quot;&quot;
    left, right = interval
    leftval = func(left)
    rightval = func(right)

    if leftval == rightval:
        for ratio in number_bfs(max_depth):
            exploring_point = left + ratio * (right - left)
            if func(exploring_point) != leftval:  # 两个突变点
                return leftval, 2, [
                    __bool_func_singularity_single(func, (left, exploring_point), tol),
                    __bool_func_singularity_single(func, (exploring_point, right), tol),
                ], interval
        return leftval, 0, [], interval  # 没有突变点
    else:
        return leftval, 1, [__bool_func_singularity_single(func, interval, tol)], interval  # 一个突变点

def calc_total_true_length(leftval, n_point, points, interval):
    &quot;&quot;&quot;
    计算布尔函数在区间内为True的总长度
    &quot;&quot;&quot;
    left, right = interval
    interval_len = right - left

    if n_point == 0:
        return leftval * interval_len
    elif n_point == 1:
        if leftval:
            return points[0] - left
        else:
            return right - points[0]
    else:
        center = points[1] - points[0]
        if not leftval:
            return center
        else:
            return interval_len - center

def merge_intervals(intervals):
    if not intervals:
        return []
    
    intervals_sorted = sorted(intervals, key=lambda x: x[0])
    merged = []
    current_start, current_end = intervals_sorted[0]
    
    for interval in intervals_sorted[1:]:
        if interval[0] &amp;lt;= current_end:
            current_end = max(current_end, interval[1])
        else:
            merged.append((current_start, current_end))
            current_start, current_end = interval
    merged.append((current_start, current_end))
    
    return merged

def total_interval_sum(intervals):
    merged = merge_intervals(intervals)
    total = 0.0
    for start, end in merged:
        total += end - start
    return total

if __name__ == &apos;__main__&apos;:
    ret = bool_func_singularity(lambda x: abs(x)&amp;lt;3, (-20, 20), tol=1e-10)
    print(ret)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;可视化验证代码&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;import numpy as np
from numpy.typing import NDArray
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from mpl_toolkits.mplot3d import Axes3D
from q1 import missile_coord, shielding_time, uav_coord, grenade_coord, smoke_coord, TARGET_CHECKPOINTS
plt.rcParams[&apos;font.sans-serif&apos;] = [&apos;SimHei&apos;]
plt.rcParams[&apos;axes.unicode_minus&apos;] = False


# 常量定义
DECOY_POSITION = np.array([0, 0, 0])  # 假目标位置
TARGET_POSITION = np.array([0, 200, 0]) 
SMOKE_RADIUS = 10  # 烟雾云半径(m)

# 5 架无人机的位置信息分别为 FY1(17800,0,1800)、FY2(12000,1400,1400)、FY3(6000,−3000,700)、FY4(11000,2000,1800)、FY5(13000,−2000,1300)。
F1 = np.array([17800, 0, 1800])
F2 = np.array([12000, 1400, 1400])
F3 = np.array([6000, -3000, 700])
F4 = np.array([11000, 2000, 1800])
F5 = np.array([13000, -2000, 1300])

# 3 枚导弹 M1、M2、M3分别位于 (20000,0,2000)、(19000,600,2100)、(18000,−600,1900)；
M1 = np.array([20000, 0, 2000])
M2 = np.array([19000, 600, 2100])
M3 = np.array([18000, -600, 1900])

M: list[NDArray] = []  # 导弹初始位置
FA: list[NDArray] = []  # 无人机初始位置
azimuth: list[float] = []  # 方位角
speed: list[float] = []  # 无人机速度
grenades: list[list[tuple[float, float]]] = []  # 烟雾弹投下和引信
missile_prev = 0
uav_prev = 0
grenade_prev = 0
view_box1 = 40
view_box2 = 500
follow_uav = False

prev = &apos;q5-1m3f-auto&apos;
match prev:
    case &apos;q1&apos;:  # 问题一预设
        M = [M1]
        FA = [F1]
        azimuth = [np.arctan2(DECOY_POSITION[1] - FA[0][1], DECOY_POSITION[0] - FA[0][0])]
        speed = [120]
        grenades = [[(1.5, 3.6)]]
    case &apos;q2opt&apos;:  # 问题二优化
        M = [M1]
        FA = [F1]
        azimuth = [np.deg2rad(3.8191)]
        speed = [105.0614]
        grenades = [[(12.8644, 8.3575)]]
    case &apos;q3opt&apos;:  # 问题三优化
        M = [M1]
        FA = [F1]
        azimuth = [np.deg2rad(366.312771)]
        speed = [122.199967]
        grenades = [[(0, 0), (1, 0), (2, 0)]]
        grenade_prev = 1
        follow_uav = True
    case &apos;q4opt&apos;:  # 问题四优化
        M = [M1]
        FA = [F1, F2, F3]
        azimuth = [
            0.0872,
            4.7623,
            1.3523,
        ]
        speed = [
            124.1693,
            113.7334,
            117.6129,
        ]
        grenades = [
            [( 0.9075, 0.1371)],
            [( 6.0254, 6.0193)],
            [(24.7345, 2.1004)],
        ]
    case &apos;q5-1m3f-f1&apos;:  # 问题五子问题 - 关于离群的F1
        M = [M1, M2, M3]
        FA = [F1]
        azimuth = [np.deg2rad(110)]
        speed = [140]
        grenades = [[(0, 0), (2.220374, 1.665190), (5.298336, 2.009814)]]
        follow_uav = True
    case &apos;q5-1m3f-auto&apos;:  # 问题五子问题 - q5生成的参数预览
        M = [M1, M2, M3]
        FA = [F2]
        azimuth = [3.5798407960319683]
        speed = [139.95150489308995]
        grenades = [[(10.239036512780858, 7.79331074493688), (13.08472206817667, 9.80941768962815), (19.229957247335026, 10.069753943152957)]]
        
        follow_uav = True
        missile_prev = 2
    case &apos;q5-1m3f-all&apos;:  # 问题五 - 看全局
        M = [M1, M2, M3]
        FA = [F1, F2, F3, F4, F5]
        azimuth = [0,0,0,0,0]
        speed = [0,0,0,0,0]
        grenades = [[(0,0)],[(0,0)],[(0,0)],[(0,0)],[(0,0)]]
        follow_uav = True

if len(M) == 0:
    print(&quot;未选中预设&quot;)
    exit()

# 创建图形和3D轴
def set_view(ax: Axes3D):
    ax.set_xlabel(&apos;X (m)&apos;)
    ax.set_ylabel(&apos;Y (m)&apos;)
    ax.set_zlabel(&apos;Z (m)&apos;)
    ax.plot([DECOY_POSITION[0]], [DECOY_POSITION[1]], [DECOY_POSITION[2]], &apos;kx&apos;, markersize=10, label=&apos;假目标&apos;)
    ax.plot([TARGET_POSITION[0]], [TARGET_POSITION[1]], [TARGET_POSITION[2]], &apos;rx&apos;, markersize=10, label=&apos;真目标&apos;)
    
    missile_traj = [ax.plot([], [], [], &apos;r-&apos;, label=&apos;导弹轨迹&apos;)[0] for _ in range(len(M))]
    missile_point = ax.plot([], [], [], &apos;ro&apos;, markersize=3, label=&apos;导弹&apos;)[0]
    uav_traj = [ax.plot([], [], [], &apos;b-&apos;, label=&apos;无人机轨迹&apos;)[0] for _ in range(len(FA))]
    uav_point = ax.plot([], [], [], &apos;bo&apos;, markersize=3, label=&apos;无人机&apos;)[0]
    grenade_traj = [[ax.plot([], [], [], &apos;k-&apos;, label=&apos;烟雾弹轨迹&apos;)[0] for _ in range(len(grenades[i]))] for i in range(len(FA))]
    grenade_point = ax.plot([], [], [], &apos;ko&apos;, markersize=3, label=&apos;烟雾弹&apos;)[0]
    viewline = [ax.plot([], [], [], &apos;g:&apos;, label=&apos;导弹探测线&apos;)[0] for _ in range(len(M))]
    smoke_spheres = []

    return {
        &apos;missile_traj&apos;: missile_traj,  # 导弹轨迹，Artist: missile[i] 表示第i个导弹的轨迹
        &apos;missile_point&apos;: missile_point,  # 导弹，Artist: missile_point 表示所有导弹的位置
        &apos;uav_traj&apos;: uav_traj,  # 无人机轨迹，Artist: uav_traj[i] 表示第i个无人机的轨迹
        &apos;uav_point&apos;: uav_point,  # 无人机，Artist: uav_point 表示所有无人机的位置
        &apos;grenade_traj&apos;: grenade_traj,  # 烟雾弹轨迹，Artist: grenade_traj[i][j] 表示第i个无人机的第j个烟雾弹的轨迹
        &apos;grenade_point&apos;: grenade_point,  # 烟雾弹，Artist: grenade_point 表示所有烟雾弹的位置
        &apos;viewline&apos;: viewline,  # 导弹探测线，Artist: viewline[i] 表示第i个导弹的探测线
        &apos;smoke_spheres&apos;: smoke_spheres,  # 烟雾云，Artist: smoke_spheres[i] 表示第i个烟雾云
    }

fig = plt.figure(figsize=(16, 8))
ax1 = fig.add_subplot(121, projection=&apos;3d&apos;)
ax2 = fig.add_subplot(122, projection=&apos;3d&apos;)
ax1.set_title(&apos;导弹锁定观察真目标/导弹重合烟雾即遮挡&apos;)
ax2.set_title(&apos;烟雾弹视角&apos;)
axes = [ax1, ax2]
axobjslst = [set_view(ax) for ax in axes]  # type: ignore

def update_view(ax: Axes3D, objs, data):
    objs[&apos;missile_point&apos;]   .set_data(data[&apos;missile_point&apos;][0], data[&apos;missile_point&apos;][1])
    objs[&apos;missile_point&apos;]   .set_3d_properties(data[&apos;missile_point&apos;][2])
    objs[&apos;uav_point&apos;]       .set_data(data[&apos;uav_point&apos;][0], data[&apos;uav_point&apos;][1])
    objs[&apos;uav_point&apos;]       .set_3d_properties(data[&apos;uav_point&apos;][2])
    objs[&apos;grenade_point&apos;]   .set_data(data[&apos;grenade_point&apos;][0], data[&apos;grenade_point&apos;][1])
    objs[&apos;grenade_point&apos;]   .set_3d_properties(data[&apos;grenade_point&apos;][2])
    for i in range(len(M)):
        objs[&apos;missile_traj&apos;][i]  .set_data(data[&apos;missile_traj&apos;][i][0], data[&apos;missile_traj&apos;][i][1])
        objs[&apos;missile_traj&apos;][i]  .set_3d_properties(data[&apos;missile_traj&apos;][i][2])
        objs[&apos;viewline&apos;][i]      .set_data(data[&apos;viewline&apos;][i][0], data[&apos;viewline&apos;][i][1])
        objs[&apos;viewline&apos;][i]      .set_3d_properties(data[&apos;viewline&apos;][i][2])
    for i in range(len(FA)):
        objs[&apos;uav_traj&apos;][i]      .set_data(data[&apos;uav_traj&apos;][i][0], data[&apos;uav_traj&apos;][i][1])
        objs[&apos;uav_traj&apos;][i]      .set_3d_properties(data[&apos;uav_traj&apos;][i][2])
    for i in range(len(FA)):
        for j in range(len(grenades[i])):
            objs[&apos;grenade_traj&apos;][i][j]  .set_data(data[&apos;grenade_traj&apos;][i][j][0], data[&apos;grenade_traj&apos;][i][j][1])
            objs[&apos;grenade_traj&apos;][i][j]  .set_3d_properties(data[&apos;grenade_traj&apos;][i][j][2])
    
    for sphere in objs[&apos;smoke_spheres&apos;]:
        sphere.remove()
    objs[&apos;smoke_spheres&apos;].clear()
    for sphere_pos in data[&apos;smoke_spheres&apos;]:
        # sphere = ax.plot([sphere_pos[0]], [sphere_pos[1]], [sphere_pos[2]], &apos;go&apos;, markersize=20, alpha=0.5)[0]
        u = np.linspace(0, 2 * np.pi, 10)
        v = np.linspace(0, np.pi, 10)
        x = SMOKE_RADIUS * np.outer(np.cos(u), np.sin(v)) + sphere_pos[0]
        y = SMOKE_RADIUS * np.outer(np.sin(u), np.sin(v)) + sphere_pos[1]
        z = SMOKE_RADIUS * np.outer(np.ones(np.size(u)), np.cos(v)) + sphere_pos[2]
        sphere = ax.plot_surface(x, y, z, color=&apos;gray&apos;, alpha=0.7)
        objs[&apos;smoke_spheres&apos;].append(sphere)


# 轨迹历史存储
missile_history = [[[], [], []] for _ in range(len(M))]
uav_history = [[[], [], []] for _ in range(len(FA))]
grenade_history = [[[[], [], []] for _ in range(len(grenades[i]))] for i in range(len(FA))]
def t_append(dest, src):
    for i in range(len(dest)):
        dest[i].append(src[i])

# 动画更新函数
def update(frame):
    t = t_ani_start + frame * t_ani_tpf
    smoke_spheres = []

    # 更新导弹位置
    viewlines_data = []
    missile_points = ([], [], [])
    for i in range(len(M)):
        # 更新导弹位置
        missile_pos = missile_coord(M[i], t)
        t_append(missile_history[i], missile_pos)
        t_append(missile_points, missile_pos)
        # 更新导弹观察线
        viewlines_data.append([[missile_pos[d], TARGET_POSITION[d]] for d in (0, 1, 2)])
    
    # 更新无人机位置
    uav_points = ([], [], [])
    for i in range(len(FA)):
        uav_pos = uav_coord(FA[i], azimuth[i], speed[i], t)
        t_append(uav_history[i], uav_pos)
        t_append(uav_points, uav_pos)
    
    # 更新烟雾弹/烟雾位置
    grenade_points = ([], [], [])
    for i in range(len(FA)):
        for j in range(len(grenades[i])):
            t_L, t_F = grenades[i][j]
            t_B = t_L + t_F
            if t &amp;gt;= t_L and t &amp;lt; t_B:
                # 烟雾弹飞行阶段
                grenade_pos = grenade_coord(FA[i], azimuth[i], speed[i], t_L, t_F, t)
                t_append(grenade_history[i][j], grenade_pos)
                t_append(grenade_points, grenade_pos)
            elif t &amp;gt;= t_B and t &amp;lt;= t_B + 20:
                # 烟雾扩散阶段
                smoke_pos = smoke_coord(FA[i], azimuth[i], speed[i], t_L, t_F, t)
                t_append(grenade_history[i][j], smoke_pos)
                t_append(grenade_points, smoke_pos)
                smoke_spheres.append(smoke_pos)

    
    data = {
        &apos;missile_traj&apos;: missile_history,
        &apos;missile_point&apos;: missile_points,
        &apos;viewline&apos;: viewlines_data,
        &apos;uav_traj&apos;: uav_history,
        &apos;uav_point&apos;: uav_points,
        &apos;grenade_traj&apos;: grenade_history,
        &apos;grenade_point&apos;: grenade_points,
        &apos;smoke_spheres&apos;: smoke_spheres,
    }
    # 更新数据
    [update_view(ax, axobjs, data) for ax, axobjs in zip(axes, axobjslst)]  # type: ignore

    # 更新坐标轴并强制重绘

    # ax1视图：跟随导弹，总是朝向真目标
    first_missile = (missile_points[0][missile_prev], missile_points[1][missile_prev], missile_points[2][missile_prev])
    ax1_viewpos = first_missile
    ax1.set_xlim([ax1_viewpos[0] - view_box1, ax1_viewpos[0] + view_box1])  # type: ignore
    ax1.set_ylim([ax1_viewpos[1] - view_box1, ax1_viewpos[1] + view_box1])  # type: ignore
    ax1.set_zlim([ax1_viewpos[2] - view_box1, ax1_viewpos[2] + view_box1])  # type: ignore
    
    view_vector = ax1_viewpos - TARGET_POSITION
    azimuth_angle = np.arctan2(view_vector[1], view_vector[0])
    distance_xy = np.sqrt(view_vector[0]**2 + view_vector[1]**2)
    elevation_angle = np.arctan2(view_vector[2], distance_xy)
    ax1.view_init(  # type: ignore
        elev=np.degrees(elevation_angle)-1.4,
        azim=np.degrees(azimuth_angle)
    )
    ax1.figure.canvas.draw()  # type: ignore

    # ax2视图：跟随烟雾弹
    follow_uav_pos = (uav_points[0][uav_prev], uav_points[1][uav_prev], uav_points[2][uav_prev])
    follow_grenade_pos = (grenade_points[0][grenade_prev], grenade_points[1][grenade_prev], grenade_points[2][grenade_prev]) if grenade_points[0] else None
    ax2_viewpos = (
        follow_uav_pos if t &amp;lt; grenades[0][0][0] else
        (follow_grenade_pos or follow_uav_pos) if t &amp;lt; sum(grenades[0][0]) + 20 else  # type: ignore
        follow_uav_pos)
    if follow_uav:
        ax2_viewpos = follow_uav_pos
    ax2.set_xlim([ax2_viewpos[0] - view_box2, ax2_viewpos[0] + view_box2])  # type: ignore
    ax2.set_ylim([ax2_viewpos[1] - view_box2, ax2_viewpos[1] + view_box2])  # type: ignore
    ax2.set_zlim([ax2_viewpos[2] - view_box2, ax2_viewpos[2] + view_box2])  # type: ignore
    ax2.figure.canvas.draw()  # type: ignore

    objs = []
    def append_artists(ax_objs):
        objs.append(ax_objs[&apos;missile_point&apos;])
        objs.append(ax_objs[&apos;uav_point&apos;])
        objs.append(ax_objs[&apos;grenade_point&apos;])
        objs.extend(ax_objs[&apos;missile_traj&apos;])
        objs.extend(ax_objs[&apos;uav_traj&apos;])
        [objs.extend(ax_objs[&apos;grenade_traj&apos;][i]) for i in range(len(FA))]
        objs.extend(ax_objs[&apos;viewline&apos;])
        objs.extend(ax_objs[&apos;smoke_spheres&apos;])
    
    [append_artists(axo) for axo in axobjslst]


    return objs

# 创建动画
t_ani_start = 0
t_ani_tpf = 0.1
t_ani_end = 60
ani_frames = int((t_ani_end - t_ani_start) / t_ani_tpf)
ani = FuncAnimation(fig, update, frames=ani_frames, interval=50, blit=True)
ax1.legend()

plt.show()
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>新建文件夹 (1)</title><link>https://blog.emumu.xyz/posts/2026-01-02-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2026-01-02-00/</guid><description>请输入文本</description><pubDate>Fri, 02 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;那天有个同学跟我说，诶你能不能弄一个智慧树在线刷课的脚本，我说了一堆有的没的，总归是没做。&lt;/p&gt;
&lt;p&gt;他也算是会电脑的，至少不像别人压缩解压都得教。显然他很清楚写一个油猴脚本可以自动刷课、切集数什么的，平时也会用ps什么的。他本来是另一个屋的，因为一些事情换过来，隐约觉得他其实原来那屋的技术担当。&lt;/p&gt;
&lt;p&gt;我跟他说的大概意思是，智慧树非常大牌，既然我找了一圈（甚至有只隔了不到半年的脚本）都不能用，大概率是他们在严查，我又翻了一下前端js，不出所料是minimize过的，又在那弹debugger，我也没啥心思破解了，说不定再走几步把我学习记录再给清了。。&lt;/p&gt;
&lt;p&gt;当时我正在推魔裁，对于玩着这种很休闲，完全可以暂停，点击量不高但也必须拿着鼠标的游戏，同时还有两个显示屏的我顺带去刷课简直就是享受。学习通需要额外点几下，不过我找到学习通能用的脚本了。&lt;/p&gt;
&lt;p&gt;在翻遍greasyfork找不到能用的脚本之后，我没有开发脚本的想法，直接去开始人力刷课。为什么我没立刻去开发脚本呢？边写边找出原因吧。&lt;/p&gt;
&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;It was laziness that inspired invention and promoted the progress of humanity[^1].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;[^1]: 凯利 FC. 懒惰的智慧[J]. 哈泼斯杂志, 1923(2).&lt;/p&gt;
&lt;p&gt;这句话在程序员里总是特别受用。他们有时候喜欢以懒惰为借口，花5小时的时间来制作一个可以在1分钟完成这件事的工具，而不愿意花费5分钟完成这件事。但就我个人而言，这只在程序员精力充沛，兴致勃勃的时候适用。如果我没什么精力，我就会退化成一个翻实验报告pdf都要别人帮的超绝普通人。&lt;/p&gt;
&lt;p&gt;但当我真的有兴致的时候，我其实很可能是个怪人。其一就是我喜欢写代码，这样一个在其他人头疼不已的东西在我却成了娱乐。当时的半年前(25年5月)我接触了javascript，正是学得热火朝天、接触前端高级特性:spoiler[、刷ai好感度]的时候。至少热爱这方面，我应该没落下风。&lt;/p&gt;
&lt;p&gt;其实要刷的课并不多。课程虽然路边但样子还是要装一装的。一共几十小时，不多也不少，刷几天确实能刷完。或许又是因为我已经做了一些类似的东西了。比如某dmm游的日常自动化什么的。这东西太简单了，我当时是这么想的。但对原理的理解让我知道反制办法其实很多。对于小游戏公司(甚至还是日本的)而言确实是没什么好破解的。智慧树不一样，智慧树是国内的在线课头部品牌，大学生出入频繁，自动化需求高发。在这样的地方挑战做一个自动化脚本定能让我更上十层楼。这是一个有着十足吸引力的挑战，而且毕竟前端与用户相争，和后端不同，用户是百分百能突破的。问题在于它可以给你使绊子，别出心裁地给你使出足以让你崩溃的绊子。但自夸地说，除了社交以外，只要是我能且想做到的，我从没畏难过。&lt;/p&gt;
&lt;p&gt;魔裁是我接触的第一个辩论文字avg，我非常喜欢，但这完全不重要:spoiler[粉红小狗可爱(๑＞ڡ＜)☆]。显然推游戏是我当时不愿意写脚本的最大阻碍，没有之一。写到这，我突然不理解当时有什么压力能让我拿着游戏不放，毕竟现在这会我刚刚放下复习期末的笔，码了会新项目然后继续扛着39度的烧躺在床上码新文章。我总是觉得什么都压不倒我，压力的感觉很是虚幻缥缈的。&lt;/p&gt;
&lt;p&gt;但往回看，我花了几乎一整个暑假去学vue学从头搭网站并搓了个五位数行数代码的项目，开学后立刻着手数模比赛，完成后倦怠几个月直到第一科期末发复习题。抛开一切主观感受，分析过去的所有时间和状态我在这篇文章上花的时间已经完全超过了我能尝试去开发智慧树刷课脚本的时间。我的结论是，我能在自由时间不去写代码而是打游戏，根本原因在于：&lt;/p&gt;
&lt;p&gt;:spoiler[&lt;strong&gt;我的迸发力不足了。&lt;/strong&gt;]&lt;/p&gt;
&lt;p&gt;和健康状况无关，迸发力是一种控制三分钟热度能不能启动和持久的一个因素。具象地说，跃跃欲试地尝试新事物，代码一写写到凌晨，这就是迸发力的表现。&lt;/p&gt;
&lt;p&gt;唉通俗点说其实就是累了。&lt;/p&gt;
&lt;p&gt;休息了。不码文章了。今天到这里吧，你今天也记得也早点睡。&lt;/p&gt;
</content:encoded></item><item><title>Traceback 里为什么不显示源码的绝对路径？</title><link>https://blog.emumu.xyz/posts/2025-11-13-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2025-11-13-00/</guid><description>溯源了C扩展模块的co_filename不是绝对路径的原因及其解决办法</description><pubDate>Sat, 15 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;写完代码，一运行，报错了。Python 的 Traceback 会告诉你错误发生在哪个文件的哪一行。我们通常会根据这个绝对路径去找到源文件，查看问题。&lt;/p&gt;
&lt;p&gt;但在使用 C 扩展模块时，你可能会遇到一个奇怪的现象：Traceback 里显示的文件名是一个相对路径（比如&lt;code&gt;path/main.pyx&lt;/code&gt;），而不是我们熟悉的绝对路径。这会导致一些依赖绝对路径的工具（例如，用来判断这个文件属于哪个第三方包）直接失效&lt;/p&gt;
&lt;p&gt;剧透：问题的解决实际上是绕了个没那么稳定的路，这个问题不动cython或者源码是没法彻底解决的，就是用&lt;code&gt;__file__&lt;/code&gt;……&lt;/p&gt;
&lt;p&gt;起因是我正在尝试通过&lt;code&gt;traceback.py&lt;/code&gt;中&lt;code&gt;TracebackException.stack[i].filename&lt;/code&gt;获取一个错误链的所有文件名，并且尝试压缩这一串东西，让tb看起来没那么狰狞，同时我需要提取出关键信息：这个文件来自什么模块。&lt;/p&gt;
&lt;h2&gt;名词解释&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;名词&lt;/th&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;解释&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;编程语言&lt;/td&gt;
&lt;td&gt;狭义特指Python语法本身。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cpython&lt;/td&gt;
&lt;td&gt;代码库&lt;/td&gt;
&lt;td&gt;使用C语言实现的标准Python。也是我们一般情境用到几乎所有的python。本期分析的python源代码使用cpython。大部分以后情况也会这样。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cython&lt;/td&gt;
&lt;td&gt;代码库&lt;/td&gt;
&lt;td&gt;一个Python的第三方包，它将python源代码改造为接入cpython API的c源代码并编译以获得极高的执行速度。一种方式是编写与python语法极为相似的&lt;code&gt;.pyx&lt;/code&gt;文件，并编译为&lt;code&gt;.pyd/.so&lt;/code&gt;。本期主题就是&lt;code&gt;.pyx&lt;/code&gt;文件中报错不会写出完整路径的问题&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Traceback&lt;/td&gt;
&lt;td&gt;概念&lt;/td&gt;
&lt;td&gt;或称为堆栈跟踪或回溯，它在发生错误时展示，展示导致错误的函数调用序列及其扩展信息。写的很清楚就是调试好帮手，很乱红红一片就是红温发生器。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;问题重现&lt;/h2&gt;
&lt;p&gt;首先来看这样一个测试&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from traceback import TracebackException

try:
    import cython_module
    import dppath_cymodule
    # cython_module.pyx &amp;amp; the/cmodule/inthe/deep/path/dppath_cymodule.pyx
    &quot;&quot;&quot;
    def raise_error_in_cython():
        raise ValueError(&quot;这是在 Cython 中引发的错误&quot;)
    &quot;&quot;&quot;

    import python_module
    # python_module.py
    &quot;&quot;&quot;
    def raise_error_in_python():
        raise ValueError(&quot;这是在 Python 中引发的错误&quot;)
    &quot;&quot;&quot;
except ImportError as e:
    print(&quot;编译 Cython 模块: python setup.py build_ext --inplace&quot;)
    # setup.py
    &quot;&quot;&quot;
    from distutils.core import setup
    from Cython.Build import cythonize

    setup(
        ext_modules=cythonize(&quot;cython_module.pyx&quot;),
    )
    &quot;&quot;&quot;
    TracebackException.from_exception(e).print();import sys;sys.exit(1)

def test_and_print(name, method):
    &quot;&quot;&quot;测试 Cython 模块中的错误&quot;&quot;&quot;
    print(f&quot;测试 {name} 模块错误...&quot;)
    try:
        method()
    except Exception as e:
        print(&quot;捕获到的tb文件链:&quot;)
        [print(&apos;-&apos;, stack.filename, stack.line) for stack in TracebackException.from_exception(e).stack]
    print(&quot;=&quot; * 50)

def raise_error_in_numpy():
    import numpy as np
    np.random.uniform(low=[1, 2], high=[4, 5, 6], size=(3))

if __name__ == &quot;__main__&quot;:
    test_and_print(&quot;Cython&quot;, cython_module.raise_error_in_cython)
    test_and_print(&quot;Python&quot;, python_module.raise_error_in_python)
    test_and_print(&quot;带路径的 Cython&quot;, dppath_cymodule.raise_error_in_cython2)
    test_and_print(&quot;Numpy&quot;, raise_error_in_numpy)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;测试 Cython 模块错误...
捕获到的tb文件链:
- c:\Users\BPuffer\Desktop\_\test.py method()
- cython_module.pyx
==================================================
测试 Python 模块错误...
捕获到的tb文件链:
- c:\Users\BPuffer\Desktop\_\test.py method()
- c:\Users\BPuffer\Desktop\_\python_module.py raise ValueError(&quot;这是在 Python 中引发的错误&quot;)
==================================================
测试 带路径的 Cython 模块错误...
捕获到的tb文件链:
- c:\Users\BPuffer\Desktop\_\test.py method()
- the\\cmodule\\inthe\\deep\\path\\dppath_cymodule.pyx       
==================================================
测试 Numpy 模块错误...
捕获到的tb文件链:
- c:\Users\BPuffer\Desktop\_\test.py method()
- c:\Users\BPuffer\Desktop\_\test.py np.random.uniform(low=[1, 2], high=[4, 5, 6], size=(3))
- numpy\\random\\mtrand.pyx
==================================================

# 另有文件结构：
C:\USERS\BPUFFER\DESKTOP\_
│  build.cmd
│  cython_module.pyx
│  python_module.py
│  setup.py
│  test.py
└─the
   └─cmodule
       └─inthe
           └─deep
               └─path
                       dppath_cymodule.pyx
# 编译后新增
│  cython_module.cp312-win_amd64.pyd
│  cython_module.pyx
│  dppath_cymodule.cp312-win_amd64.pyd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;显然，&lt;code&gt;cython_module.pyx&lt;/code&gt;并不打算露出它的绝对位置。&lt;/p&gt;
&lt;h2&gt;为什么？&lt;/h2&gt;
&lt;p&gt;这不是一个 bug，而是 Cython 的一个设计上的权衡。理解它，需要明白 Cython 代码是如何运行的。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;你写的是&lt;code&gt;.pyx&lt;/code&gt;源码&lt;/strong&gt;，比如&lt;code&gt;src/example/path/main.pyx&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;它被编译成二进制文件&lt;/strong&gt;，比如一个&lt;code&gt;.pyd&lt;/code&gt;或&lt;code&gt;.so&lt;/code&gt;文件。这个文件最终会被安装到你的 Python 环境里，例如&lt;code&gt;lib/site-packages/example/path/main.cp312-win_amd64.pyd&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Python 运行时真正加载和执行的是这个&lt;code&gt;.pyd&lt;/code&gt;文件&lt;/strong&gt;。Python 知道这个&lt;code&gt;.pyd&lt;/code&gt;文件的绝对路径，就像知道普通&lt;code&gt;.py&lt;/code&gt;文件的路径一样。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;那么问题来了：Traceback 里的源码路径&lt;code&gt;path/main.pyx&lt;/code&gt;是哪来的？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这个路径是在编译时由 Cython 记录下来的。通常是项目源码目录里的相对路径。&lt;strong&gt;而且不会给到源码级别的行展示。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;当运行时错误发生，Cython 会忠实地把这个编译时记录的相对路径报告给你。它 &lt;strong&gt;不会&lt;/strong&gt; 动态地去计算这个&lt;code&gt;.pyx&lt;/code&gt;文件在你当前机器上的绝对路径。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;为什么不呢？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;因为 Python 运行时 &lt;strong&gt;根本不需要&lt;/strong&gt; 这个&lt;code&gt;.pyx&lt;/code&gt;源文件来执行程序。一切都已经编译在&lt;code&gt;.pyd&lt;/code&gt;文件里了。当然说是被编译进去了，实际上也只是编译了哪些操作对应了源码的行，并没有真的把原语句编译进去。&lt;/p&gt;
&lt;p&gt;如果 Cython 非要报告一个绝对路径，那么就只有一种方法：要求你在部署、安装二进制包的时候，也必须把原始的&lt;code&gt;.pyx&lt;/code&gt;源文件按照编译时的目录结构一模一样地放在旁边。这对于用户来说是一个不必要的负担。绝大多数用户只需要安装二进制包来运行程序，并不需要查看 Cython 源码。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;所以，Cython 的选择是：&lt;/strong&gt;
报告编译时的相对路径。这样：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;对于&lt;strong&gt;拥有完整项目源码的开发者&lt;/strong&gt;来说，他们可以根据这个相对路径在项目里找到对应的源文件。&lt;/li&gt;
&lt;li&gt;对于&lt;strong&gt;只安装了二进制包的用户&lt;/strong&gt;，他们也不至于因为找不到源文件而遇到更多错误。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;如何解决？&lt;/h2&gt;
&lt;p&gt;既然从 Traceback 里拿到的&lt;code&gt;co_filename&lt;/code&gt;是不可靠的相对路径，我们就需要一个可靠的锚点。这个锚点就是模块的&lt;code&gt;__file__&lt;/code&gt;属性。&lt;/p&gt;
&lt;p&gt;对于同一个模块，&lt;code&gt;__file__&lt;/code&gt;属性会给出运行时加载的&lt;code&gt;.pyd&lt;/code&gt;文件（或&lt;code&gt;.so&lt;/code&gt;文件）的 &lt;strong&gt;绝对路径&lt;/strong&gt;。通过这个绝对路径，你就能准确地判断出这个模块属于哪个第三方包。&lt;/p&gt;
&lt;p&gt;当然也仅限包名。对于这件事的最初目的——&lt;strong&gt;对Traceback的路径进行压缩美化输出&lt;/strong&gt;——中，除了模块名，还有压缩的路径部分，这部分我会使用原始提供的filename。完全路径模式下则用原始&lt;code&gt;__file__&lt;/code&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PASSED [100%]
pypy被玩坏了！这肯定不是py的问题！绝对不是！
  文件 test_exc_from_libs.py:29:12 的 test_from_third_party_lib
    np.random.uniform(low=[1, 2], high=[4, 5, 6], size=(3))
  文件 [numpy 模块] numpy/random/mtrand.pyx:1183 的 numpy.random.mtrand.RandomState.uniform
[ValueError] operands could not be broadcast together with shapes (3,) (2,) 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;::github{repo=&quot;emumus/kawaii-traceback&quot;}&lt;/p&gt;
&lt;h2&gt;路径被塞进&lt;code&gt;co_filename&lt;/code&gt;的过程&lt;/h2&gt;
&lt;h3&gt;由 Cython 编译的&lt;code&gt;.c&lt;/code&gt;源码中的端倪&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// _\the\cmodule\inthe\deep\path\dppath_cymodule.pyx
#define __PYX_MARK_ERR_POS(f_index, lineno) \
    { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__;  (void)__pyx_clineno; }
#define __PYX_ERR(f_index, lineno, Ln_error) \
    { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; }

...

  /* &quot;dppath_cymodule.pyx&quot;:2
 * # the/cmodule/inthe/deep/path/dppath_cymodule.pyx
 * def raise_error_in_cython2():             # &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;
 *     raise ValueError(&quot; Cython &quot;)
 */

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_AddTraceback(&quot;dppath_cymodule.raise_error_in_cython2&quot;, __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;code&gt;FileFinder&lt;/code&gt;找到&lt;code&gt;.pyc&lt;/code&gt;的过程&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;import cython_module&lt;/code&gt;-&amp;gt;找到文件&lt;code&gt;cython_module.cp312-win_amd64.pyd&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# cpython\Lib\importlib\_bootstrap_external.py
class FileFinder:
    &quot;&quot;&quot;File-based finder.
    Interactions with the file system are cached for performance, being
    refreshed when the directory the finder is handling has been modified.
    &quot;&quot;&quot;
    ...
    def _get_spec(self, loader_class, fullname, path, smsl, target):
        loader = loader_class(fullname, path)
        return spec_from_file_location(fullname, path, loader=loader,
                                       submodule_search_locations=smsl)
    def find_spec(self, fullname, target=None):
        &quot;&quot;&quot;Try to find a spec for the specified module.
        Returns the matching spec, or None if not found.
        &quot;&quot;&quot;
        ...
        # Check for a file w/ a proper suffix exists.
        for suffix, loader_class in self._loaders:
            try:
                full_path = _path_join(self.path, tail_module + suffix)
            except ValueError:
                return None
            _bootstrap._verbose_message(&apos;trying {}&apos;, full_path, verbosity=2)
            if cache_module + suffix in cache:
                if _path_isfile(full_path):
                    return self._get_spec(loader_class, fullname, full_path,
                                          None, target)
        if is_namespace:
            _bootstrap._verbose_message(&apos;possible namespace for {}&apos;, base_path)
            spec = _bootstrap.ModuleSpec(fullname, None)
            spec.submodule_search_locations = [base_path]
            return spec
        return None
...
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Cython提供处理器的过程(解析pyd文件的处理器)&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// cpython\Python\import.c
...
/*[clinic input]
_imp.extension_suffixes

Returns the list of file suffixes used to identify extension modules.
[clinic start generated code]*/

static PyObject *
_imp_extension_suffixes_impl(PyObject *module)
/*[clinic end generated code: output=0bf346e25a8f0cd3 input=ecdeeecfcb6f839e]*/
{
    PyObject *list;

    list = PyList_New(0);
    if (list == NULL)
        return NULL;
#ifdef HAVE_DYNAMIC_LOADING
    const char *suffix;
    unsigned int index = 0;

    while ((suffix = _PyImport_DynLoadFiletab[index])) {
        PyObject *item = PyUnicode_FromString(suffix);
        if (item == NULL) {
            Py_DECREF(list);
            return NULL;
        }
        if (PyList_Append(list, item) &amp;lt; 0) {
            Py_DECREF(list);
            Py_DECREF(item);
            return NULL;
        }
        Py_DECREF(item);
        index += 1;
    }
#endif
    return list;
}
...
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;挖坑&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;文件被解析生成模块，模块生成CodeType的完整代码还没翻完整。&lt;/li&gt;
&lt;li&gt;ai总说Cython有设置能在编译到c的阶段贴上这个路径，没找到。也没找到Cython生成的地方。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>反向代理的代价</title><link>https://blog.emumu.xyz/posts/2025-10-25-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2025-10-25-00/</guid><description>聊聊「月宫小站 - 教务系统」的后端实现</description><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;月宫小站教务系统是一个以前端为主，实际上是全栈的项目。与其细说作为大头但高度注ai的前端，我还是想着重讲讲关于后端代理的事情。&lt;/p&gt;
&lt;p&gt;因为显然，那个难看到爆又经常套娃又时不时宕机的jsp页面教务系统肯定不是现代程序员的杰作。数科的大佬似乎也是有人从表开始做新的系统了。本着不能把这个想法憋死在娘胎里的想法，我还是在假期紧赶慢赶把这个系统做了出来。&lt;/p&gt;
&lt;p&gt;项目遇到的第一个，也是最根本的障碍，就是 CORS（跨源资源共享） 限制。&lt;/p&gt;
&lt;p&gt;简单来说，CORS是现代浏览器的一项核心安全策略。它规定: &lt;code&gt;example.com&lt;/code&gt; 网站的前端 JavaScript，不能随意向 &lt;code&gt;another.com&lt;/code&gt; 发起请求并读取响应。&lt;/p&gt;
&lt;p&gt;为什么要有这种限制？设想一个场景: &lt;code&gt;evil.com&lt;/code&gt; 精心仿造了 &lt;code&gt;bilibili.com&lt;/code&gt; 的登录页面。当你在这个高仿页面输入账号密码时，如果允许跨域请求，&lt;code&gt;evil.com&lt;/code&gt; 的脚本就能将你的凭证直接发往真正的B站服务器。登录成功后，它甚至可以窃取你的登录状态或个人数据。而这一切，用户可能毫不知情。&lt;/p&gt;
&lt;p&gt;CORS 机制的存在，使得 &lt;code&gt;evil.com&lt;/code&gt; 的恶意请求被浏览器直接拦截。它能发出请求，但用户的浏览器会出手，它无法读取来自 &lt;code&gt;bilibili.com&lt;/code&gt; 的响应，最终只会得到一个 &lt;code&gt;TypeError: Failed to fetch&lt;/code&gt; 的错误。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;你可能会想: 那 &lt;code&gt;evil.com&lt;/code&gt; 自己架个服务器，把密码收过来再去B站尝试登录不就行了？
理论上可以，但这会暴露其服务器IP。当同一IP出现大量异常登录尝试时，极易被目标网站的风控系统识别并封禁。
是的代理池可以解决。但代理复代理，代理早晚会穷尽。ip可不是天上掉下来的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;现在我要解决的就是类似这样的问题。在这个项目里，我就是那个&lt;code&gt;evil.com&lt;/code&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sequenceDiagram
    actor 0 as &quot;&quot;
    participant 1 as  前端
    participant 2 as  我的后端代理
    participant 3 as  真的教务系统

    %% ========== 第一阶段: 登录初始化 ==========
    Note over 0,3: 【第一阶段: 登录初始化】

    0-&amp;gt;&amp;gt;+1:  点击登录按钮
    1-&amp;gt;&amp;gt;+2:  请求登录网页
    2-&amp;gt;&amp;gt;+3:  请求原始登录页 + Set-Cookie
    3--&amp;gt;&amp;gt;-2:  返回网页 + Set-Cookie
    2--&amp;gt;&amp;gt;-1:  返回网页 + Set-Cookie
    Note over 1:  浏览器自动处理Cookie存储

    %% ========== 第二阶段: 凭证认证 ==========
    Note over 0,3: 【第二阶段: 凭证认证与SSO票据获取】

    1-&amp;gt;&amp;gt;+2:  携带Cookie + 用户凭据
    2-&amp;gt;&amp;gt;+3:  提交认证请求
    3--&amp;gt;&amp;gt;-2:  获得SSO Ticket + 重定向指令
    2--&amp;gt;&amp;gt;-1:  返回SSO Ticket&amp;lt;br/&amp;gt;触发第一次重定向
    Note over 1:  浏览器自动处理302重定向

    %% ========== 第三阶段: SSO会话登记 ==========
    Note over 0,3: 【第三阶段: SSO会话建立】

    1-&amp;gt;&amp;gt;+2:  携带Ticket + JSESSIONID
    2-&amp;gt;&amp;gt;+3:  验证SSO票据
    3--&amp;gt;&amp;gt;-2:  重定向到SSO主页&amp;lt;br/&amp;gt;登记JSESSIONID
    2--&amp;gt;&amp;gt;-1:  返回SSO主页&amp;lt;br/&amp;gt;触发第二次重定向
    Note over 1:  现在有了SSO会话身份

    %% ========== 第四阶段: 服务令牌获取 ==========
    Note over 0,3: 【第四阶段: 获取目标服务访问权】

    1-&amp;gt;&amp;gt;+2:  请求SSO主页
    2-&amp;gt;&amp;gt;+3:  获取目标服务令牌
    3--&amp;gt;&amp;gt;-2:  颁发教务系统Token&amp;lt;br/&amp;gt;重定向至目标系统
    2--&amp;gt;&amp;gt;-1:  携带Token重定向&amp;lt;br/&amp;gt;触发第三次重定向
    Note over 1:  即将进入教务系统

    %% ========== 第五阶段: 系统会话建立 ==========
    Note over 0,3: 【第五阶段: 建立教务系统会话】

    1-&amp;gt;&amp;gt;+2:  提交JSESSIONID + Token
    2-&amp;gt;&amp;gt;+3:  验证令牌有效性
    3--&amp;gt;&amp;gt;-2:  登记JSESSIONID&amp;lt;br/&amp;gt;重定向到系统主页
    2--&amp;gt;&amp;gt;-1:  返回教务系统主页&amp;lt;br/&amp;gt;触发第四次重定向
    Note over 1:  成功建立教务系统会话

    %% ========== 第六阶段: 最终主页获取 ==========
    Note over 0,3: 【第六阶段: 进入系统】

    1-&amp;gt;&amp;gt;+2:  请求教务系统主页
    2-&amp;gt;&amp;gt;+3:  获取学生主页
    3--&amp;gt;&amp;gt;-2:  返回完整的个人信息页面
    2--&amp;gt;&amp;gt;-1:  成功返回学生主页
    1--&amp;gt;&amp;gt;0:  解析并显示个人信息&amp;lt;br/&amp;gt;登录流程完成！

    %% ========== 总结注释 ==========
    Note over 0,3: 最终进入系统
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;2025-10-25-00-01.png&quot; alt=&quot;Fiddler实录&quot; /&gt;&lt;/p&gt;
&lt;p&gt;在教务系统登录过程中，我需要解决的两个核心问题是CORS和Cookie携带。首先复杂而&lt;code&gt;HTTPOnly&lt;/code&gt;的Cookie管理注定了前端不可能处理这样的怪物。&lt;/p&gt;
&lt;p&gt;解决方案非常明确: 引入一个反向代理服务器。让我的前端不再直接请求教务系统，而是请求与我同源的代理服务器；再由这个代理服务器去“冒充”浏览器，向真实的教务系统发起请求，最后将净化后的数据返回给前端。&lt;/p&gt;
&lt;p&gt;考虑到用户量并不大，教务系统流量又不高，我现在会先不用代理池，直接用服务器做可行性实验（不然玩不好会被借刀杀人搞成DDOS）。现在第一个问题是:&lt;/p&gt;
&lt;h2&gt;如何请求到网页数据&lt;/h2&gt;
&lt;p&gt;下面是最普通的代理所做的事情:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sequenceDiagram
    participant 0 as 用户
    participant 1 as proxy.com
    participant 2 as target.com

    0-&amp;gt;&amp;gt;1: 请求: Host:target.com ... &amp;lt;br/&amp;gt;(但其实发给了proxy.com)
    1-&amp;gt;&amp;gt;2: 原样转发请求（保留Host及所有内容）
    2--&amp;gt;&amp;gt;1: 原样返回响应 target.com/resrc
    1--&amp;gt;&amp;gt;0: 转发响应 target.com/resrc ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但实际上，浏览器前端的安全策略几乎没有办法把&lt;code&gt;Host: target.com&lt;/code&gt;转发到&lt;code&gt;proxy.com&lt;/code&gt;。我们需要一种方式使代理服务器知道我们要去哪。&lt;/p&gt;
&lt;p&gt;比如说，&lt;code&gt;proxy.com/proxy/target.com&lt;/code&gt;。这个方案可行吗？&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;目标&lt;/th&gt;
&lt;th&gt;代理转换&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;http://target.com&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://proxy.com/proxy/target.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;https://target.com/path/to/endpoint&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://proxy.com/proxy/target.com/path/to/endpoint&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ws://target.com?query=1234&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ws://proxy.com/proxy/target.com?query=123&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;当然可行。通过路径传递是很&lt;em&gt;我没意见&lt;/em&gt;的方式。只要在整个项目前后端都使用同一套标准的转换就可以了&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sequenceDiagram
    participant 0 as frontend.site
    participant 1 as -&amp;gt;proxy.com
    participant 2 as proxy.com-&amp;gt;
    participant 3 as target.com

    0-&amp;gt;&amp;gt;1: 请求 proxy.com/proxy/target.com/resrc
    1-&amp;gt;&amp;gt;2: 转换为 target.com/resrc
    2-&amp;gt;&amp;gt;3: 请求 target.com/resrc
    3--&amp;gt;&amp;gt;2: 响应 target.com/resrc
    2--&amp;gt;&amp;gt;1: 加上frontend.site的CORS头
    1--&amp;gt;&amp;gt;0: 以 proxy.com 的身份响应数据
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;好的第一个问题解决了。现在我们解决第二个问题:&lt;/p&gt;
&lt;h2&gt;如何维持Cookie状态？&lt;/h2&gt;
&lt;p&gt;首先我排除了后端维持，即使这个方案理论可行而且是AI一解。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第一，你将要作为代理服务器主动保留用户信息，我无法接受，这将不是代理而是后端，尤其是针对这个教务系统的后端。&lt;/li&gt;
&lt;li&gt;第二，这个服务器需要一个缓存数据库来应对，为此掏出Redis实在小题大做。&lt;/li&gt;
&lt;li&gt;第三&amp;lt;del&amp;gt;，当时的我其实前端并非特别熟练&amp;lt;/del&amp;gt;，我登时希望用一个fetch like的&lt;code&gt;fetchProxy&lt;/code&gt;函数转换并请求来解决一切问题。事实上我成功了。在此之前，我们要先讨论一下Cookie里都有什么。我们首先知道，请求中有&lt;code&gt;Cookie&lt;/code&gt;头，而响应中有&lt;code&gt;Set-Cookie&lt;/code&gt;头，这两个我们都要收拾。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;Cookie: JSESSIONID=9FFE...0301;
Set-Cookie: JSESSIONID=9FFE...0301; Path=/authserver; secure; SameSite=None; Secure; HttpOnly
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这是一对不是很全但真实的Cookie头。Cookie除了键值还有一些属性，服务器将Cookie交给浏览器保管，当浏览器认为Cookie的属性与请求相符（如果是fetch发起的，fetch要设置携带凭据）时，它会随请求将Cookie发送出去。浏览器认为相符主要取决于:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Domain&lt;/code&gt;: Cookie被存储时默认&lt;code&gt;Domain&lt;/code&gt;为这个请求的&lt;code&gt;Host&lt;/code&gt;，发送时也匹配这个&lt;code&gt;Host&lt;/code&gt;。服务器不常通过&lt;code&gt;Domain&lt;/code&gt;指定。但如果他这么做了，无疑会给我们的&lt;code&gt;proxy.com&lt;/code&gt;当头一棒——连读取都不必考虑，它根本就没法设置&lt;code&gt;target.com&lt;/code&gt;的Cookie，这个&lt;code&gt;Domain&lt;/code&gt;发明出来是给子域名用的。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Path&lt;/code&gt;: 只有当目标终结点处于该&lt;code&gt;Path&lt;/code&gt;或其下时，Cookie会被发送。注意，如果我们使用&lt;code&gt;/proxy/target.com/path&lt;/code&gt;，那么返回的&lt;code&gt;Path: /path&lt;/code&gt;就不仅要加上前面的&lt;code&gt;proxy&lt;/code&gt;还要加上当前的&lt;code&gt;Domain&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Secure&lt;/code&gt;: 大小写无所谓（都写可能是为了那个拟人兼容）。只有https下才发送这个Cookie。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SameSite&lt;/code&gt;: 是否要考虑同一站点
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;None&lt;/code&gt;: 允许所有请求携带 Cookie，但必须同时 &lt;code&gt;Secure&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Lax&lt;/code&gt;: 允许同一站点和某些跨站请求携带 Cookie。这包括本地的不同端口，域名和子域名相互，子域名之间，这就够了。考虑到开发环境不想配ssl的，强烈建议改成&lt;code&gt;Lax&lt;/code&gt;。（ps: 同一站点指同域名、同端口、同协议。）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Strict&lt;/code&gt;: 仅允许同一站点的请求携带 Cookie。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当响应直接通过代理，单带一个CORS头来到前端后，不正确的&lt;code&gt;Domain&lt;/code&gt;使它无法被设置，错误的&lt;code&gt;Path&lt;/code&gt;使其永远发不出去，&lt;code&gt;SameSite:Strict&lt;/code&gt;更是给你Cookie直接嘎巴一下嗯死在炕上了。&lt;/p&gt;
&lt;p&gt;现在我们要做的很明确了。在后端添加cors的同时做这样一件事:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Path&lt;/code&gt;: 改为&lt;code&gt;proxy/{(Domain或响应域名)}/{原Path}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Domain&lt;/code&gt;: 改为&lt;code&gt;proxy.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SameSite==&quot;Strict&quot;&lt;/code&gt;的: 改为&lt;code&gt;Lax&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;Set-Cookie: JSESSIONID=9FFE...0301; Domain=proxy.com; Path=/proxy/target.com/authserver; secure; SameSite=None; Secure; HttpOnly
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;另外，&lt;code&gt;HttpOnly&lt;/code&gt;是用于禁止js访问的。这一点可以保留，毕竟咱用不上，也没必要暴露增加不确定性。&lt;/p&gt;
&lt;h2&gt;如何处理重定向？&lt;/h2&gt;
&lt;p&gt;与Cookie相比，重定向要简单的多。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Location: http://target.com/sso.jsp?ticket=v9Iy...boDE
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;只要在返回响应时简单把他按&lt;a href=&quot;#%E5%A6%82%E4%BD%95%E8%AF%B7%E6%B1%82%E5%88%B0%E7%BD%91%E9%A1%B5%E6%95%B0%E6%8D%AE&quot;&gt;上面的&lt;/a&gt;规则转换一下就能完全解决了。要注意浏览器会根据HSTS（一种可选的响应头）自动处理不降级策略，即如果响应是https，而请求是http，浏览器会自动升级为https。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Location: http://proxy.com/proxy/target.com/sso.jsp?ticket=v9Iy...boDE
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;结语&lt;/h2&gt;
&lt;p&gt;SSO Ticket此处的实现本质上就查询字符串，JSESSIONID/会话追踪本质上就是Cookie。现在，所有一切有条不紊地运行着。一个&lt;code&gt;fetch(proxyTo(&apos;target.com&apos;))&lt;/code&gt;解决了所有那些看不见的。除了有点慢以外 :spoiler[这个真没招，得花钱]。&lt;/p&gt;
&lt;p&gt;这或许只是一个简单的代理扩展，但回想当时边做前端边迷迷糊糊地问ai代理方案，ds的回答模棱两可，经常给出类似 &lt;code&gt;SameSite: Lax&lt;/code&gt; 不能跨本地端口之类的错误回答。现在豁然开朗的自己比起来，只觉得“人一定要大量且频繁地记录自己”是如此正确。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;emumus/tsukimiyaJwgl&quot;}&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;那么，evil.com做了这一切的代价是什么呢？&lt;/p&gt;
</content:encoded></item><item><title>浅谈python自学之旅</title><link>https://blog.emumu.xyz/posts/2025-05-10-00/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2025-05-10-00/</guid><description>从高中开始的梦</description><pubDate>Sat, 10 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;我的自学经历可能对纯新手参考性有限——毕竟我是出于热爱主动钻研编程的。&lt;/p&gt;
&lt;p&gt;本文更偏向&lt;strong&gt;个人经验漫谈&lt;/strong&gt;，适合茶余饭后寻找学习灵感时阅读。&lt;/p&gt;
&lt;h2&gt;阶段一：初学&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;代码生来不是让人看不懂的，恰恰相反，就是用来让人看懂复杂的逻辑的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我从高一开始接触python编程，一开始我并没有系统地看视频，更多的是不会就搜。&lt;/p&gt;
&lt;p&gt;在初学阶段，最有效的学习方式是多试、多搜、主动践行编程思维。每当遇到反直觉的数学问题（例如&quot;20%概率抽5次比10%概率抽10次更容易中奖?&quot;），立刻用代码模拟验证。这种即学即用的方式让我快速建立了编程直觉。&lt;/p&gt;
&lt;p&gt;只是看视频绝无可能进步，但视频能在你毫无头绪止步不前的时候推你一把。比如你可以在手机上把视频打开放到手机架上，老师写一句照着写一句，写完运行成功了，可以改改数再试试。&lt;/p&gt;
&lt;p&gt;B站上大多数高收藏量的视频都很不错。我倾向于介绍&lt;a href=&quot;https://www.bilibili.com/video/BV1ng4y1i7Uk&quot;&gt;mosh大神的课程&lt;/a&gt;。不过课程是死的，人是活的，选自己看的舒服的视频才是最重要的。看视频的时候注意不要过早接触不该接触的部分，比如视频里的Django框架。看这个的一般是面向就业的。&lt;/p&gt;
&lt;p&gt;我见过学python时死记硬背关键词的。绝对不要这么做。单词一定要遇到一个弄懂一个。代码里出现一个&lt;code&gt;init&lt;/code&gt;，就要去问ai这是什么意思，然后把Initialize这个单词学会。在这一阶段总共会遇到不到100个英语单词，还有几个既熟悉又陌生的单词比如run(运行), float(浮点数)等。&lt;/p&gt;
&lt;p&gt;至此我没使用过什么太高级的代码编辑器，只有一个IDLE。太全面的编辑器我反而看不懂，因为涉及到很多把代码工程化标准化的东西，而我暂时用不到，眼花缭乱的专有名词和设置也只会乱人心。&lt;/p&gt;
&lt;p&gt;当时我在中学，并没有太多时间看视频，最主要还是实战练习。当然这证明脱离视频完全实战练习+百度也是能学到东西的，即使效率可能并不高。&lt;/p&gt;
&lt;h2&gt;阶段二：应用&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;人的价值在于创造力。机器能干的，人不要干。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;当我发现编程语言能将「字符串」这种东西写到文件里的时候，我意识到这东西现在开始可能有用了。&lt;/p&gt;
&lt;p&gt;我高中痴迷于Minecraft。这个游戏里命令的格式非常原始，比如要显示一个粒子效果就需要写一长串&lt;code&gt;particle minecraft:dust 1.0 0.5 0.0 1 1 2 3 0 0 0 1 0 force&lt;/code&gt;。里面有颜色、坐标、透明度等等参数。当我发现python可以瞬间生成几万几十万行这种指令并写入到文件里执行的时候，我立刻开始着手写一些复杂的东西，比如画一个圆，变成色环……这个过程我学习了很多&lt;strong&gt;零散化的编程相关知识点&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;“零散化的编程相关知识点”是很杂很乱的，有的python课默认你懂，有的只会涉及一点。比如颜色编码、文本编码、环境变量、图片读取及其格式、运行速度的概念、文件路径文件权限甚至&lt;code&gt;|&lt;/code&gt;键在哪这些问题等等都是在这个时期解决的。这些知识点有大有小，有人视作常识，有人闻所未闻，有人有但得一知半解之悟，只有大量上手实践才能把这个坑彻底填满。&lt;/p&gt;
&lt;p&gt;好处是，这些知识点基本都是全计算机领域通用的。而且填满之后可以让你永远不会问出“我刚解压的文件在哪呢”这样的话。&lt;/p&gt;
&lt;p&gt;本阶段渡过之后，你就正式入门python了。现在你能够驾驭VSCode、PyCharm(我正在用)等重型IDE软件了。需要注意的是，这次不能什么都弄懂了，因为你要进入深水区了。看到不懂的按钮，学习之前最好先问一下ai：“我一定需要这个功能吗？”&lt;/p&gt;
&lt;p&gt;ABCD阶段是我上大学后并行渡过的。虽然是我一起渡过的，但你完全可以自行选修。&lt;/p&gt;
&lt;h2&gt;阶段A：专业知识&lt;/h2&gt;
&lt;p&gt;尽管跨专业，一些计算机专业知识的学习一定程度上能加深对python的理解。举例来说，如果我不系统学操作系统，纯靠ai帮我写多线程，我可能这辈子都想不明白为什么cpu和内存都占满了，程序就是跑不动一点。&lt;/p&gt;
&lt;p&gt;我学了一些基本的算法，当然至今我的算法能力也比不上ACM选手，但一些思维方式为我日后的学习带来了一定启发，至少我现在很少会写暴力遍历了。&lt;/p&gt;
&lt;p&gt;针对操作系统，四级网络工程师的考纲包含操作系统中的进程线程模型和并发，这直接让我完成了学习异步、多线程和多进程的前置基础。同时对于我理解python的GIL上也很有帮助&lt;/p&gt;
&lt;p&gt;众所周知python爬虫非常出名。于是我学了爬虫基础，破解了某收集表的定位打卡，实现了自定义位置和自动化帮几个人打卡，当然一个月后还是东窗事发，毕竟活人不能生成。&lt;/p&gt;
&lt;p&gt;之后我还用python爬取了数学建模的数据、游戏相关资源等。这部分知识还适用于对接API，比如后来实现了微信ai聊天等。&lt;/p&gt;
&lt;h2&gt;阶段B：数学建模&lt;/h2&gt;
&lt;p&gt;我发现很多视频的讲解的侧重点完全不同，起点也参差不齐。个人推荐先从“过程记录”等记录类视频下手，了解赛程之后选一个粉丝多的up主的教程过一遍。之后的一些细小的概念就只能去广学涉猎了。接触到不懂的概念要先确定这是哪个科目的，然后再去B站搜“&lt;strong&gt;xx期末速成&lt;/strong&gt;”比如运筹学期末速成，最优化理论期末速成……这些视频的干货量是最高的，反正也不是真的要考，可以慢慢吃里面的陌生概念。&lt;/p&gt;
&lt;p&gt;代码方面，我开始接触几个常用的数学建模库，比如numpy，pandas，scipy等等。我大多数时间是主动学习，也就是在写代码中学习。我会有意识地动用相关的库，使用相关的概念，比如接触到相关的数据模型我就会使用pandas.DataFrame，大规模计算会用numpy等。值得一提的是。学会python绘图之后，可以做一些在以前看来很暴力、但对计算机来说很平常的事，比如求微分方程的数值解。&lt;/p&gt;
&lt;p&gt;这些常用的库的学习方式中，操作比较频繁的库（numpy,matplotlib等）我采用了读文档+百度的方式学习，代码量比较少的（scipy、sklearn等）就直接问AI了。&lt;/p&gt;
&lt;p&gt;文档。就是库的开发者本人写的面向老手的教程，或者说介绍，里面有很多可能连ai也不知道的细节，但阅读门槛比较高。文档主要这些库的开发者们自己写的，所以总是最全面，最详细的。唯一的缺点是可能是英文的。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/posts/2025-05-10-01/&quot;&gt;面向数学建模编程&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;阶段C：软件工程&lt;/h2&gt;
&lt;p&gt;我要开发自己的网站。为此我需要学习后端框架。我从零开始学习主流的python后端框架Flask的方式就是看视频。因为有基础，理解速度非常快。但开始学容器化部署相关知识时，我又遇到一条类似阶段二的鸿沟，细碎的经验只能通过试错+百度解决。目前正在度过中。&lt;/p&gt;
&lt;p&gt;对于异步、数据库、Git等比较小但重要的知识点，我在开发过程中就克服了。但工程化优化还要等我未来系统学习数据库和阅读asyncio源码之后才行。&lt;/p&gt;
&lt;h2&gt;阶段D：社区生态&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com&quot;&gt;Github&lt;/a&gt;是全球最大的代码托管平台。只要编程英语过关，你能在这找到无数别人留下的资料、代码等（&lt;strong&gt;自己看和学一般不用管开源许可&lt;/strong&gt;）。&lt;/p&gt;
&lt;p&gt;开源指开放源代码，绝大多数允许私人非商业使用，一些小工具或者你认为写起来并不多但很麻烦且常用的代码很容易就能在上面找到。&lt;/p&gt;
&lt;p&gt;当然你也可以在这留下你自己的代码。不过开源又是另一套社区规矩了。&lt;/p&gt;
&lt;h2&gt;阶段四: 真正的Python&lt;/h2&gt;
&lt;p&gt;现在我对python的理解已经足够深入，再深入下去我就应该去探索C源码和接口了。&lt;/p&gt;
&lt;p&gt;我们都知道Python的运行速度慢，但更要知道它慢在哪，如何能快。都知道Python是单线程，但要知道如何尽量减少单线程的影响如异步，或者直接学习使用多线程。这些就是我正在理解的问题。&lt;/p&gt;
&lt;p&gt;这个阶段，我能在网上学到的东西已经寥寥无几，基本全靠日语生蹩脚的英语去大量看文档。有时候也会看看B站&lt;a href=&quot;https://space.bilibili.com/245645656&quot;&gt;码农高天&lt;/a&gt;的视频，看看各路Python core dev的&lt;a href=&quot;https://github.com/gaogaotiantian&quot;&gt;github仓库&lt;/a&gt;等等。&lt;/p&gt;
&lt;h2&gt;结语&lt;/h2&gt;
&lt;p&gt;学python最重要的就是上手多试。前期上手多写测试，后期上手做大项目。只有练习了、理解了才会有真收获。&lt;/p&gt;
&lt;p&gt;附：&lt;/p&gt;
&lt;p&gt;推荐的python版本：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.python.org/downloads/release/python-3128/&quot;&gt;Python 3.12.8 官网安装&lt;/a&gt; -- 比较稳定的python版本。&lt;/p&gt;
&lt;p&gt;代码编辑器：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.jetbrains.com.cn/pycharm/download/&quot;&gt;Pycharm (目前是免费付费统一版本)&lt;/a&gt; -- 纯python开发环境下最好用的编辑器&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;VSCode&lt;/a&gt; -- 多语言环境下的代码编辑器&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.qpython.com.cn&quot;&gt;QPython&lt;/a&gt; -- 在手机上利用碎片时间学习·运行python的软件&lt;/p&gt;
</content:encoded></item><item><title>面向数学建模编程</title><link>https://blog.emumu.xyz/posts/2025-05-10-01/</link><guid isPermaLink="true">https://blog.emumu.xyz/posts/2025-05-10-01/</guid><description>如何开始学习使用Python进行数学建模，包括数据处理、模型建立、求解等。</description><pubDate>Sat, 10 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;本教程结合个人经验，为时间有限的准编程手们提供尽可能时间上最有效的教程。如果你时间充足希望系统学习，你可以看看&lt;a href=&quot;/posts/2025-05-10-00/&quot;&gt;我是怎么学习的&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;[警告]&lt;/strong&gt; 本文包含大量主观内容，可以提供有限的方向参考，但切勿总是奉为圭臬。&lt;/p&gt;
&lt;h2&gt;开始&lt;/h2&gt;
&lt;p&gt;首先，面向数学建模从零完整开始学习编程语言这件事的代价就是极高的。更好的方案是学习语言的基本数据结构和语法，然后尝试“理解”编程语言，再使用AI辅助生成代码。&lt;/p&gt;
&lt;p&gt;下面是我自行量化的学习项目表，可根据自身情况自行选修。&lt;/p&gt;
&lt;p&gt;对于Python、MATLAB、北太天元，选择一项深入学习，否则适合你的题型面将非常少。SPSS最好只作为初级工具使用。&lt;/p&gt;
&lt;p&gt;对于新兴的国产分析软件&lt;a href=&quot;https://www.baltamatica.com/download.html&quot;&gt;北太天元&lt;/a&gt;，我的态度是十分支持。北太天元语法高度兼容MATLAB语法，既避免了被MATLAB卡脖子又有国内开发者生态。但其工具箱生态仍在发展中，复杂问题可能需要自行实现算法，要做好转回MATLAB的准备。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;项目&lt;/th&gt;
&lt;th&gt;重要程度&lt;/th&gt;
&lt;th&gt;学习难度&lt;/th&gt;
&lt;th&gt;地位&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;程序设计&lt;/td&gt;
&lt;td&gt;(5/5)[编程手·任何时候]&lt;/td&gt;
&lt;td&gt;(2/5)&lt;/td&gt;
&lt;td&gt;否则编程根本无从下手&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python语法&lt;/td&gt;
&lt;td&gt;(5/5)[用Python时]&lt;/td&gt;
&lt;td&gt;(4/5)&lt;/td&gt;
&lt;td&gt;绝对T0，最接近神的一个&amp;lt;br /&amp;gt;通用性和体系都是最完善的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MATLAB语法&lt;/td&gt;
&lt;td&gt;(5/5)[用MATLAB时]&lt;/td&gt;
&lt;td&gt;(3/5)&lt;/td&gt;
&lt;td&gt;T0.5，数学建模方面够用&amp;lt;br /&amp;gt;并且在工业级广泛应用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;北太天元语法&lt;/td&gt;
&lt;td&gt;(5/5)[用北太天元时]&lt;/td&gt;
&lt;td&gt;(3/5)&lt;/td&gt;
&lt;td&gt;T1，工具箱规模没有MATLAB大&amp;lt;br /&amp;gt;但数学建模目的完全够用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SPSS&lt;/td&gt;
&lt;td&gt;(3/5)[用SPSS时]&lt;/td&gt;
&lt;td&gt;(2/5)&lt;/td&gt;
&lt;td&gt;仅适用离散题型，且并非特别万能&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SPSSAU&lt;/td&gt;
&lt;td&gt;(3/5)[做离散题时]&lt;/td&gt;
&lt;td&gt;(1/5)&lt;/td&gt;
&lt;td&gt;仅适用离散题型&amp;lt;br /&amp;gt;注意，SPSSAU是在线付费的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Excel高级统计操作&lt;/td&gt;
&lt;td&gt;(2/5)[做离散题时]&lt;/td&gt;
&lt;td&gt;(1/5)&lt;/td&gt;
&lt;td&gt;离散题型的数据预处理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;算法&lt;/td&gt;
&lt;td&gt;(2/5)[做综合题时]&lt;/td&gt;
&lt;td&gt;(5/5)&lt;/td&gt;
&lt;td&gt;一些综合题可能需要编程算法解决&amp;lt;br /&amp;gt;但初学者可以先跳过这类题&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;算法的重要程度低是因为针对数学建模，数学思维重要得多，而一般算法可以用现成稳定的库实现。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;面向数学建模的Python学习路线&lt;/h2&gt;
&lt;h3&gt;1. 尽快提升熟练度&lt;/h3&gt;
&lt;p&gt;对于Python初学者，如果没有时间可以不学面向对象(就是类、继承那一堆乱七八糟的)，但内置数据类型的处理一定要熟练运用。比如这种技术上不难但实操起来十分吃&lt;strong&gt;熟练度&lt;/strong&gt;的问题：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;将一个布尔值列表转换为时间区间格式&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 输入
series = [False, False, True, True, False, False, True, True, True, True, True, False, True]
# 输出
assert solve(series) == {
    &quot;start&quot;: [2, 6, 12],
    &quot;end&quot;: [4, 11, 13],
    &quot;duration&quot;: [2, 5, 1]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;新手面对这个问题可以使用暴力遍历，但老手可以使用numpy的向量化操作简化流程，具体步骤可以自行研究&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 快速掌握报错信息和调试&lt;/h3&gt;
&lt;p&gt;学习过程中最好尽快掌握怎么看报错和PDB(如 &lt;code&gt;breakpoint()&lt;/code&gt;)的使用。&lt;/p&gt;
&lt;p&gt;其次要系统学习numpy,pandas和matplotlib三个库。其中numpy用于数据计算、pandas用于数据存储、matplotlib用于数据展示。这三个库不是终点，而是更多复杂的库（如sklearn高级数学模型、seaborn绘图等）的基础。&lt;/p&gt;
&lt;p&gt;最后是学会看&lt;strong&gt;代码的意图&lt;/strong&gt;。哪怕是我正式比赛环境敲代码也不会一行行去敲，而是先想好我要做什么，再描述出来，最后让AI把我&lt;strong&gt;已经想好的逻辑&lt;/strong&gt;以代码形式展现出来。这时一旦代码出了bug，我就需要理解它写出来的代码的意图是什么，理解不了就使用&lt;strong&gt;调试功能&lt;/strong&gt;跑一遍。然后找到对应问题进行修正。&lt;/p&gt;
&lt;h2&gt;使用AI进行编程&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;最后让AI把我&lt;strong&gt;已经想好的模型&lt;/strong&gt;以代码形式展现出来。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;比方说我希望进行PCA分析，首先我要写下面的代码&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 我给AI的提示代码
INPUT_FILE = &quot;data.xlsx&quot;
X_cols = [&quot;IN1&quot;,&quot;IN2&quot;,&quot;IN3&quot;,&quot;IN4&quot;,&quot;IN5&quot;]
...
X_data = ...
X_std = ...

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后再让AI续写一个PCA分析。这样可以省去很多麻烦事比如问你数据在哪又问你是什么格式需不需要去重、标准化……&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# AI生成的代码
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
import pandas as pd

data = pd.read_excel(INPUT_FILE)
X_data = data[X_cols]
X_std = StandardScaler().fit_transform(X_data)
pca = PCA(n_components=2)
principal_components = pca.fit_transform(X_std)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1. AI选型&lt;/h3&gt;
&lt;p&gt;众所周知、AI的智商有高有低，此处以多功能的&lt;a href=&quot;https://www.doubao.com/chat/&quot;&gt;豆包&lt;/a&gt;和高智商的&lt;a href=&quot;https://chat.deepseek.com/&quot;&gt;DeepSeek&lt;/a&gt;为例：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;问题&lt;/th&gt;
&lt;th&gt;选型&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;螺线的长度怎么求&lt;/td&gt;
&lt;td&gt;豆包(熟知的已知结论)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;帮我翻译一下这个论文&lt;/td&gt;
&lt;td&gt;豆包(能够快速响应)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;推荐几个数据分析网站&lt;/td&gt;
&lt;td&gt;豆包(搜索能力)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;写一个去除前后缀的函数&lt;/td&gt;
&lt;td&gt;豆包(简单任务没必要浪费Deepseek时间)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;将这句话用论文表述出来&lt;/td&gt;
&lt;td&gt;Deepseek(语言表述多样化)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;构建基于xxx的微分方程&lt;/td&gt;
&lt;td&gt;Deepseek(高强度场景理解)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;这段论文表述有没有什么致命错误&lt;/td&gt;
&lt;td&gt;Deepseek(思维链能够细致分析)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;令tf模型每训练一个批次缓存一个副本&lt;/td&gt;
&lt;td&gt;Deepseek(单纯的智商高)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;把这个一万行的文件里的异常值找出来&lt;/td&gt;
&lt;td&gt;不适合AI(大量数字中AI很可能忽视信息)&amp;lt;br /&amp;gt;可以改为令其写python代码找出异常值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;帮我画一个这个数学模型的结构示意图&lt;/td&gt;
&lt;td&gt;不适合绘图AI(绘图AI偏向艺术领域)&amp;lt;br /&amp;gt;可以改为令其写代码后在线生成如 &lt;a href=&quot;https://mermaid.live&quot;&gt;mermaid.live&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;帮我解这个复杂的微分方程&lt;/td&gt;
&lt;td&gt;不适合AI(AI很容易在长竖式中出错)&amp;lt;br /&amp;gt;可以使用在线求解工具如 &lt;a href=&quot;https://www.wolframalpha.com&quot;&gt;W|A&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;多功能AI可以类比国内市面上的各种AI比如混元、文心一言等等。功能都是较为完善的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;高智商AI中Deepseek是最方便的，替代有OpenAI的o1-mini, o1, o3-mini等。不可否认o3虽然非常厉害，但每日限制使其难以适应三天数模的节奏，当然一些特别棘手的问题问一下也是可以的。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. AI给我的代码出现了一个问题&lt;/h3&gt;
&lt;p&gt;别急，AI代码的问题无非以下几种：&lt;/p&gt;
&lt;p&gt;1.&lt;strong&gt;你给它的数据和描述不对版&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;有时候它不检查是因为太信任你。额外检查是因为不信任你。如果你想让他发挥的更自由，你就说&lt;code&gt;你是xx领域专家，请帮我……&lt;/code&gt;，否则如果你很清楚接下来你想做什么，你就说&lt;code&gt;你是听话的python助手，现在……&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;2.&lt;strong&gt;命名不规范&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;AI的命名通常是十分有意义的。但这有时候会让它们造成依赖，比如他们排序之后错误地将前面已经排序好的列名&lt;code&gt;sorted_inputs = [&apos;IN1&apos;,&apos;IN2&apos;,&apos;IN3&apos;]&lt;/code&gt;当作数据&lt;code&gt;[4,3,2]&lt;/code&gt;，尝试使用数据定位列名，结果就会造成类型不匹配或者找不到(有时会造成&lt;code&gt;None&lt;/code&gt;的出现)的情况。这时候就是代码意图理解和python学习成果展现的时候了。&lt;/p&gt;
&lt;p&gt;3.&lt;strong&gt;多字缺字&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;目前我只在deepseek-v3上见过这样的情况。对于ai来说这是很奇异的，但一般来说这种错误只要找到它缺了哪个括号、多了哪个括号处理一下就行了(大部分都是多了)。&lt;/p&gt;
&lt;h3&gt;3. 人机协同&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;AI知道的&lt;/th&gt;
&lt;th&gt;AI不知道的&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;你应该知道的&lt;/td&gt;
&lt;td&gt;使用python能做哪些事&amp;lt;br /&amp;gt;e.g. &amp;lt;br /&amp;gt;使用python当然能够进行数据清洗&lt;/td&gt;
&lt;td&gt;你的题目长什么样&amp;lt;br /&amp;gt;e.g. &amp;lt;br /&amp;gt;表格的输入列为[&quot;IN1&quot;,&quot;IN2&quot;,...]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;你可能不知道的&lt;/td&gt;
&lt;td&gt;某些库代码上具体怎么写&amp;lt;br /&amp;gt;e.g.&amp;lt;br /&amp;gt;从sklearn中引入支持向量机回归的具体方法&lt;/td&gt;
&lt;td&gt;最终的问题&amp;lt;br /&amp;gt;e.g.&amp;lt;br /&amp;gt;评委想看到论文的研究方向&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;链接&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;[通用]&lt;/strong&gt; 非常全面的Python图网站 - &lt;a href=&quot;https://python-graph-gallery.com/&quot;&gt;Python Graph Gallery&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;[离散]&lt;/strong&gt; 大量免费的数据集和模型 - &lt;a href=&quot;https://www.kaggle.com/&quot;&gt;Kaggle&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;[连续]&lt;/strong&gt; 低智能的AI会给高精确的解 - &lt;a href=&quot;https://www.wolframalpha.com/&quot;&gt;Wolfram|Alpha&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;[几何]&lt;/strong&gt; 高效画图，设置动点 - &lt;a href=&quot;https://www.geogebra.org/calculator&quot;&gt;GeoGebra&lt;/a&gt;&lt;/p&gt;
</content:encoded></item></channel></rss>