A*寻路算法从原理到实战:启发函数、性能调优与避坑指南
1. 从游戏地图到代码实现A*寻路到底在解决什么问题第一次接触A寻路是在做一个战棋类小Demo的时候。当时地图不大20×20的格子我心想用广度优先搜索BFS暴力铺开不就行了结果单位一多每帧都在跑全图搜索帧率直接掉到个位数。后来换成A同样的地图、同样的单位数量搜索节点数少了将近一个数量级帧率稳在60。这个对比让我意识到A*不是更高级的BFS而是带方向感的BFS——它知道该往哪边找而不是盲目地一圈圈往外扩。A*读作A-star是一种启发式搜索算法核心用途是在一张带权图或者网格地图上找到从起点到终点的一条代价最小的路径。它最典型的应用场景就是游戏里的角色寻路、机器人路径规划、地图导航中的路线计算。你玩的RTS游戏里单位绕开障碍物走到指定位置背后大概率就是A*或者它的变种在跑。这篇文章适合谁看如果你已经会写BFS或DFS但不知道A的估价函数怎么设计或者你照着网上的代码抄了一个A能跑但不知道为什么这么写又或者你写出来的A*在某些地图上会卡死、绕远路、甚至找不到路径——那这篇内容就是给你准备的。我会从最核心的原理讲起把每个参数为什么这么设、代码每一行在干什么都说清楚最后给出一份可以直接跑的完整实现以及我在实际使用中踩过的坑和调优经验。先给一个最直观的理解把A想象成你在一个陌生城市里找路。BFS的做法是以起点为圆心一圈一圈往外搜直到碰到终点而A的做法是每走到一个路口看一眼地图上终点的大致方向优先往那个方向走。那个看一眼方向的动作就是启发函数heuristic。它让搜索有了方向感从而大幅减少无效探索。但这里有个关键点方向感不能乱给。如果启发函数估得太乐观可能找到的不是最优路径估得太悲观又退化成BFS。怎么把握这个度就是A*最核心的设计问题也是后面要重点拆解的内容。2. 拆开A*的三个核心零件开放列表、关闭列表与估价函数很多人学A的时候代码能看懂但自己写就卡壳根本原因是没有把A的数据结构和决策逻辑分开理解。A*本质上就是两个列表加一个公式把这三样东西吃透代码自然就出来了。2.1 开放列表与关闭列表搜索的待办和已完成A*在运行过程中需要维护两个集合开放列表Open List存放待考察的节点。也就是那些已经被发现、但还没有展开检查其邻居的节点。你可以把它理解成一张待办事项清单。关闭列表Closed List存放已考察的节点。这些节点的邻居已经被检查过了不需要再重复处理。每次循环从开放列表里取出一个最有希望的节点怎么定义最有希望就是估价函数的事把它移到关闭列表然后检查它的所有邻居。对于每个邻居如果邻居在关闭列表里跳过已经处理过了。如果邻居不在开放列表里计算它的估价加入开放列表并记录它的父节点。如果邻居已经在开放列表里比较经过当前节点到达邻居的代价是否比原来记录的更低如果更低更新它的父节点和代价。这个流程听起来简单但有一个细节特别容易出错关闭列表里的节点代价还可能被更新吗在标准A*中如果一个节点已经进了关闭列表理论上它的最优代价已经确定了不需要再更新。但这个结论成立的前提是启发函数满足一致性consistency后面会专门讲。如果你的启发函数设计不当关闭列表里的节点代价可能还需要修正这时候就需要用一些变种算法来处理。提示开放列表的实现方式直接影响性能。新手常用数组或列表每次取最小值都要遍历一遍复杂度是O(n)。节点一多就慢得离谱。正确做法是用优先队列最小堆取最小值O(log n)。这是A*性能优化的第一课。2.2 估价函数f(n) g(n) h(n)A*的灵魂A*的决策逻辑全部浓缩在一个公式里f(n) g(n) h(n)g(n)从起点到节点n的实际代价。这个是确定的走一步算一步累加出来的。h(n)从节点n到终点的估计代价。这个是猜的由启发函数给出。f(n)经过节点n的路径的总代价估计。A*每次从开放列表里取f(n)最小的节点来展开。g(n)好理解就是已经走过的路。关键是h(n)怎么设计。h(n)的设计直接决定了A*的行为h(n)的取值算法行为是否保证最优h(n) 0退化为Dijkstra算法均匀向外扩展是h(n) 实际代价搜索范围偏大但保证最优是h(n) 实际代价只沿最优路径搜索效率最高是h(n) 实际代价搜索范围小速度快但可能不是最优否这张表是A最核心的知识点。很多人写A发现怎么绕远了或者怎么找不到最短路径十有八九是h(n)估大了。2.3 启发函数怎么选曼哈顿、欧几里得还是对角线在网格地图上h(n)的常见选择有三种对应不同的移动规则曼哈顿距离h |x1 - x2| |y1 - y2|适用于只能上下左右四个方向移动的地图。因为在这种地图上你从A点到B点横向要走|dx|步纵向要走|dy|步加起来就是实际最少步数。所以曼哈顿距离是恰好等于实际代价的估计效率最高且保证最优。欧几里得距离h sqrt((x1-x2)^2 (y1-y2)^2)适用于可以任意方向移动的地图。但在四方向或八方向的网格地图上欧几里得距离会小于实际步数因为网格移动不能走斜线所以它是乐观估计保证最优但搜索范围会大一些。对角线距离h max(|dx|, |dy|) (sqrt(2)-1) * min(|dx|, |dy|)适用于八方向移动可以走斜线的地图。斜着走一步的代价是sqrt(2)≈1.414直着走一步是1。这个公式把两种移动分开算是八方向地图上最精确的启发函数。我个人的经验是先确定你的移动规则再选启发函数。四方向用曼哈顿八方向用对角线任意方向用欧几里得。选错了不会导致错误结果只要不高估但会影响搜索效率。有一次我在八方向地图上用了曼哈顿距离结果路径明显偏向先走直线再走斜线看起来特别别扭换成对角线距离之后就自然多了。3. 手写A*的完整流程从节点定义到路径回溯原理讲完了现在进入实操。我会用Python写一份完整的A*实现代码尽量简洁每一部分都加上注释说明为什么这么写。你可以直接复制运行也可以照着改成自己需要的语言。3.1 节点与地图的数据结构设计首先定义节点。一个节点需要存哪些信息坐标x, yg值、h值、f值父节点用于最后回溯路径import heapq import math class Node: def __init__(self, x, y): self.x x self.y y self.g float(inf) # 从起点到这里的实际代价 self.h 0 # 到终点的估计代价 self.f float(inf) # g h self.parent None # 父节点用于回溯路径 def __lt__(self, other): # 优先队列需要比较按f值排序 return self.f other.f这里有个细节__lt__方法必须定义否则heapq没法比较Node对象。另外g初始化为无穷大表示还没到达过。地图用一个二维数组表示0表示可通行1表示障碍# 0 可通行, 1 障碍 grid [ [0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 1, 0, 1, 0, 0], [0, 0, 0, 1, 0, 1, 0, 0], [0, 1, 0, 0, 0, 1, 0, 0], [0, 1, 1, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], ]3.2 启发函数与邻居生成的具体实现启发函数用曼哈顿距离四方向移动def heuristic(a, b): return abs(a.x - b.x) abs(a.y - b.y)邻居生成四方向def get_neighbors(node, grid): directions [(0, 1), (0, -1), (1, 0), (-1, 0)] # 上下左右 neighbors [] rows len(grid) cols len(grid[0]) for dx, dy in directions: nx, ny node.x dx, node.y dy if 0 nx rows and 0 ny cols and grid[nx][ny] 0: neighbors.append((nx, ny)) return neighbors如果要支持八方向把directions改成八个方向同时启发函数换成对角线距离。这里先以四方向为例逻辑最清晰。3.3 主循环开放列表的取出、展开与更新主循环是A*的核心逻辑如下def astar(grid, start_pos, end_pos): start Node(*start_pos) end Node(*end_pos) start.g 0 start.h heuristic(start, end) start.f start.g start.h open_list [] heapq.heappush(open_list, start) # 用字典记录开放列表中的节点方便查找 open_dict {start_pos: start} closed_set set() while open_list: current heapq.heappop(open_list) current_pos (current.x, current.y) # 如果这个节点已经被处理过可能重复入堆跳过 if current_pos in closed_set: continue # 到达终点回溯路径 if current_pos end_pos: path [] while current: path.append((current.x, current.y)) current current.parent return path[::-1] # 反转从起点到终点 closed_set.add(current_pos) open_dict.pop(current_pos, None) for nx, ny in get_neighbors(current, grid): if (nx, ny) in closed_set: continue # 计算经过当前节点到达邻居的g值 tentative_g current.g 1 # 四方向每步代价为1 neighbor open_dict.get((nx, ny)) if neighbor is None: # 新节点创建并加入开放列表 neighbor Node(nx, ny) neighbor.g tentative_g neighbor.h heuristic(neighbor, end) neighbor.f neighbor.g neighbor.h neighbor.parent current heapq.heappush(open_list, neighbor) open_dict[(nx, ny)] neighbor elif tentative_g neighbor.g: # 找到更短的路径更新 neighbor.g tentative_g neighbor.f neighbor.g neighbor.h neighbor.parent current # 注意这里不重新入堆而是直接修改堆中对象 # 因为heapq不支持更新修改后堆性质可能被破坏 # 简单做法是重新push一个配合closed_set去重 heapq.heappush(open_list, neighbor) return None # 没有找到路径这段代码有几个关键点需要解释第一为什么用open_dict因为heapq只能取最小值不能高效地查找某个坐标是否已经在开放列表里。用字典做索引查找是O(1)。第二为什么更新g值后要重新pushheapq不支持修改堆中元素的优先级。修改了neighbor的f值之后堆的性质被破坏了。最简单的处理方式是重新push一个然后在pop的时候用closed_set判断是否已经处理过。这是一种懒惰删除策略虽然会浪费一些空间但实现简单且正确。第三closed_set的作用。防止重复处理同一个节点。注意在pop之后才加入closed_set而不是在push的时候这是为了配合懒惰删除。3.4 路径回溯与结果验证路径回溯的逻辑很简单从终点节点开始沿着parent指针一路往回走直到起点然后把路径反转。path astar(grid, (0, 0), (5, 7)) if path: print(找到路径长度:, len(path)) for p in path: print(p) else: print(没有可行路径)跑一下这段代码你会得到一条从(0,0)到(5,7)的路径。可以自己画一下地图验证路径应该是绕开所有1的。注意如果起点或终点本身是障碍物或者终点被障碍物完全包围A*会返回None。实际使用中一定要处理这种情况否则游戏里的角色会卡住不动。4. 实测中暴露的五个典型问题与修复方案代码能跑不代表没问题。我在实际项目里用A*的时候踩过不少坑有些是逻辑错误有些是性能问题还有些是看起来对但实际不对的隐蔽bug。这一节把这些问题和解决方案整理出来你遇到类似情况可以直接对照排查。4.1 路径贴墙走代价函数缺少转向惩罚第一个问题很直观角色沿着障碍物的边缘走看起来像贴着墙在蹭。这不是bug而是A*的正常行为——因为贴墙走的步数和走中间一样算法没有理由选择中间。但在实际游戏里贴墙走很难看。解决方案是在代价函数里加入转向惩罚如果从当前节点到邻居的方向和上一步的方向不同就额外加一点代价。def move_cost(current, neighbor, last_direction): new_direction (neighbor.x - current.x, neighbor.y - current.y) cost 1.0 if last_direction is not None and new_direction ! last_direction: cost 0.5 # 转向惩罚 return cost这样A*会倾向于走直线路径看起来自然很多。代价是搜索空间会略微增大因为g值不再等于步数启发函数需要相应调整曼哈顿距离仍然可用因为它不高估。4.2 开放列表爆炸重复节点导致的性能雪崩第二个问题是我在一个大地图上遇到的地图200×200障碍物密集A*跑一次要好几秒。用profiler一查发现开放列表里堆了几万个节点大量是重复的。原因就是前面提到的懒惰删除策略。每次更新g值都push一个新节点旧节点还留在堆里。虽然pop的时候会跳过但堆的体积膨胀得很快。解决方案有两种方案一用支持 decrease-key 的优先队列。比如用斐波那契堆但Python标准库没有需要自己实现或者用第三方库。方案二入堆前检查。如果节点已经在开放列表里且新g值更大就不push。但这需要额外的数据结构来跟踪。我实际用的是方案二的简化版用一个g_score字典记录每个位置当前已知的最小g值push之前比较一下if tentative_g g_score.get((nx, ny), float(inf)): g_score[(nx, ny)] tentative_g # 创建或更新节点push这样能大幅减少重复push。实测在200×200的密集障碍地图上搜索时间从3秒降到了0.2秒。4.3 找不到路径起点被包围与边界判断遗漏第三个问题是明明有路但A*说没有。排查下来有两种常见原因原因一起点或终点在障碍物里。这个好排查检查一下grid[start]和grid[end]是不是1。原因二邻居生成的边界判断写错了。比如0 nx rows写成了0 nx rows导致第一行和最后一行永远访问不到。这种错误很隐蔽因为大部分路径不经过边界偶尔才暴露。我的建议是写一个可视化工具把搜索过程画出来。哪些节点被展开了、开放列表里有哪些、路径是什么一目了然。我用的就是matplotlib几十行代码排查效率提升巨大。4.4 启发函数高估为什么你的A*不再最优第四个问题最隐蔽路径能找到但明显不是最短的。比如明明可以走10步A*给了12步的方案。根本原因是启发函数高估了实际代价。回到那张表h(n) 实际代价时A*不保证最优。什么情况下会高估比如在四方向地图上用了欧几里得距离乘以一个系数或者在有权重的地图上用了不考虑权重的距离。排查方法把h(n)强制设为0跑一遍。如果结果变短了说明原来的h(n)高估了。然后逐步调整h(n)找到既高效又正确的那一个。提示A的最优性证明依赖于h(n) ≤ 实际代价这个条件。只要满足这个条件A一定能找到最优解。这个条件叫可采纳性admissibility。另外还有一个更强的条件叫一致性consistency满足一致性的启发函数能保证关闭列表里的节点不需要再更新。4.5 动态障碍物A*重算的时机与增量更新思路第五个问题是游戏场景特有的障碍物会动。比如其他单位走到了路径上原来的路径走不通了。最直接的做法是重新跑一次A*。但如果每帧都重算性能扛不住。我的做法是路径失效检测每次单位移动前检查下一步是否被占用。如果被占用才触发重算。局部重算只重算从当前位置到终点的路径而不是从头算。缓存对于静态地图把常用路径缓存起来避免重复计算。如果障碍物变化频繁可以考虑D* Lite或者LPA*这类增量搜索算法它们能在环境变化时快速修正路径而不是从头算。不过实现复杂度高不少中小型项目用失效检测重算就够了。5. 从能跑到好用A*的性能调优与工程化建议代码跑通了问题也修了接下来考虑的是怎么让A*在实际项目里稳定高效地工作。这一节分享一些工程化的经验都是我在多个项目里验证过的。5.1 优先队列的选型heapq够用吗Python的heapq是二叉堆push和pop都是O(log n)。对于大多数场景够用了。但如果你的地图特别大比如1000×1000或者需要频繁更新优先级可以考虑配对堆Pairing Heapdecrease-key操作均摊O(1)适合频繁更新的场景。桶队列Bucket Queue如果f值的范围有限且是整数可以用桶队列操作接近O(1)。不过说实话大部分项目用heapq就够了。我做过一个500×500的地图用heapq跑A*单次搜索平均20毫秒完全够用。先别急着优化profile之后再说。5.2 地图预处理JPS跳点搜索的适用场景如果你的地图是均匀网格且障碍物是静态的可以试试JPSJump Point Search。它的核心思想是在直线方向上很多节点不需要逐个展开可以直接跳到下一个关键节点。实测在开阔地图上JPS比普通A*快一个数量级。但JPS有几个限制只适用于均匀代价的网格地图。实现比A*复杂不少尤其是对角线移动的处理。在障碍物密集的地图上优势不明显。我的建议是先用A*跑通确认性能瓶颈确实在寻路上再考虑JPS。不要一上来就上复杂算法。5.3 多单位寻路的冲突处理排队与让行RTS游戏里经常有几十个单位同时寻路。如果各自跑各自的A*会出现堵门现象所有单位挤在同一个路口。常见的处理方式路径平滑A*出来的路径是格子序列用视线检测Line of Sight把能直连的格子合并减少拐点。局部避障在A*路径的基础上用转向行为Steering Behavior做局部避让。分层寻路把地图分成大区域先做区域级寻路再做格子级寻路。适合超大地图。这些内容展开又是一大篇这里只提个方向。核心思路是A*负责全局路径局部冲突用其他机制解决。5.4 可视化调试把搜索过程画出来最后强烈推荐一个调试手段把A*的搜索过程可视化。用matplotlib或者pygame把以下信息画出来地图障碍物用黑色可通行用白色关闭列表已处理的节点浅灰色开放列表待处理的节点浅绿色最终路径红色起点和终点蓝色和红色我每次写A*都会先做这个可视化因为很多问题比如启发函数方向不对、邻居生成有遗漏看图一眼就能发现比看代码快十倍。import matplotlib.pyplot as plt import matplotlib.colors as mcolors def visualize(grid, closed_set, open_dict, path, start, end): rows, cols len(grid), len(grid[0]) display [[0]*cols for _ in range(rows)] for i in range(rows): for j in range(cols): if grid[i][j] 1: display[i][j] 3 # 障碍 for (x, y) in closed_set: display[x][y] 1 # 已处理 for (x, y) in open_dict: display[x][y] 2 # 待处理 if path: for (x, y) in path: display[x][y] 4 # 路径 display[start[0]][start[1]] 5 display[end[0]][end[1]] 6 cmap mcolors.ListedColormap([white, lightgray, lightgreen, black, red, blue, orange]) plt.imshow(display, cmapcmap) plt.show()这段代码跑出来的图能清楚看到A*的搜索范围是不是朝着终点方向偏如果是一个均匀的圆形说明启发函数没起作用h0如果是椭圆偏向终点说明启发函数在正常工作。6. 写在最后几个让我少走弯路的实操心得A*这个算法看懂了和写对了之间隔着好几道坎。我把自己踩坑之后总结的几条经验放在这里希望能帮你省点时间。第一条先把BFS写对再改A*。A本质上就是BFS加上优先级。如果你BFS都写不利索直接上A会同时面对搜索逻辑和优先级管理两个问题排查起来很痛苦。先用BFS跑通然后把队列换成优先队列把f值加上一步步来。第二条启发函数宁小勿大。估小了顶多慢一点估大了直接错。拿不准的时候先用h0跑一遍确认路径正确再逐步加大h值观察路径长度和搜索节点数的变化。第三条可视化不是可选项是必选项。我见过太多人对着代码debug半天画个图五分钟就找到问题了。搜索类算法的调试图比代码直观得多。第四条性能问题先profile再优化。不要凭感觉猜瓶颈。用cProfile跑一下看看时间花在堆操作上还是邻居生成上针对性优化。我见过有人把启发函数优化了半天结果瓶颈在邻居生成的边界判断上。第五条A*不是万能的。如果地图是动态的、单位是连续的、或者需要频繁重算A*可能不是最优选择。根据场景选算法而不是拿着锤子找钉子。代码我放在上面了可以直接跑。建议你先把地图改小一点比如5×5手动推演一遍A*的每一步把开放列表和关闭列表的变化写下来。这个过程走一遍比看十篇文章都管用。

相关新闻

嵌入式实时噪声估计:三层递进式鲁棒算法设计

嵌入式实时噪声估计:三层递进式鲁棒算法设计

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

2026/10/16 5:16:33 阅读更多 →
恭介的法则:研发团队如何将踩坑经验固化为可执行规则

恭介的法则:研发团队如何将踩坑经验固化为可执行规则

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

2026/10/16 5:16:33 阅读更多 →
Colab K80 深度学习实战:环境配置、训练优化与断点续训技巧

Colab K80 深度学习实战:环境配置、训练优化与断点续训技巧

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

2026/10/16 5:16:33 阅读更多 →

最新新闻

暖黄温柔调色预设全攻略:人像街拍建筑城市场景详解

暖黄温柔调色预设全攻略:人像街拍建筑城市场景详解

要说这两年社交媒体上最耐看的色调,“暖黄温柔”绝对算一个。它不是那种一眼惊艳的浓烈滤镜,而是像下午三四点的阳光懒懒地洒在墙面上,整个画面都带着一层淡淡的、暖融融的黄色,看起来舒服又不扎眼。我自己是常年在外面拍人像和城…

2026/10/16 6:09:49 阅读更多 →
免费替代Office怎么选?LibreOffice、WPS、OnlyOffice实测对比

免费替代Office怎么选?LibreOffice、WPS、OnlyOffice实测对比

1. 为什么我开始关注免费替代 Office 的方案先说个大家都知道的情况:Office 从买断制变成了订阅制之后,个人版一年几百块,企业版更贵,而且越来越多人只是拿它写个论文、做个表格、排个简历,根本用不到那些深度功能。我…

2026/10/16 6:09:49 阅读更多 →
AI加低代码,两周快速上线中秋抽奖活动页的实战指南

AI加低代码,两周快速上线中秋抽奖活动页的实战指南

每年中秋前两周,运营就会带着需求过来问:能不能用AI加低代码,把这个中秋抽奖活动页快速上线。说实话,早几年我听到这种问题还会犹豫,现在反而觉得这个场景是低代码平台最能证明自己的时候。中秋营销有着极其明确的时间…

2026/10/16 6:09:49 阅读更多 →
红黑树原理与C++实现:从黑高守恒到插入删除修复全解析

红黑树原理与C++实现:从黑高守恒到插入删除修复全解析

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

2026/10/16 6:09:49 阅读更多 →
BepInEx 插件框架安装:三步锁好门,首启 10 分钟跑通

BepInEx 插件框架安装:三步锁好门,首启 10 分钟跑通

BepInEx 插件框架安装:三步锁好门,首启 10 分钟跑通 【免费下载链接】BepInEx Unity / XNA game patcher and plugin framework 项目地址: https://gitcode.com/GitHub_Trending/be/BepInEx BepInEx 是面向 Unity Mono、IL2CPP 和 .NET 游戏的插件…

2026/10/16 6:09:49 阅读更多 →
Project AIRI 桌面端使用指南:从安装、初始配置到机体模块与角色模型的完整上手手册

Project AIRI 桌面端使用指南:从安装、初始配置到机体模块与角色模型的完整上手手册

人工智能AI AgentMCP 服务工具调用GUI 自动化语音数字人交互助手 【免费下载链接】airi 💖🧸 自托管、归你拥有的 Grok 风格 AI 伴侣与 waifu / 赛博生命灵魂容器,目标是接近 Neuro-sama 的高度;支持实时语音聊天、Minecraft 和 F…

2026/10/16 6:08:48 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

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

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

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

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

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

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

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

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

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

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

2026/10/15 9:49:14 阅读更多 →