魔方复原Python源码:从打乱状态到六面归位的完整实现
简介这是一份用Python实现魔方复原算法的源码资源面向对算法设计、数据结构与Python编程感兴趣的开发者及学习者帮助理解如何用程序模拟魔方求解过程。压缩包共26个文件约73KB以11个py脚本为核心涵盖魔方状态建模、旋转操作与复原算法另有5个js与1个html、1个css构成Web端交互展示4个txt记录颜色分析与解法日志并附md说明、license及pyc缓存文件。资源围绕层先法、角先法、ZZ法等复原策略展开通过类与方法组织旋转序列并涉及Tkinter或PyQt界面交互与性能优化思路。目前已有2412人学习下载适合希望深入数据结构、算法设计与Python复杂逻辑实现的读者参考实践。1. 魔方复原Python源码从打乱状态到六面归位的完整实现你有没有过这种经历手头有个魔方拧乱了之后死活还原不回去最后只能拆了重装。其实用代码来解魔方比手拧靠谱得多。这份魔方复原Python源码干的就是这件事——输入一个打乱后的魔方状态程序自动算出复原步骤一步步把六面还原。它适合两类人一类是想学搜索算法但不想啃纯理论的开发者另一类是想拿一个完整可跑的小项目练手Python工程结构的人。整个项目不依赖重型框架核心就是状态建模加搜索求解代码量可控逻辑链路清晰拿来读或者改都挺顺手。下面我从项目结构、核心算法、运行方式到二次开发把它拆开讲一遍。2. 项目架构与核心模块魔方状态怎么表示、求解器怎么组织2.1 目录结构与模块职责拿到源码包第一件事是看目录。这个项目的结构不复杂常见做法是分成三层表示层、求解层、入口层。我一般会先扫一眼根目录确认没有隐藏的依赖坑。rubiks-cube-solver/ ├── cube/ │ ├── __init__.py │ ├── state.py # 魔方状态定义与初始化 │ ├── moves.py # 基本旋转操作 │ └── validator.py # 状态合法性校验 ├── solver/ │ ├── __init__.py │ ├── bfs.py # 广度优先搜索求解 │ ├── heuristic.py # 启发式评估函数 │ └── optimizer.py # 步骤压缩与优化 ├── utils/ │ ├── parser.py # 输入解析字符串/列表转状态 │ └── visualizer.py # 终端可视化输出 ├── main.py # 命令行入口 ├── requirements.txt └── README.mdcube/目录负责魔方的数学表示solver/目录放搜索算法utils/是辅助工具。这种分层的好处是你想换求解算法只动solver/就行不用碰状态定义。main.py是统一入口命令行传参后调用解析器和求解器最后输出步骤序列。2.2 魔方状态的数据结构魔方状态表示是整个项目的地基。常见做法有两种一种是模拟六个面的二维数组另一种是用一维数组加索引映射。这份源码用的是后者因为一维数组在旋转操作时更容易做切片和拼接。# cube/state.py class CubeState: 用一维数组表示魔方状态。 顺序上(U) 下(D) 前(F) 后(B) 左(L) 右(R)每面9个格子。 索引 0-8 对应 U 面9-17 对应 D 面以此类推。 def __init__(self, facesNone): if faces is None: # 默认复原状态每面同色 self.faces list(UUUUUUUUUDDDDDDDDDFFFFFFFFFBBBBBBBBBLLLLLLLLLRRRRRRRRR) else: self.faces list(faces) def is_solved(self): 检查六面是否各自同色 for i in range(6): face self.faces[i*9:(i1)*9] if len(set(face)) ! 1: return False return True def copy(self): 深拷贝当前状态搜索时避免污染原状态 return CubeState(self.faces[:])这里faces是一个长度54的列表每个元素是U/D/F/B/L/R中的一个字符。is_solved逐面检查是否9个格子同色。copy方法在搜索过程中很关键因为每一步旋转都会产生新状态不能直接改原对象。参数说明faces参数可以传入自定义状态字符串长度必须是54字符集限定在六个面字母内。如果传入非法字符或长度不对validator.py里的校验函数会抛异常。2.3 旋转操作的实现方式旋转操作定义在moves.py里。每个基本动作U、D、F、B、L、R 及其逆操作本质上是对faces列表做一组索引置换。# cube/moves.py from cube.state import CubeState # 以 U 面顺时针旋转为例定义索引置换表 U_PERM [ (0, 2, 8, 6), (1, 5, 7, 3), # U 面自身旋转 (18, 36, 45, 9), (19, 37, 46, 10), (20, 38, 47, 11) # 侧面受影响的行 ] def apply_move(state, move): 对魔方状态执行一步旋转。 move: 字符串如 U, U, U2 new_faces state.faces[:] base move[0] times 1 if len(move) 2: times 2 if move[1] 2 else 3 # 逆时针等于顺时针三次 for _ in range(times): for cycle in PERM_TABLE[base]: tmp new_faces[cycle[-1]] for idx in reversed(cycle[:-1]): new_faces[idx] new_faces[cycle[cycle.index(idx)-1]] new_faces[cycle[0]] tmp return CubeState(new_faces)这段代码的核心是PERM_TABLE它把每个面的旋转映射成若干组循环置换。apply_move根据 move 字符串决定旋转次数顺时针一次逆时针三次180度两次。每次旋转按循环置换更新索引位置。参数说明move支持U、U、U2三种格式大小写敏感。PERM_TABLE需要为六个面各定义一组置换这里只展示了 U 面的部分。实际源码里每个面都有对应的置换表总共六组。2.4 求解器入口与搜索流程solver/bfs.py是默认求解器。它从初始状态出发逐层扩展直到找到复原状态。为了避免无限搜索通常会加一个深度上限。# solver/bfs.py from collections import deque from cube.moves import apply_move ALL_MOVES [U, U, U2, D, D, D2, F, F, F2, B, B, B2, L, L, L2, R, R, R2] def solve(initial_state, max_depth6): 广度优先搜索求解魔方。 返回步骤列表若超过 max_depth 未找到则返回 None。 queue deque([(initial_state, [])]) visited set() visited.add(tuple(initial_state.faces)) while queue: state, path queue.popleft() if state.is_solved(): return path if len(path) max_depth: continue for move in ALL_MOVES: next_state apply_move(state, move) key tuple(next_state.faces) if key not in visited: visited.add(key) queue.append((next_state, path [move])) return Nonesolve函数用队列做 BFSvisited集合记录已经出现过的状态避免重复扩展。max_depth控制搜索深度默认6步。如果打乱步骤超过6步BFS 可能找不到解这时候需要换启发式搜索或者加大深度。参数说明initial_state是CubeState实例max_depth是整数建议不超过8否则内存和耗时都会明显上升。返回的path是 move 字符串列表按顺序执行即可复原。3. 运行环境与实操步骤从零把项目跑起来3.1 环境准备与依赖安装这个项目对 Python 版本要求不高3.7 以上都能跑。依赖很少requirements.txt里通常只有colorama用于终端彩色输出其他都是标准库。# 创建虚拟环境推荐避免污染全局包 python -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate # 安装依赖 pip install -r requirements.txt如果requirements.txt里没有固定版本号直接装最新版一般也没问题。但如果你在离线环境需要提前把colorama的 wheel 包下好。提示虚拟环境激活后命令行前面会出现(venv)标识确认激活成功再装包。3.2 输入格式与解析器用法utils/parser.py负责把用户输入转成CubeState。支持的输入格式有两种54字符字符串和分面列表。# utils/parser.py from cube.state import CubeState def parse_string(s): 解析54字符字符串为 CubeState。 字符必须是 U/D/F/B/L/R 之一长度必须为54。 s s.strip().upper() if len(s) ! 54: raise ValueError(f输入长度必须为54当前为{len(s)}) valid set(UDFBLR) if not set(s).issubset(valid): raise ValueError(f输入包含非法字符{set(s) - valid}) return CubeState(list(s)) def parse_faces(faces): 解析六个面的列表每个面9个字符。 faces: [U面, D面, F面, B面, L面, R面] if len(faces) ! 6 or any(len(f) ! 9 for f in faces): raise ValueError(必须提供6个面每面9个字符) return CubeState(list(.join(faces)))parse_string适合从命令行直接传一长串字符parse_faces适合在代码里按面构造。两个函数都会做长度和字符集校验非法输入直接抛ValueError不会让脏数据进到求解器。参数说明字符串输入不区分大小写内部会转成大写。面列表输入要求每个面恰好9个字符顺序固定为 U、D、F、B、L、R。3.3 命令行运行与输出解读main.py是入口用argparse接收参数。常见用法是传一个打乱字符串然后看输出的步骤序列。# 方式一直接传54字符字符串 python main.py --state UUUUUUUUUDDDDDDDDDFFFFFFFFFBBBBBBBBBLLLLLLLLLRRRRRRRRR # 方式二从文件读取 python main.py --file scramble.txt # 方式三指定最大搜索深度 python main.py --state ... --max-depth 8输出通常长这样初始状态已解析开始求解... 找到解法共 4 步 U R F U2 总耗时0.32 秒步骤序列按从左到右执行即可复原。如果输出未找到解法说明当前max_depth不够或者状态本身不合法比如某个棱块颜色组合在真实魔方中不存在。注意BFS 在深度超过7之后耗时增长很快建议先用小深度测试确认流程通了再加大。3.4 可视化输出与调试技巧utils/visualizer.py提供了终端打印魔方状态的功能调试时很有用。它把一维数组还原成二维展开图用不同颜色区分六个面。# utils/visualizer.py from colorama import Fore, Style, init init(autoresetTrue) COLOR_MAP { U: Fore.WHITE, D: Fore.YELLOW, F: Fore.GREEN, B: Fore.BLUE, L: Fore.MAGENTA, R: Fore.RED, } def print_cube(state): 以展开图形式打印魔方状态 f state.faces # 打印 U 面 for row in range(3): print( * 6 .join(COLOR_MAP[f[row*3col]] f[row*3col] for col in range(3))) # 打印 L F R B 四面 for row in range(3): line for face_offset in [36, 18, 45, 27]: # L F R B for col in range(3): idx face_offset row*3 col line COLOR_MAP[f[idx]] f[idx] line print(line) # 打印 D 面 for row in range(3): print( * 6 .join(COLOR_MAP[f[9row*3col]] f[9row*3col] for col in range(3)))调试时我一般会在apply_move前后各调一次print_cube肉眼确认旋转结果是否符合预期。如果某个面的颜色乱了基本就是PERM_TABLE里索引写错了。参数说明print_cube依赖coloramaWindows 终端需要先init()才能正常显示颜色。如果不想装额外包可以把颜色映射去掉只打印字符。4. 避坑与常见问题搜索跑不动、状态对不上怎么办4.1 搜索深度设太大导致内存暴涨现象把max_depth设成10以上程序跑了几分钟没结果内存占用飙升。原因BFS 每层扩展18个分支深度10时状态数理论上接近18的10次方虽然visited去重能砍掉一部分但内存还是扛不住。解决先用小深度验证逻辑确认无误后改用启发式搜索heuristic.py里的 A* 或 IDA*或者把max_depth控制在7以内。如果必须解深打乱建议换用两阶段算法先还原棱块再还原角块。4.2 输入字符串长度对但颜色分布不合法现象输入54个字符长度和字符集都合法但求解器返回None或者旋转时索引越界。原因真实魔方的状态受物理约束不是任意54字符组合都能还原。比如单个棱块翻转、单个角块扭转、两个棱块互换这些在真实魔方中不可能出现。解决在validator.py里加合法性校验检查棱块和角块的排列奇偶性、翻转数。常见做法是统计每个棱块的颜色组合确认没有孤立翻转。4.3 旋转操作后状态与预期不符现象执行U之后打印出来的魔方某个面颜色错位。原因PERM_TABLE里某个循环置换的索引写反了或者循环方向搞错。解决拿一个复原状态的魔方手动执行一步U对照真实魔方的变化逐索引核对PERM_TABLE。我一般会在测试里写一个test_moves.py对每个基本动作做单步验证确保旋转结果和物理魔方一致。4.4 逆时针操作被当成顺时针执行现象输入U结果和U效果一样。原因apply_move里判断逆时针的逻辑写错了比如把times 3写成了times 1。解决检查apply_move中move[1]的判断分支。U应该执行三次顺时针旋转U2执行两次。可以在函数入口加一行日志打印move和times确认解析正确。4.5 终端颜色显示乱码现象print_cube输出一堆转义字符没有颜色。原因colorama没有初始化或者终端不支持 ANSI 颜色。解决在visualizer.py顶部调用colorama.init(autoresetTrue)。如果终端确实不支持把COLOR_MAP里的颜色值全改成空字符串只保留字符输出。5. 二次开发与改造思路换算法、加功能、提性能5.1 把 BFS 换成 IDA* 搜索BFS 适合浅层搜索深度一上来就歇菜。想解更复杂的打乱可以把solver/bfs.py替换成 IDA*。核心改动是引入启发式函数比如统计每个面未归位的格子数或者用模式数据库预计算部分子问题的距离。# solver/ida_star.py def ida_star_solve(initial_state, heuristic, max_depth20): IDA* 求解heuristic 返回当前状态到复原状态的下界估计。 bound heuristic(initial_state) path [] while bound max_depth: result search(initial_state, path, 0, bound, heuristic) if result is not None: return result bound 1 return None改造时注意启发式函数必须满足可采纳性不高估真实距离否则找到的解可能不是最优。常见做法是用角块或棱块的模式数据库预计算一批状态的距离表。5.2 增加 Web 接口或图形界面命令行用久了会想要个界面。可以在main.py旁边加一个app.py用 Flask 或 FastAPI 包一层 HTTP 接口前端传打乱字符串后端返回步骤序列。# app.py from flask import Flask, request, jsonify from utils.parser import parse_string from solver.bfs import solve app Flask(__name__) app.route(/solve, methods[POST]) def solve_api(): data request.get_json() state parse_string(data[state]) steps solve(state, max_depthdata.get(max_depth, 6)) return jsonify({steps: steps or [], solved: steps is not None})这样前端可以用任意框架画魔方后端只负责算步骤。注意接口要做输入校验防止非法字符串导致求解器抛异常。5.3 步骤优化与冗余消除BFS 找到的解不一定最短可能包含冗余步骤比如U U这种互相抵消的操作。solver/optimizer.py可以做后处理扫描步骤序列合并同面连续操作消除逆操作对。# solver/optimizer.py def optimize_steps(steps): 合并同面操作消除冗余 result [] for move in steps: if result and result[-1][0] move[0]: # 同面操作合并次数 prev result.pop() total (prev.count move.count) % 4 if total 1: result.append(Move(move.face, 1)) elif total 2: result.append(Move(move.face, 2)) elif total 3: result.append(Move(move.face, 3)) else: result.append(move) return result这个优化不改变最终状态但能让步骤序列更短、更易读。改造时注意Move类的定义需要把U、U、U2统一成面加次数的形式。5.4 性能验证与回归测试改完算法后怎么确认没改坏我一般会建一个测试集包含若干已知打乱和对应最短步数跑一遍对比结果。可以用pytest写参数化测试每个用例检查求解器返回的步骤执行后是否复原。# tests/test_solver.py import pytest from utils.parser import parse_string from solver.bfs import solve from cube.moves import apply_move pytest.mark.parametrize(scramble,expected_max, [ (UUUUUUUUUDDDDDDDDDFFFFFFFFFBBBBBBBBBLLLLLLLLLRRRRRRRRR, 0), (UUUUUUUUUDDDDDDDDDFFFFFFFFFBBBBBBBBBLLLLLLLLLRRRRRRRR, 1), ]) def test_solve(scramble, expected_max): state parse_string(scramble) steps solve(state, max_depth6) assert steps is not None assert len(steps) expected_max # 执行步骤后验证复原 for move in steps: state apply_move(state, move) assert state.is_solved()这套测试跑通之后再换算法心里就有底了。从那以后我每次改求解器都强制走一遍回归测试确认新旧算法在已知用例上结果一致才敢往深了调。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

Z型提升机Solidworks设计实战:建模、装配与运动仿真的完整复盘

Z型提升机Solidworks设计实战:建模、装配与运动仿真的完整复盘

我们车间最近要上一条小产能的粉粒混合生产线,中间遇到一个很实际的输送问题:空间只有不到十米见方,物料是颗粒状含水率还不低,气力输送打不动,普通斗式提升机只能垂直走一条线,进出口不在同侧,…

2026/10/18 11:53:12 阅读更多 →
YOLO钢表面缺陷检测数据集:从零到训练全流程解析

YOLO钢表面缺陷检测数据集:从零到训练全流程解析

简介:这份面向钢表面缺陷检测的YOLO数据集,包含10000张真实场景高清图片,并同步提供VOC、COCO和YOLO三种格式标签,可直接用于YOLO系列目标检测模型的训练与验证。适合工业质检研究者、算法工程师以及正在学习目标检测的学生&#…

2026/10/18 11:53:12 阅读更多 →
轻量级NetFlow入侵检测:可解释、可演进的实战方案

轻量级NetFlow入侵检测:可解释、可演进的实战方案

简介:本资源是一套基于Python实现的机器学习网络入侵检测系统源码及完整项目说明,面向计算机安全、人工智能方向的本科生与初学者,解决课程设计、期末大作业中缺乏高可用、可复现IDS实践方案的痛点。压缩包共16个文件(17.51MB&…

2026/10/18 11:53:12 阅读更多 →

最新新闻

Android自定义SeekBar:图片背景与图片进度的实现方案与避坑指南

Android自定义SeekBar:图片背景与图片进度的实现方案与避坑指南

简介:面向Android开发者的SeekBar定制方案资源包,以图片替换系统原生样式,解决默认SeekBar外观单一、难以匹配界面整体设计的问题。压缩包内是一个完整的Eclipse工程示例,演示如何继承SeekBar并编写MySeekBar类,在attr…

2026/10/19 2:21:37 阅读更多 →
匹配滤波与脉冲压缩:从信噪比最大化到MATLAB仿真避坑

匹配滤波与脉冲压缩:从信噪比最大化到MATLAB仿真避坑

简介:这是一份面向雷达信号处理、数字信号处理学习者的Matlab仿真与推导资料,核心围绕线性调频(LFM)信号匹配滤波,系统讲解增益和归一化系数的来龙去脉。作者先分别推导信号和白噪声通过匹配滤波后的增益公式&#xff…

2026/10/19 2:21:37 阅读更多 →
基于RK3588的边缘AI婴儿监护系统:多模态融合与工程实践

基于RK3588的边缘AI婴儿监护系统:多模态融合与工程实践

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

2026/10/19 2:21:37 阅读更多 →
Codex 0.105.0语音编程实测:按住空格说话让AI直接写代码

Codex 0.105.0语音编程实测:按住空格说话让AI直接写代码

作为一个常年在终端里干活的人,我对"命令行工具又更新了"这种消息本来已经麻木了。但这次 Codex 0.105.0 的更新确实让我多看了两眼:按住空格键,对着终端说话,让它直接把代码写出来。听起来像demo噱头,但真正…

2026/10/19 2:21:37 阅读更多 →
专科生论文降AIGC检测全攻略:从查重到AI痕迹的实战方法

专科生论文降AIGC检测全攻略:从查重到AI痕迹的实战方法

查重率10%,AIGC疑似度91%。A同学拿着检测报告坐在我面前时,表情比论文答辩还沉重。导师的话很直接:要么把AI痕迹降下来,要么别进盲审。这不是个例。最近几个月,找我咨询论文降重的人里,专科生比例明显上升&…

2026/10/19 2:21:37 阅读更多 →
PyCharm 安装激活全流程避坑指南:从版本选择到环境配置

PyCharm 安装激活全流程避坑指南:从版本选择到环境配置

简介:面向初学Python编程语言或需要重新配置开发环境的人群,这份PyCharm安装教程以Word文档形式,完整梳理了从获取安装包、安装选项配置到激活授权的整个操作链路。文档采用分步骤讲解,先介绍在浏览器搜索入口找到下载页面&#x…

2026/10/19 2:20:36 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 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/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 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/18 0:55:02 阅读更多 →
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/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练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/18 12:16:16 阅读更多 →