news 2026/10/13 8:28:25

基于FaceNet的人脸识别与相似度匹配:原理、实现与避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于FaceNet的人脸识别与相似度匹配:原理、实现与避坑指南

简介:基于Facenet的人脸检测识别与相似性匹配毕业设计完整代码,面向计算机视觉方向本科生及人脸识别开发者,提供一套可直接运行或二次开发的全流程方案。项目以FaceNet模型为核心,覆盖人脸检测、特征向量提取、MySQL数据库写入、相似度计算与结果返回等关键环节;用户通过POST提交新图片,即可在库中检索并匹配出相似人脸。压缩包共33个文件,约3.2MB,主要包含Python源码(人脸检测、API接口、保存图片、数据库操作等)、预训练模型数据、测试图片、建表SQL、依赖清单及说明文档,目录结构清晰,便于按模块阅读理解。已有467人学习或下载。代码注释详细、功能链路完整,非常适合毕业设计演示与功能扩展,也能帮助开发者快速掌握FaceNet在实际项目中的落地思路与常见实现细节。

1. 基于 FaceNet 的人脸检测识别与相似度匹配:毕设到底在做什么

人脸识别方向的毕业设计,十个人里有八个做的都是同一个闭环:检测出人脸、把脸变成一串数字、再拿这串数字去比大小。这套逻辑里最难讲清楚、也是最容易出彩的部分,就是“把脸变成数字”这一步。Facenet 的价值恰好落在这里——它用卷积网络把人脸图像映射到 128 维特征向量,同一个人的不同照片在欧氏空间里距离很近,不同人则天然拉得很远,人脸识别和人脸相似性匹配就都统一成了向量距离计算。

这个题目适合正在选毕设方向、或者想在一个月内快速把整套流程跑通的本科/硕士生,也适合刚接触人脸识别的开发者在本地搭一套最小可用系统。读这篇文章你会得到一条主线:检测对齐、特征提取、相似度阈值、训练评估,每一步该用什么、为什么这么选、坑在哪儿。我按自己带毕设的全过程来写,不贴完整源码仓库,但代码骨架和关键参数给你,照着搭就能跑通。

2. FaceNet 的原理与选型:为什么适合做毕业设计

2.1 三元组损失:FaceNet 把人脸映射到 128 维空间的核心逻辑

FaceNet 的本质是一个卷积神经网络,输入是一张对齐后的人脸图,输出是 128 维特征向量。关键不是网络结构多深,而是它训练时用的三元组损失(Triplet Loss),这个损失函数直接决定了特征向量在欧氏空间里的分布形态。

三元组由三张图组成:锚点样本,正样本,负样本。训练目的很直观——拉近锚点与正样本的距离,推开锚点与负样本的距离。损失函数写出来大概是:

def triplet_loss(anchor, positive, negative, margin=0.2): d_pos = torch.sum((anchor - positive) ** 2, dim=1) # 同个人两张脸的距离 d_neg = torch.sum((anchor - negative) ** 2, dim=1) # 不同人两张脸的距离 loss = torch.clamp(d_pos - d_neg + margin, min=0.0) # 距离差至少要小于 -margin return loss.mean()

margin 参数控制同类和异类的距离间隔。代码里我把 margin 设为 0.2,这是原论文实验中的常用值。太大会让训练收敛困难,太小则分类边界模糊。训练完成后,直接用欧氏距离比较任意两张脸的 128 维向量,就能得到相似度分数。

注意一个容易误解的点:FaceNet 训练出来的是特征提取器,它本身不做分类。所以它不关心你训练集里有多少个人,也不需要为每个人单独加一个全连接层。这一点和用分类网络(比如 softmax 训练人脸分类器)有本质区别,也是它的长相类似于“开箱即用的特征底座”的原因。

2.2 模型选型:FaceNet 与 ArcFace、CosFace 的对比,毕设到底选哪个

人脸特征提取器现在不止 FaceNet 一种。我在带毕设时最常被问到的是:不做 FaceNet 行不行,用 ArcFace 是不是更好。这里给出横向对比,方便你根据实际需求决定。

特征提取器损失函数特点毕设适配度
FaceNetTriplet Loss特征直接对应欧氏距离,语义清晰,预训练模型多高,适合讲原理和演示
ArcFaceAngular Margin Softmax分类边界更严格,刷榜常用,但训练调参复杂中,需要大规模数据才能发挥优势
CosFaceCosine Margin类似 ArcFace,更强调余弦距离中偏下,精度高但工程资料少
传统方法(如 HOG+LBP)无无需 GPU,但精度差距明显低,除非题目硬性要求传统方法

我的建议是毕业设计优先用 FaceNet,理由有三条:第一,Triplet Loss 的直观性好,答辩的时候能讲清楚“同一人距离近、不同人距离远”这个核心思想;第二,网上可用的预训练权重和复现代码很多,不用从零训练也能完成系统演示;第三,后期做相似度匹配时,欧氏距离的阈值语义非常清楚,不涉及角度特征的额外换算。

如果你所在的课题组对识别精度有硬性要求,非要用 ArcFace,那做好训练数据准备和损失函数调参的心理准备,至少在数据量和训练时间上要比 FaceNet 多付出不少代价。

2.3 开发环境与依赖安装:一套能直接启动的环境清单

调试环境用 Python 和一个主流深度学习框架就够,不再额外引入花哨的依赖。我的习惯是把依赖写进 requirements.txt,这样换机器部署时直接一条命令重建环境。

torch>=2.0 torchvision>=0.15 opencv-python>=4.8 numpy>=1.24 Pillow>=10.0 facenet-pytorch>=2.5 matplotlib>=3.7 scikit-learn>=1.3

facenet-pytorch 这个库封装了预训练的 Inception-ResNet v1 模型和 MTCNN 检测器,拿来即用,特别适合毕设阶段快速验证思路。安装命令是pip install -r requirements.txt,装完后可以用下面这段代码验证环境是否可用。

from facenet_pytorch import InceptionResnetV1 model = InceptionResnetV1(pretrained='casia-webface').eval() print("模型加载成功,输出维度:", model.last_linear.in_features)

参数说明:pretrained='casia-webface'表示加载在公开人脸数据集上预训练好的权重;model.last_linear.in_features输出的是 512,这是 Inception-ResNet v1 模型的固定维度,不要和 FaceNet 原论文的 128 混淆,实际使用时这个数字就是特征向量的长度。如果连这一步都报错,优先检查 PyTorch 版本和网络连接,权重文件需要从网上下载。

3. 从数据集到训练:完整代码怎么组织才不留死角

3.1 数据预处理:用 MTCNN 做人脸检测与对齐,避开“脸歪导致特征乱”的坑

FaceNet 对输入数据的对齐要求很高。原论文训练时用五个人脸关键点(双眼、鼻尖、双嘴角),先把人脸旋转到统一姿态,再缩放裁剪成 160x160。如果拿未对齐的人脸图直接塞进模型,同一个人的特征向量会乱跳,相似度匹配几乎必翻车。

处理对齐的工具,工程中最常见的是 MTCNN。它同时输出人脸框和五个关键点坐标,你再根据关键点做相似变换。facenet-pytorch 里已经内置了封装好的版本,不需要自己从头实现检测器。

from facenet_pytorch import MTCNN from PIL import Image mtcnn = MTCNN( image_size=160, # 输出图像尺寸,FaceNet 的固定输入 margin=0, # 是否在检测框外圈扩充像素 keep_all=False, # True 返回所有检测脸,False 只返回置信度最高的一张 post_process=True # 做像素归一化到 [-1, 1] ) img = Image.open("demo.jpg") face_tensor = mtcnn(img) # 返回 [1, 3, 160, 160] 的归一化张量,未检测到人脸时返回 None

这里有几个必调参数要解释清楚。image_size必须等于后续 FaceNet 模型的输入尺寸,改了它模型会直接报错或者严重掉点。keep_all在做单人识别时必须设为 False,否则多人图片会返回多张脸,后续特征提取代码就乱了。margin我设为 0,因为 MTCNN 默认框本身就紧贴人脸,再扩容易混入背景噪声。

对齐做完后,建议把处理好的 160x160 人脸图存成预处理数据集,而不是每次训练都现跑检测器。磁盘只多占几百 MB,但训练速度能快出好几倍,我见过不少同学每次训练都重新跑 MTCNN,一个 epoch 跑两小时,纯属和自己过不去。

3.2 训练脚本的结构设计:预训练权重、Triplet Loss、验证逻辑拆开写

训练脚本是毕设代码里最需要讲清楚结构的部分。我不建议把所有逻辑写在一个几百行的 .py 文件里,答辩时很难向评委交代清楚。习惯上是分成四个模块:数据加载与预处理、特征提取模型、损失函数和训练主循环、评估脚本。

特征提取模型的定义十分简洁,因为主干网络直接复用预训练的 Inception-ResNet v1:

import torch.nn as nn from facenet_pytorch import InceptionResnetV1 class FaceNetModel(nn.Module): def __init__(self, embedding_size=512): super().__init__() self.backbone = InceptionResnetV1(pretrained='casia-webface').eval() self.backbone.last_linear = nn.Linear(512, embedding_size) def forward(self, x): return self.backbone(x) # 输出已做 L2 归一化

训练主循环的关键点在于三元组采样。三元组并不是网络跑完自动生成的,你得从数据里构造每个 batch 的 anchor、positive、negative。常见做法是在一个 batch 里随机选 P 个人,每个人选 K 张图,凑成 P×K 张图,然后动态生成三元组。我在毕设代码里常用这种“在线三元组挖掘”策略。

def online_triplet_mining(features, labels, margin=0.2): """输入一个 batch 的特征和标签,返回参与计算 loss 的三元组索引""" cos_sim = torch.matmul(features, features.T) # 特征已经 L2 归一化,内积即余弦相似度 # 对每个样本,找到最难的正样本(距离最远的同类)和最难负样本(距离最近的异类) for i in range(features.size(0)): pos_mask = (labels == labels[i]) & (torch.arange(labels.size(0)) != i) neg_mask = labels != labels[i] hardest_positive = torch.max(cos_sim[i][pos_mask]) # 最难正样本,相似度最低 hardest_negative = torch.min(cos_sim[i][neg_mask]) # 最难负样本,相似度最高 triplet = (i, hardest_positive_idx, hardest_negative_idx) loss = torch.clamp(cos_sim[i][hardest_negative_idx] - cos_sim[i][hardest_positive_idx] + margin, min=0)

训练轮数不用太多。有预训练权重的情况下,在自建数据集上微调 10 到 15 个 epoch 就够。学习率从较低数值起步,例如1e-4,每 5 个 epoch 衰减为原来的 0.1 倍。batch size 受限于显存,一般设 16 到 32,P 取 4、K 取 4 或 P=8、K=2 都常见。

3.3 模型评估与验证:用 LFW 风格的图像对协议算准确率

很多毕设写到这里,只拿两张图比一下相似度就说“效果很好”,这在答辩场上是站不住脚的。正规做法是仿照 LFW 评估协议:准备一堆相同身份和不同身份的图像对,模型对每对算相似度分数,再统计不同阈值下的准确率、错误接受率、错误拒绝率。

评估代码的核心就是算一批图像对的特征向量相似度,再对比标注标签。下面是一个可跑通的评估骨架:

def evaluate_pairs(model, pairs, threshold=1.0, device='cuda'): model.eval() y_true, y_scores = [], [] with torch.no_grad(): for img1, img2, same_person in pairs: emb1 = model(img1.unsqueeze(0).to(device)) # [1, 512] emb2 = model(img2.unsqueeze(0).to(device)) dist = torch.dist(emb1, emb2, p=2).item() # 欧氏距离 y_scores.append(dist) y_true.append(int(same_person)) # 用 sklearn 计算指定阈值下的指标 from sklearn.metrics import accuracy_score pred = [1 if s < threshold else 0 for s in y_scores] return accuracy_score(y_true, pred) threshold = 1.0 # 欧氏距离小于该阈值判定为同一人 acc = evaluate_pairs(model, test_pairs, threshold=threshold) print(f"Threshold={threshold} Accuracy={acc:.4f}")

这段代码的关键参数是threshold。FaceNet 论文里的经验值大约是 0.75 到 1.0 之间,但这是针对 128 维特征的标准。如果用的代码库输出 512 维,阈值通常要往上调到 1.5 左右。原因是一个特征向量各维分布不同,维度越多,欧氏距离的期望值越大,不能直接照搬论文数字。

评估时候还有一个肉眼可见的大坑:图像对选出来之后,两张图片都必须过 MTCNN 对齐并裁成 160x160,如果让原图直接进模型,评估结果会比真实水平差一大截,而且你无法区分是模型问题还是预处理问题。

4. 人脸识别与相似度匹配的工程实现:从特征到业务闭环

4.1 检测、对齐、提取特征、比对:串联完整流程的代码骨架

工程上的人脸识别不是一个模型单独完成的,而是检测器与特征提取器串联工作。检测器负责找人,特征提取器负责认人。两个模型各有各的输入输出,不能混在一起。

我给毕设搭过一个现成的调用顺序,这段代码可以封装成一个类,在 Flask 或 Qt 界面里复用:

from facenet_pytorch import MTCNN, InceptionResnetV1 import torch from PIL import Image class FaceMatcher: def __init__(self, threshold=1.5, device='cuda'): self.device = device self.mtcnn = MTCNN(image_size=160, keep_all=False).to(device) self.model = InceptionResnetV1(pretrained='casia-webface').eval().to(device) self.threshold = threshold self.feature_db = {} # 注册库:名字 -> 特征向量 def extract_face(self, image: Image.Image): face_tensor = self.mtcnn(image) # 检测并对齐人脸 if face_tensor is None: return None with torch.no_grad(): feature = self.model(face_tensor.unsqueeze(0).to(self.device)) return feature.squeeze(0).cpu() # [512] 向量 def register(self, name: str, image: Image.Image): feature = self.extract_face(image) if feature is not None: self.feature_db[name] = feature def identify(self, image: Image.Image): """返回 (人名, 距离),匹配失败时人名为 None""" feature = self.extract_face(image) if feature is None: return None, None best_name, best_dist = None, float('inf') for name, db_feat in self.feature_db.items(): dist = torch.dist(feature, db_feat, p=2).item() if dist < best_dist: best_dist, best_name = dist, name if best_dist < self.threshold: return best_name, best_dist return None, best_dist

这个类的设计有明显的分层:extract_face只负责从图像到特征,register负责注册库,identify负责检索。注册库的feature_db可以换成数据库或者 redis,但保留统一接口是关键,答辩时你只要说一句“识别过程就是查特征库”就足够清楚。

4.2 相似度阈值怎么定:欧氏距离与余弦相似度的两套刻度

工程里头最玄学的就是这个阈值。阈值定高了,陌生人容易混进来;定低了,本人又经常被拒。不同的预训练模型、不同的对齐方式,合适的阈值都不一样,所以正确的做法不是抄别人的数字,而是在自己的验证集上重算。

常见的相似度度量有两种:欧氏距离和余弦相似度。它俩只是刻度不同,本质上可以换算。face 向量 L2 归一化后,欧氏距离d和余弦相似度cos的关系是d^2 = 2 - 2cos。也就是说,阈值总是成对的,不要混用标准。

度量方式含义阈值经验范围判断规则
欧氏距离向量终点间的直线距离1.2 ~ 1.6小于阈值为同一人
余弦相似度向量夹角余弦值0.6 ~ 0.8大于阈值为同一人

这个表的经验值建立在 512 维输出和 MTCNN 对齐的前提下。如果你换用了 128 维输出的模型变体,或者手工对齐,误差会很明显。我在某个模拟项目里测过一次,直接用 128 维模型的阈值去匹配 512 维模型,陌生人误识率直接翻了三倍,最后老老实实重新按验证集的分布定阈值。

实操中的定标方法是:在验证集里不停换阈值,画出 ROC 曲线定位“误接受率”和“误拒绝率”交点,然后在交点附近微调。如果你对界面展示要求不高,更直接的办法是统计自己系统里 30 张真脸对和 30 张假脸对的距离分布,取正中间为初始阈值。

4.3 实时识别的最小实现:摄像头画面里框出人并显示姓名

做完静态图的匹配,毕设功能就要往实时方向推进了。实时识别的核心是控制推理频率,不要每帧都跑检测和特征提取,否则 CPU/GPU 占用高到界面卡死。

我的经验法则是:MTCNN 检测每帧都跑,但 FaceNet 特征提取只在检测到新脸的时候触发,且同一张跟踪框内的脸不重复提取。这个逻辑用 OpenCV 的 VideoCapture 就能搭出来:

import cv2 cap = cv2.VideoCapture(0) matcher = FaceMatcher(threshold=1.5) while cap.isOpened(): ret, frame = cap.read() if not ret: break rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) name, dist = matcher.identify(Image.fromarray(rgb)) if name: cv2.putText(frame, f"{name} ({dist:.2f})", (20, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) cv2.imshow("Face Recognition", frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()

注意代码里identify每帧都会执行完整检测+识别,仅适合演示,后续优化方向是加上追踪器,只对新人脸做特征提取,老脸直接沿用已有身份标签。这里要先保证识别流程正确,再谈性能优化,千万别反过来,否则界面出了 bug 你都不知道是检测问题还是追踪问题。

5. 毕设避坑指南:训练和部署中常见的 5 类翻车现场

5.1 训练 Loss 不降反升,准确率全看运气

现象:用预训练模型微调,loss 一直震荡,验证准确率飘忽不定,今天测同一张脸能识别,明天距离就超阈值了。 原因:最常见的是训练数据没有做严格对齐,同一人的照片有正面、低头、侧脸,模型的特征被“搅浑”。其次是学习率设太大,把预训练权重破坏了;还有一个隐蔽问题:三元组采样方式不对,batch 里如果每个身份只有一张图,根本无法生成正样本对。 解决:先可视化预处理后的数据,确认每张脸都被 MTCNN 对齐成统一姿态。把学习率降到1e-4以下,并检查 batch 内的 P×K 结构是否满足“至少两个人、每人至少两张图”。如果还不行,干脆冻结 backbone 的前面几层,只微调最后一个残差块和输出层。

5.2 测试集上准确率不错,一到现场识别就崩

现象:离线评估准确率 95%,拿摄像头一测,本人偶尔识别不出来,陌生人又频繁被误认。 原因:现场光照和训练集差异太大,MTCNN 把脸框得不够稳,导致输入的 160x160 图像内容抖动。另一个原因是你只在公开数据集的图像对上定阈值,没在当前摄像头场景里重新标定。 解决:在部署房间采集 20 到 30 张包含本人和其他人的照片,重新计算阈值。如果光照影响严重,给 MTCNN 加一点预处理:先做直方图均衡化,再检测人脸。不要盲目换大模型,先把输入侧稳定住。

5.3 GPU 显存溢出,batch size 调到 8 还是报错

现象:训练一开始就报 CUDA out of memory,把 batch size 从 32 一路降到 8 依然失败。 原因:显存消耗不只是 batch size 决定的,MTCNN 在训练阶段如果被错误地放进 CUDA 图里一起反向传播,会额外吃掉大量显存;另外 160x160 的输入在 Inception-ResNet v1 中通道数多,特征图占用也大。 解决:让 MTCNN 只负责数据预处理,不参与梯度计算,最好在数据加载阶段就把它放到 CPU 上执行。混精度训练也能省一半显存,PyTorch 中开启torch.autocast(device_type='cuda', dtype=torch.float16)即可。如果还不足,把输入用 128x128 代替 160x160,在微调阶段精度损失通常有限。

5.4 预训练模型下载卡住或校验失败,训练无法继续

现象:代码跑到加载权重就停住,日志显示下载超时,或者加载时提示文件哈希不匹配。 原因:不少预训练权重托管在境外地址,国内网络访问经常断流,下载一半失败;哈希不匹配的情况多见于网络不稳定导致文件损坏。 解决:不要用代码内下载的方式死磕。换个网络源或者找网友整理好的镜像包,手动下载权重文件,再用绝对路径加载:

model = InceptionResnetV1() state_dict = torch.load("path/to/weights.pt", map_location='cpu') model.load_state_dict(state_dict)

5.5 识别速度太慢,摄像头画面明显卡顿

现象:实时识别时帧率只有 3 到 5 FPS,画面掉帧严重,演示时体验不佳。 原因:每帧都跑一遍完整 MTCNN 检测加 FaceNet 特征提取,模型本身在 CPU 上推理,或者显卡性能较弱,重复计算太多。 解决:两个方向。一是把 FaceNet 换成更小的结构,比如 MobileFaceNet,特征维度还是 512,速度提升 3 倍以上;二是做推理优化,将模型导出为 ONNX 后开启批处理。如果只是为了答辩演示,控制识别频率为每秒两次,画面流畅度立刻改善,损失一点实时性但视觉上几乎察觉不到。

6. 让毕设上台阶:模型导出、量化与接口服务化的三个加分技巧

毕业设计做到“能识别”只能拿基础分,真正拉开差距的是把系统做成可交付的东西。我建议下一个步骤是抛弃 Jupyter Notebook,把训练好的 FaceNet 模型导出为 ONNX,部署成一个本地服务。你只需要在答辩现场打开浏览器,上传照片就能实时返回相似度结果,这比现场敲代码稳定得多。

导出 ONNX 时注意把批处理维度设为动态,这样既能单张推理又能批量请求。量化方面,FP16 精度在 GPU 上几乎没有肉眼可见的掉点,体积能减小一半;如果你的部署目标是 CPU,可以试试动态量化,用 PyTorch 的torch.quantization.quantize_dynamic一行代码完成,但人脸特征提取对数值敏感度较高,务必用同一批验证集重新测一遍阈值。

最后把识别封装成一个轻量接口,用 FastAPI 起服务,核心逻辑是接收上传图片,调用FaceMatcher.identify,返回 JSON 格式的姓名和距离。这里有一个细节:上传的图片尺寸可能很大,而 MTCNN 对分辨率过高的输入内存开销陡增,建议先限制短边尺寸不超过 800 像素。

我栽过的最大一个跟头是展示时忘了关掉 Debug 模式,结果 FastAPI 自带的交互文档把接口暴露得清清楚楚,现场跑了半天才发现输入输出的数据格式没封装好,评委一眼就看到底层实现。后来所有服务都统一走固定输入输出结构,内部用 DTO 兜底,展示时就顺滑了。

希望这篇文章能帮你把人脸识别的毕设从“能跑”推进到“能讲清楚、能演示、能答辩”。做到对齐、阈值和模型选型这三件事,你的毕业设计就已经超过九成的人。祝顺利。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/13 8:28:23

Claude+Codex+Grok三AI协作工作流:个人开发者的王炸组合

凌晨一点&#xff0c;我盯着屏幕上三列终端窗口&#xff0c;左边是Claude在梳理整个项目的依赖关系&#xff0c;中间是Codex在批量生成后端接口&#xff0c;右边是Grok在揪一段递归逻辑里的边界条件。三个AI助手各干各的活&#xff0c;互不打扰&#xff0c;但产出却在同一个代码…

作者头像 李华
网站建设 2026/10/13 8:27:37

用OpenClaw统一对接多云AI服务:从API适配到生产级实践

前阵子我给内部一个自动化工具加AI能力&#xff0c;原本以为就是申请一个云端的模型接口&#xff0c;把请求发过去、把结果接回来。真动起手来才发现&#xff0c;市面上的云端AI服务远不止「大语言模型」一种&#xff0c;语音转写、图片理解、向量检索、内容安全审核&#xff0…

作者头像 李华
网站建设 2026/10/13 8:26:41

GEO优化半年无效?揭秘AI搜索为何不引用你的品牌

如果你连续半年雷打不动地更新博客、铺外链、调TDK&#xff0c;Google排名甚至肉眼可见地往上爬&#xff0c;但打开任意一个带AI搜索的对话框&#xff0c;问一句“这个领域里有哪些值得关注的品牌”&#xff0c;回答里却始终没有你的名字——先别急着骂算法。这个问题大概率不是…

作者头像 李华
网站建设 2026/10/13 8:26:08

Java八种基本类型详解:内存逻辑、笔试陷阱与工程选型

"Java语言提供了八种基本类型"——这句话你八成在教材、题库、技术博客里都见过&#xff0c;后面跟着的【二十23】这种编号&#xff0c;基本可以断定是哪套笔试题里的题目序号。我见过太多人看到这句话&#xff0c;第一反应是立刻背诵&#xff1a;byte、short、int、…

作者头像 李华
网站建设 2026/10/13 8:26:07

配电网重构与辐射状拓扑约束:断线解环建模及Matlab实现

配电网重构、网架规划、分布式电源接入优化&#xff0c;只要你在做这几个方向&#xff0c;一定被“辐射状拓扑约束”折磨过。需求听起来很简单&#xff1a;配电网正常运行必须是树状结构&#xff0c;不能有环&#xff0c;所有负荷还得连通到电源。可要把这句大白话翻译成优化模…

作者头像 李华
网站建设 2026/10/13 8:25:49

UVa 1084 Deer-Proof Fence:状态压缩集合覆盖与候选圆生成

第一次在题单里看到 “UVa 1084 Deer-Proof Fence” 的时候&#xff0c;我以为是个纯几何模拟题&#xff1a;给围栏、给坐标&#xff0c;算算有没有鹿能钻进去就完事。结果读完题发现完全不是那回事——这题表面是围栏&#xff0c;内核是把一堆点分成尽量少的组&#xff0c;每组…

作者头像 李华