用Weisfeiler-Lehman 图核 计算solidworks零件的拓扑相似度
相似度分析报告 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
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!