用Weisfeiler-Lehman 图核 计算solidworks零件的拓扑相似度

news2026/3/21 6:02:50
相似度分析报告 TOP-5 最相似零件对: 1. ZC6001.SLDPRT - ZC698.SLDPRT: 1.0000 (100.00%) 2. .01-111.SLDPRT - .30.00-36.4..SLDPRT: 1.0000 (100.00%) 3. ZC6001.SLDPRT - ZC6904.SLDPRT: 1.0000 (100.00%) 4. ZC6001.SLDPRT - ZC6902.SLDPRT: 1.0000 (100.00%) 5. ZC6902.SLDPRT - ZC6904.SLDPRT: 1.0000 (100.00%) 最不相似的零件对: 1. 内六角螺丝M6X35末端打孔.SLDPRT - 手柄套.SLDPRT: 0.1459 (14.59%) 2. .01-101预送带电机座.SLDPRT - 内六角螺丝M6X35末端打孔.SLDPRT: 0.1559 (15.59%) 3. .01-101预送带电机座.SLDPRT - .00-36.15预送带拉簧.SLDPRT: 0.1636 (16.36%) 统计信息: 平均相似度0.3970 (39.70%) 最大相似度1.0000 (100.00%) 最小相似度0.1459 (14.59%) 零件拓扑相似度矩阵 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 : 1.000 0.187 0.307 0.351 0.601 0.193 0.300 0.351 0.318 0.452 0.435 0.298 0.352 0.374 0.374 0.374 0.374 0.236 0.263 0.484 0.175 0.608 2 : 0.187 1.000 0.579 0.588 0.200 0.528 0.164 0.588 0.540 0.195 0.297 0.329 0.385 0.195 0.195 0.195 0.195 0.269 0.156 0.466 0.470 0.218 3 : 0.307 0.579 1.000 0.768 0.321 0.537 0.264 0.768 0.639 0.350 0.425 0.369 0.594 0.342 0.342 0.342 0.342 0.491 0.296 0.598 0.517 0.344 4 : 0.351 0.588 0.768 1.000 0.350 0.511 0.234 1.000 0.671 0.305 0.385 0.375 0.466 0.276 0.276 0.276 0.276 0.297 0.218 0.678 0.504 0.371 5 : 0.601 0.200 0.321 0.350 1.000 0.210 0.391 0.350 0.326 0.414 0.431 0.271 0.351 0.345 0.345 0.345 0.345 0.298 0.386 0.453 0.171 0.635 6 : 0.193 0.528 0.537 0.511 0.210 1.000 0.202 0.511 0.503 0.229 0.362 0.297 0.467 0.247 0.247 0.247 0.247 0.371 0.195 0.500 0.424 0.249 7 : 0.300 0.164 0.264 0.234 0.391 0.202 1.000 0.234 0.228 0.420 0.326 0.346 0.335 0.450 0.450 0.450 0.450 0.398 0.493 0.310 0.255 0.312 8 : 0.351 0.588 0.768 1.000 0.350 0.511 0.234 1.000 0.671 0.305 0.385 0.375 0.466 0.276 0.276 0.276 0.276 0.297 0.218 0.678 0.504 0.371 9 : 0.318 0.540 0.639 0.671 0.326 0.503 0.228 0.671 1.000 0.294 0.370 0.357 0.416 0.269 0.269 0.269 0.269 0.303 0.213 0.516 0.466 0.343 10 : 0.452 0.195 0.350 0.305 0.414 0.229 0.420 0.305 0.294 1.000 0.413 0.435 0.438 0.705 0.705 0.705 0.705 0.416 0.307 0.405 0.346 0.435 11 : 0.435 0.297 0.425 0.385 0.431 0.362 0.326 0.385 0.370 0.413 1.000 0.233 0.532 0.384 0.384 0.384 0.384 0.454 0.306 0.537 0.214 0.549 12 : 0.298 0.329 0.369 0.375 0.271 0.297 0.346 0.375 0.357 0.435 0.233 1.000 0.273 0.448 0.448 0.448 0.448 0.235 0.204 0.340 0.491 0.260 13 : 0.352 0.385 0.594 0.466 0.351 0.467 0.335 0.466 0.416 0.438 0.532 0.273 1.000 0.445 0.445 0.445 0.445 0.680 0.389 0.619 0.323 0.423 14 : 0.374 0.195 0.342 0.276 0.345 0.247 0.450 0.276 0.269 0.705 0.384 0.448 0.445 1.000 1.000 1.000 1.000 0.442 0.293 0.389 0.351 0.368 15 : 0.374 0.195 0.342 0.276 0.345 0.247 0.450 0.276 0.269 0.705 0.384 0.448 0.445 1.000 1.000 1.000 1.000 0.442 0.293 0.389 0.351 0.368 16 : 0.374 0.195 0.342 0.276 0.345 0.247 0.450 0.276 0.269 0.705 0.384 0.448 0.445 1.000 1.000 1.000 1.000 0.442 0.293 0.389 0.351 0.368 17 : 0.374 0.195 0.342 0.276 0.345 0.247 0.450 0.276 0.269 0.705 0.384 0.448 0.445 1.000 1.000 1.000 1.000 0.442 0.293 0.389 0.351 0.368 18 : 0.236 0.269 0.491 0.297 0.298 0.371 0.398 0.297 0.303 0.416 0.454 0.235 0.680 0.442 0.442 0.442 0.442 1.000 0.608 0.394 0.252 0.309 19 : 0.263 0.156 0.296 0.218 0.386 0.195 0.493 0.218 0.213 0.307 0.306 0.204 0.389 0.293 0.293 0.293 0.293 0.608 1.000 0.289 0.146 0.286 20 : 0.484 0.466 0.598 0.678 0.453 0.500 0.310 0.678 0.516 0.405 0.537 0.340 0.619 0.389 0.389 0.389 0.389 0.394 0.289 1.000 0.356 0.519 21 : 0.175 0.470 0.517 0.504 0.171 0.424 0.255 0.504 0.466 0.346 0.214 0.491 0.323 0.351 0.351 0.351 0.351 0.252 0.146 0.356 1.000 0.174 22 : 0.608 0.218 0.344 0.371 0.635 0.249 0.312 0.371 0.343 0.435 0.549 0.260 0.423 0.368 0.368 0.368 0.368 0.309 0.286 0.519 0.174 1.000using System; using System.Collections.Generic; using System.Linq; using SolidWorks.Interop.sldworks; using SolidWorks.Interop.swconst; namespace tools { /// summary /// WL 图核算法中的面图节点 /// /summary public class FaceNode { public int Id { get; set; } // 节点索引 public Face2 FaceObject { get; set; } // 面对象引用 public string FaceType { get; set; } // 面类型标签 public double Area { get; set; } // 面积 public Listint NeighborIds { get; set; } // 邻居节点索引列表 public string CurrentLabel { get; set; } // 当前迭代标签 public FaceNode() { NeighborIds new Listint(); } } /// summary /// 零件的面邻接图表征 /// /summary public class PartGraph { public string PartName { get; set; } // 零件名称 public ListFaceNode Nodes { get; set; } // 节点列表 public Dictionarystring, int LabelFrequency { get; set; } // 标签频率统计 public PartGraph() { Nodes new ListFaceNode(); LabelFrequency new Dictionarystring, int(); } } /// summary /// 从 SolidWorks 零件构建面邻接图 /// /summary public static class FaceGraphBuilder { /// summary /// 从零件文档构建面邻接图 /// /summary public static PartGraph BuildGraph(ModelDoc2 swModel, string partName ) { if (swModel null) { Console.WriteLine(错误没有打开的活动文档。); return null; } PartDoc partDoc (PartDoc)swModel; PartGraph graph new PartGraph(); graph.PartName string.IsNullOrEmpty(partName) ? swModel.GetTitle() : partName; // 存储邻接关系的字典面索引 - 邻居面索引集合 var adjacencyDict new Dictionaryint, HashSetint(); var faceIndexMap new DictionaryFace2, int(); var facesList new ListFace2(); int faceCount 0; // 获取所有实体 object[] vBodies (object[])partDoc.GetBodies2((int)swBodyType_e.swSolidBody, false); if (vBodies null || vBodies.Length 0) { Console.WriteLine(警告未找到实体 body); return graph; } // 遍历所有 body提取面和邻接关系 foreach (Body2 body in vBodies) { object[] vEdges (object[])body.GetEdges(); if (vEdges null) continue; foreach (Edge edge in vEdges) { var twoAdjacentFaces (object[])edge.GetTwoAdjacentFaces(); if (twoAdjacentFaces null || twoAdjacentFaces.Length 2) continue; Face2 face1 (Face2)twoAdjacentFaces[0]; Face2 face2 (Face2)twoAdjacentFaces[1]; // 为每个面分配唯一索引 if (!faceIndexMap.ContainsKey(face1)) { faceIndexMap[face1] faceCount; facesList.Add(face1); } if (!faceIndexMap.ContainsKey(face2)) { faceIndexMap[face2] faceCount; facesList.Add(face2); } int index1 faceIndexMap[face1]; int index2 faceIndexMap[face2]; // 初始化邻接矩阵条目 if (!adjacencyDict.ContainsKey(index1)) adjacencyDict[index1] new HashSetint(); if (!adjacencyDict.ContainsKey(index2)) adjacencyDict[index2] new HashSetint(); // 添加邻接关系 adjacencyDict[index1].Add(index2); adjacencyDict[index2].Add(index1); } } // 创建节点并分配初始标签 for (int i 0; i faceCount; i) { Face2 face facesList[i]; Surface surface face.IGetSurface(); // 确定面类型 string faceType GetFaceType(surface); // 计算面积 (mm²) double area Math.Round(face.GetArea() * 1000000, 2); FaceNode node new FaceNode { Id i, FaceObject face, FaceType faceType, Area area, CurrentLabel faceType, // 初始标签为面类型 NeighborIds adjacencyDict.ContainsKey(i) ? adjacencyDict[i].ToList() : new Listint() }; graph.Nodes.Add(node); } Console.WriteLine($零件 [{graph.PartName}] 构建完成{faceCount} 个面); return graph; } /// summary /// 根据曲面几何特性确定面类型 /// /summary private static string GetFaceType(Surface surface) { if (surface.IsPlane()) return 平面; if (surface.IsCylinder()) return 圆柱面; if (surface.IsCone()) return 圆锥面; if (surface.IsSphere()) return 球面; if (surface.IsTorus()) return 圆环面; return 其他曲面; } } }using System; using System.Collections.Generic; using System.IO; using SolidWorks.Interop.sldworks; using SolidWorks.Interop.swconst; namespace tools { /// summary /// 批量计算零件拓扑相似度 /// /summary public static class SimilarityCalculator { /// summary /// 从文件夹中加载所有零件并构建图 /// /summary public static ListPartGraph LoadPartsFromFolder(string folderPath, ISldWorks swApp) { var graphs new ListPartGraph(); if (!Directory.Exists(folderPath)) { Console.WriteLine($错误文件夹不存在 - {folderPath}); return graphs; } // 获取所有 SolidWorks 零件文件 string[] partFiles Directory.GetFiles(folderPath, *.sldprt, SearchOption.AllDirectories); Console.WriteLine($在文件夹中找到 {partFiles.Length} 个零件文件\n); foreach (string file in partFiles) { // 跳过 SolidWorks 临时文件 string fileName Path.GetFileName(file); if (fileName.StartsWith(~$)) { Console.WriteLine($跳过临时文件{fileName}); continue; } try { Console.WriteLine($正在加载{fileName}); int errors 0; int warnings 0; // 打开零件文档 ModelDoc2 model swApp.OpenDoc6( file, (int)swDocumentTypes_e.swDocPART, (int)swOpenDocOptions_e.swOpenDocOptions_Silent, , ref errors, ref warnings); if (model ! null) { // 构建图结构 PartGraph graph FaceGraphBuilder.BuildGraph(model, Path.GetFileName(file)); if (graph ! null graph.Nodes.Count 0) { graphs.Add(graph); } // 关闭文档 swApp.CloseDoc(model.GetTitle()); } else { Console.WriteLine($ 打开失败错误代码{errors}); } } catch (Exception ex) { Console.WriteLine($ 处理文件时出错{ex.Message}); } } Console.WriteLine($\n成功加载 {graphs.Count} 个零件的图结构); return graphs; } /// summary /// 从当前已打开的零件中构建图列表 /// /summary public static ListPartGraph BuildGraphsFromOpenParts(ModelDoc2[] models, string[] names null) { var graphs new ListPartGraph(); for (int i 0; i models.Length; i) { if (models[i] ! null) { string name names ! null names.Length i ? names[i] : models[i].GetTitle(); PartGraph graph FaceGraphBuilder.BuildGraph(models[i], name); if (graph ! null graph.Nodes.Count 0) { graphs.Add(graph); } } } return graphs; } /// summary /// 计算单个零件对的相似度 /// /summary public static double CalculatePairSimilarity(PartGraph graph1, PartGraph graph2, int iterations 3) { Console.WriteLine($\n计算零件对相似度:); Console.WriteLine($ 零件 1: {graph1.PartName} ({graph1.Nodes.Count} 个面)); Console.WriteLine($ 零件 2: {graph2.PartName} ({graph2.Nodes.Count} 个面)); // 执行 WL 迭代 var freqList1 WLGraphKernel.PerformWLIterations(graph1, iterations); var freqList2 WLGraphKernel.PerformWLIterations(graph2, iterations); // 计算综合相似度 double similarity WLGraphKernel.CalculateComprehensiveSimilarity(freqList1, freqList2); Console.WriteLine($\n最终相似度{similarity:F4} ({similarity * 100:F2}%)); return similarity; } /// summary /// 运行完整分析流程 /// /summary public static void RunAnalysis(ListPartGraph graphs, int wlIterations 3, double decayFactor 0.5) { if (graphs null || graphs.Count 2) { Console.WriteLine(警告至少需要 2 个零件才能计算相似度); return; } Console.WriteLine($\n{*60}); Console.WriteLine(开始 Weisfeiler-Lehman 图核拓扑相似度分析); Console.WriteLine(${*60}); Console.WriteLine($零件数量{graphs.Count}); Console.WriteLine($WL 迭代次数{wlIterations}); Console.WriteLine($权重衰减因子{decayFactor}); Console.WriteLine(${*60}\n); // 打印每个零件的基本信息 Console.WriteLine(零件列表:); for (int i 0; i graphs.Count; i) { var graph graphs[i]; Console.WriteLine($ {i 1}. {graph.PartName,-40} [{graph.Nodes.Count} 个面]); } Console.WriteLine(); // 计算相似度矩阵 double[,] matrix WLGraphKernel.ComputeSimilarityMatrix(graphs, wlIterations, decayFactor); // 输出详细报告 OutputDetailedReport(matrix, graphs); } /// summary /// 输出详细分析报告 /// /summary private static void OutputDetailedReport(double[,] matrix, ListPartGraph graphs) { int n matrix.GetLength(0); Console.WriteLine(\n 相似度分析报告 \n); // 找出最相似的零件对 var pairs new List(int i, int j, double similarity)(); for (int i 0; i n; i) { for (int j i 1; j n; j) { pairs.Add((i, j, matrix[i, j])); } } // 按相似度排序 pairs.Sort((a, b) b.similarity.CompareTo(a.similarity)); Console.WriteLine(TOP-5 最相似零件对:); for (int k 0; k Math.Min(5, pairs.Count); k) { var pair pairs[k]; Console.WriteLine($ {k 1}. {graphs[pair.i].PartName} - {graphs[pair.j].PartName}: ${pair.similarity:F4} ({pair.similarity * 100:F2}%)); } Console.WriteLine(\n最不相似的零件对:); pairs.Reverse(); for (int k 0; k Math.Min(3, pairs.Count); k) { var pair pairs[k]; Console.WriteLine($ {k 1}. {graphs[pair.i].PartName} - {graphs[pair.j].PartName}: ${pair.similarity:F4} ({pair.similarity * 100:F2}%)); } // 统计信息 double avgSimilarity 0.0; double maxSimilarity 0.0; double minSimilarity 1.0; foreach (var pair in pairs) { avgSimilarity pair.similarity; if (pair.similarity maxSimilarity) maxSimilarity pair.similarity; if (pair.similarity minSimilarity) minSimilarity pair.similarity; } avgSimilarity / pairs.Count; Console.WriteLine(\n统计信息:); Console.WriteLine($ 平均相似度{avgSimilarity:F4} ({avgSimilarity * 100:F2}%)); Console.WriteLine($ 最大相似度{maxSimilarity:F4} ({maxSimilarity * 100:F2}%)); Console.WriteLine($ 最小相似度{minSimilarity:F4} ({minSimilarity * 100:F2}%)); Console.WriteLine(\n\n); } } }using System; using SolidWorks.Interop.sldworks; using tools; namespace recognize.train_use { /// summary /// WL 图核算法测试示例 /// /summary public class test_wl_graph_kernel { /// summary /// 测试当前打开的零件 /// /summary public static void RunTest(ISldWorks swApp, ModelDoc2 swModel) { if (swModel null) { Console.WriteLine(错误请先打开一个零件文档); return; } Console.WriteLine(\n WL 图核测试 \n); // 构建单个零件的图 PartGraph graph FaceGraphBuilder.BuildGraph(swModel); if (graph null || graph.Nodes.Count 0) { Console.WriteLine(无法构建图结构); return; } // 打印节点信息 Console.WriteLine($\n图结构信息:); Console.WriteLine($ 零件名称{graph.PartName}); Console.WriteLine($ 节点数量{graph.Nodes.Count}); // 统计面类型分布 var faceTypeStats new System.Collections.Generic.Dictionarystring, int(); foreach (var node in graph.Nodes) { if (!faceTypeStats.ContainsKey(node.FaceType)) { faceTypeStats[node.FaceType] 0; } faceTypeStats[node.FaceType]; } Console.WriteLine($\n 面类型分布:); foreach (var kvp in faceTypeStats) { Console.WriteLine($ {kvp.Key,-10}: {kvp.Value} 个); } // 执行 WL 迭代 Console.WriteLine($\n执行 WL 迭代...); var freqList WLGraphKernel.PerformWLIterations(graph, iterations: 3); // 显示每次迭代的标签频率 for (int i 0; i freqList.Count; i) { Console.WriteLine($\n 迭代 {i}:); foreach (var kvp in freqList[i]) { Console.WriteLine($ {kvp.Key}: {kvp.Value} 次); } } Console.WriteLine(\n\n); } /// summary /// 比较两个零件的相似度 /// /summary public static void CompareTwoParts(ISldWorks swApp, ModelDoc2 model1, ModelDoc2 model2) { if (model1 null || model2 null) { Console.WriteLine(错误需要两个有效的零件文档); return; } Console.WriteLine(\n 零件相似度对比 \n); // 构建两个零件的图 PartGraph graph1 FaceGraphBuilder.BuildGraph(model1, 零件 A); PartGraph graph2 FaceGraphBuilder.BuildGraph(model2, 零件 B); if (graph1 null || graph2 null) { Console.WriteLine(无法构建图结构); return; } // 计算相似度 double similarity SimilarityCalculator.CalculatePairSimilarity(graph1, graph2, iterations: 3); // 判断结果 string conclusion; if (similarity 0.8) conclusion 高度相似 - 可能是同一系列零件; else if (similarity 0.5) conclusion 中等相似 - 具有类似的拓扑结构; else conclusion 差异较大 - 拓扑结构明显不同; Console.WriteLine($\n结论{conclusion}); Console.WriteLine(\n\n); } /// summary /// 批量分析文件夹中的零件 /// /summary public static void BatchAnalysis(ISldWorks swApp, string folderPath) { Console.WriteLine(\n 批量零件相似度分析 \n); // 从文件夹加载零件 var graphs SimilarityCalculator.LoadPartsFromFolder(folderPath, swApp); if (graphs.Count 2) { Console.WriteLine(零件数量不足至少需要 2 个零件); return; } // 运行完整分析 SimilarityCalculator.RunAnalysis(graphs, wlIterations: 3, decayFactor: 0.5); } } }using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Text; namespace tools { /// summary /// Weisfeiler-Lehman 图核实现 - 计算零件拓扑相似度 /// /summary public static class WLGraphKernel { /// summary /// 执行 WL 迭代更新节点标签 /// /summary /// param namegraph零件图/param /// param nameiterations迭代次数/param /// returns每次迭代后的标签频率列表/returns public static ListDictionarystring, int PerformWLIterations(PartGraph graph, int iterations 3) { var labelFrequenciesPerIter new ListDictionarystring, int(); if (graph null || graph.Nodes.Count 0) { Console.WriteLine(警告空图无法执行 WL 迭代); return labelFrequenciesPerIter; } // 初始化所有节点的标签 foreach (var node in graph.Nodes) { node.CurrentLabel node.FaceType; } // 统计初始迭代的标签频率 (迭代 0) var initialFreq CountLabelFrequencies(graph); labelFrequenciesPerIter.Add(initialFreq); Console.WriteLine($ 迭代 0: {initialFreq.Count} 种标签); // 执行 WL 迭代 for (int iter 1; iter iterations; iter) { // 为每个节点生成新标签 var newLabels new Dictionaryint, string(); foreach (var node in graph.Nodes) { // 收集邻居标签并排序 var neighborLabels node.NeighborIds .Select(neighborId graph.Nodes[neighborId].CurrentLabel) .OrderBy(label label) .ToList(); // 构造新标签当前标签 排序后的邻居标签集合 string combinedLabel CombineLabels(node.CurrentLabel, neighborLabels); newLabels[node.Id] combinedLabel; } // 更新所有节点的标签 foreach (var node in graph.Nodes) { node.CurrentLabel newLabels[node.Id]; } // 统计本次迭代的标签频率 var freq CountLabelFrequencies(graph); labelFrequenciesPerIter.Add(freq); Console.WriteLine($ 迭代 {iter}: {freq.Count} 种标签); } return labelFrequenciesPerIter; } /// summary /// 组合当前标签和邻居标签生成新标签 /// /summary private static string CombineLabels(string currentLabel, Liststring neighborLabels) { // 格式当前标签_ (邻居标签 1邻居标签 2...) string neighborsStr string.Join(,, neighborLabels); string combined ${currentLabel}_({neighborsStr}); // 使用 MD5 哈希压缩标签避免标签过长 return HashLabel(combined); } /// summary /// 对标签字符串进行 MD5 哈希生成短标识符 /// /summary private static string HashLabel(string label) { using (MD5 md5 MD5.Create()) { byte[] inputBytes Encoding.UTF8.GetBytes(label); byte[] hashBytes md5.ComputeHash(inputBytes); // 转换为十六进制字符串 (取前 8 个字符) StringBuilder sb new StringBuilder(); for (int i 0; i 4; i) { sb.Append(hashBytes[i].ToString(X2)); } return L sb.ToString(); // L 开头表示这是生成的标签 } } /// summary /// 统计图中各标签的出现频率 /// /summary private static Dictionarystring, int CountLabelFrequencies(PartGraph graph) { var frequency new Dictionarystring, int(); foreach (var node in graph.Nodes) { if (!frequency.ContainsKey(node.CurrentLabel)) { frequency[node.CurrentLabel] 0; } frequency[node.CurrentLabel]; } return frequency; } /// summary /// 计算两个零件的相似度 (基于单次迭代的标签频率向量点积) /// /summary public static double CalculateSimilarity( Dictionarystring, int freq1, Dictionarystring, int freq2, bool useCosine true) { if (freq1.Count 0 || freq2.Count 0) return 0.0; // 获取所有标签的并集 var allLabels new HashSetstring(freq1.Keys); allLabels.UnionWith(freq2.Keys); double dotProduct 0.0; double magnitude1 0.0; double magnitude2 0.0; // 计算点积和模长 foreach (var label in allLabels) { int count1 freq1.ContainsKey(label) ? freq1[label] : 0; int count2 freq2.ContainsKey(label) ? freq2[label] : 0; dotProduct count1 * count2; magnitude1 count1 * count1; magnitude2 count2 * count2; } magnitude1 Math.Sqrt(magnitude1); magnitude2 Math.Sqrt(magnitude2); if (useCosine) { // 余弦相似度 if (magnitude1 0 || magnitude2 0) return 0.0; return dotProduct / (magnitude1 * magnitude2); } else { // 归一化点积 double maxProduct Math.Max(freq1.Values.Sum(), freq2.Values.Sum()); if (maxProduct 0) return 0.0; return dotProduct / maxProduct; } } /// summary /// 计算两个零件的综合相似度 (加权组合多次迭代的结果) /// /summary public static double CalculateComprehensiveSimilarity( ListDictionarystring, int freqList1, ListDictionarystring, int freqList2, double decayFactor 0.5) { if (freqList1.Count 0 || freqList2.Count 0) return 0.0; int maxIterations Math.Min(freqList1.Count, freqList2.Count); double totalSimilarity 0.0; double totalWeight 0.0; // 越后面的迭代权重越低 (指数衰减) for (int i 0; i maxIterations; i) { double weight Math.Pow(decayFactor, i); double sim CalculateSimilarity(freqList1[i], freqList2[i], useCosine: true); totalSimilarity weight * sim; totalWeight weight; } return totalSimilarity / totalWeight; } /// summary /// 批量计算多个零件之间的相似度矩阵 /// /summary public static double[,] ComputeSimilarityMatrix( ListPartGraph graphs, int wlIterations 3, double decayFactor 0.5) { int n graphs.Count; double[,] similarityMatrix new double[n, n]; Console.WriteLine($\n开始计算 {n} 个零件的相似度矩阵...); // 预先计算每个零件的 WL 迭代结果 var allFrequencies new ListListDictionarystring, int(); for (int i 0; i n; i) { Console.WriteLine($\n处理零件 [{i 1}/{n}]: {graphs[i].PartName}); var freqList PerformWLIterations(graphs[i], wlIterations); allFrequencies.Add(freqList); } // 计算相似度矩阵 for (int i 0; i n; i) { for (int j 0; j n; j) { if (i j) { similarityMatrix[i, j] 1.0; // 自身相似度为 1 } else if (j i) { double sim CalculateComprehensiveSimilarity( allFrequencies[i], allFrequencies[j], decayFactor); similarityMatrix[i, j] sim; similarityMatrix[j, i] sim; // 对称矩阵 } } } // 打印相似度矩阵 PrintSimilarityMatrix(similarityMatrix, graphs.Select(g g.PartName).ToList()); return similarityMatrix; } /// summary /// 打印相似度矩阵 /// /summary private static void PrintSimilarityMatrix(double[,] matrix, Liststring partNames) { int n matrix.GetLength(0); Console.WriteLine(\n 零件拓扑相似度矩阵 ); // 打印表头 Console.Write( ); for (int j 0; j n; j) { Console.Write(${j 1,-8}); } Console.WriteLine(); // 打印每一行 for (int i 0; i n; i) { Console.Write(${i 1,-4}: ); for (int j 0; j n; j) { Console.Write(${matrix[i, j],-8:F3}); } Console.WriteLine(); } Console.WriteLine(\n零件名称对应:); for (int i 0; i n; i) { Console.WriteLine($ {i 1}. {partNames[i]}); } Console.WriteLine(\n); } } }using System; using SolidWorks.Interop.sldworks; using tools; namespace recognize.train_use { /// summary /// WL 图核使用示例 /// /summary public class wl_usage_example { /// summary /// 示例 1: 分析当前打开的零件 /// /summary public static void Example1_SinglePart(ISldWorks swApp, ModelDoc2 swModel) { // 构建图结构 PartGraph graph FaceGraphBuilder.BuildGraph(swModel); // 执行 WL 迭代 var freqList WLGraphKernel.PerformWLIterations(graph, iterations: 3); // 查看每次迭代的标签频率 for (int i 0; i freqList.Count; i) { Console.WriteLine($迭代 {i} 的标签分布:); foreach (var kvp in freqList[i]) { Console.WriteLine($ 标签 {kvp.Key}: {kvp.Value} 次); } } } /// summary /// 示例 2: 比较两个零件 /// /summary public static void Example2_CompareTwoParts(ISldWorks swApp, ModelDoc2 part1, ModelDoc2 part2) { // 构建两个零件的图 PartGraph graph1 FaceGraphBuilder.BuildGraph(part1, 零件 A); PartGraph graph2 FaceGraphBuilder.BuildGraph(part2, 零件 B); // 计算相似度 double similarity SimilarityCalculator.CalculatePairSimilarity(graph1, graph2, iterations: 3); Console.WriteLine($相似度{similarity * 100:F2}%); if (similarity 0.8) Console.WriteLine(高度相似); else if (similarity 0.5) Console.WriteLine(中等相似); else Console.WriteLine(差异较大); } /// summary /// 示例 3: 批量分析文件夹中的所有零件 /// /summary public static void Example3_BatchAnalysis(ISldWorks swApp, string folderPath) { // 从文件夹加载所有零件 var graphs SimilarityCalculator.LoadPartsFromFolder(folderPath, swApp); // 运行完整分析生成相似度矩阵 SimilarityCalculator.RunAnalysis(graphs, wlIterations: 3, decayFactor: 0.5); } /// summary /// 示例 4: 自定义 WL 参数 /// /summary public static void Example4_CustomParameters(ModelDoc2 part1, ModelDoc2 part2) { PartGraph graph1 FaceGraphBuilder.BuildGraph(part1); PartGraph graph2 FaceGraphBuilder.BuildGraph(part2); // 执行更多次 WL 迭代 (捕捉更复杂的结构) var freqList1 WLGraphKernel.PerformWLIterations(graph1, iterations: 5); var freqList2 WLGraphKernel.PerformWLIterations(graph2, iterations: 5); // 使用不同的权重衰减因子 // decayFactor0.3 表示更重视早期迭代 (局部结构) // decayFactor0.8 表示更重视后期迭代 (全局结构) double sim_fastDecay WLGraphKernel.CalculateComprehensiveSimilarity( freqList1, freqList2, decayFactor: 0.3); double sim_slowDecay WLGraphKernel.CalculateComprehensiveSimilarity( freqList1, freqList2, decayFactor: 0.8); Console.WriteLine($快速衰减相似度 (侧重局部): {sim_fastDecay * 100:F2}%); Console.WriteLine($慢速衰减相似度 (侧重全局): {sim_slowDecay * 100:F2}%); } /// summary /// 示例 5: 手动计算特定迭代的相似度 /// /summary public static void Example5_ManualCalculation(ModelDoc2 part1, ModelDoc2 part2) { PartGraph graph1 FaceGraphBuilder.BuildGraph(part1); PartGraph graph2 FaceGraphBuilder.BuildGraph(part2); var freqList1 WLGraphKernel.PerformWLIterations(graph1, iterations: 3); var freqList2 WLGraphKernel.PerformWLIterations(graph2, iterations: 3); // 单独查看某次迭代的相似度 // 迭代 0: 仅基于面类型 double sim_iter0 WLGraphKernel.CalculateSimilarity(freqList1[0], freqList2[0]); // 迭代 1: 考虑一阶邻域 double sim_iter1 WLGraphKernel.CalculateSimilarity(freqList1[1], freqList2[1]); // 迭代 2: 考虑二阶邻域 double sim_iter2 WLGraphKernel.CalculateSimilarity(freqList1[2], freqList2[2]); Console.WriteLine($迭代 0 相似度 (仅面类型): {sim_iter0 * 100:F2}%); Console.WriteLine($迭代 1 相似度 (一阶邻域): {sim_iter1 * 100:F2}%); Console.WriteLine($迭代 2 相似度 (二阶邻域): {sim_iter2 * 100:F2}%); } } }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2432458.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…