当前位置: 首页 > article >正文

用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}%); } } }

相关文章:

用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: …...

Anaconda用户专属:在Ubuntu 20.04上为你的虚拟环境‘嫁接’python-pcl库

Anaconda用户专属&#xff1a;在Ubuntu 20.04上为你的虚拟环境‘嫁接’python-pcl库 对于使用Anaconda管理Python环境的开发者来说&#xff0c;有时会遇到一个棘手的问题&#xff1a;某些库只能通过系统包管理器安装&#xff0c;却无法直接用于Anaconda环境。python-pcl就是一个…...

Apache Portable Runtime (APR) 项目常见问题解决方案

Apache Portable Runtime (APR) 项目常见问题解决方案 【免费下载链接】apr Apache Apr: 这是一个Apache Apr的文档&#xff0c;用于获取Apache Apr的文档和信息。适合用于需要获取Apache Apr的文档和信息的开发者。特点包括简单易用、高性能和与Apache Apr生态系统的紧密集成。…...

企业合规新选择:LiuJuan Z-Image图片生成+AI审核一体化方案

企业合规新选择&#xff1a;LiuJuan Z-Image图片生成AI审核一体化方案 1. 企业图片生成面临的合规挑战 在数字化转型浪潮中&#xff0c;AI图片生成技术正迅速改变企业的内容生产方式。LiuJuan Z-Image Generator作为一款高性能的本地化图片生成工具&#xff0c;能够快速产出各…...

网易云音乐API 2024全新版本:一站式音乐账号管理工具深度解析

网易云音乐API 2024全新版本&#xff1a;一站式音乐账号管理工具深度解析 【免费下载链接】netease-cloud-api 网易云音乐升级API 项目地址: https://gitcode.com/gh_mirrors/ne/netease-cloud-api 网易云音乐API 2024全新版本是一款基于PHP语言开发的音乐账号管理工具&…...

GPT4、Claude3和Suno,哪个AI工具做音乐和写歌词更厉害?我的横向测评

GPT-4、Claude 3与Suno&#xff1a;三大AI音乐创作工具深度横评 去年夏天&#xff0c;当我第一次尝试用AI工具为旅行vlog配乐时&#xff0c;面对十几个音乐生成平台彻底陷入选择困难。经过半年实测三大主流工具——擅长文本的GPT-4与Claude 3、专攻音乐的Suno&#xff0c;终于整…...

AI应用架构师手记:智能生产调度系统接口自动化测试框架搭建与实践

AI应用架构师手记&#xff1a;智能生产调度系统接口自动化测试框架搭建与实践 一、引言&#xff1a;从一次产线停摆说起 凌晨3点&#xff0c;我被手机铃声惊醒——是客户生产总监的紧急电话&#xff1a;某汽车零部件工厂的智能生产调度系统突然“宕机”&#xff0c;三条产线停摆…...

如何快速掌握 SwiftyAttributes:Swift 富文本处理的终极指南

如何快速掌握 SwiftyAttributes&#xff1a;Swift 富文本处理的终极指南 【免费下载链接】SwiftyAttributes A Swifty API for attributed strings 项目地址: https://gitcode.com/gh_mirrors/sw/SwiftyAttributes SwiftyAttributes 是一个为 Swift 开发者打造的富文本处…...

OpenClaw论文写作助手:QwQ-32B辅助文献综述与格式检查

OpenClaw论文写作助手&#xff1a;QwQ-32B辅助文献综述与格式检查 1. 为什么需要AI辅助论文写作 作为一名经常需要撰写学术论文的研究人员&#xff0c;我深刻体会到论文写作过程中的痛点。从海量文献中筛选关键信息、整理参考文献、反复调整格式到最终符合期刊要求&#xff0…...

C语言编程避坑指南:SWUSTOJ期末题库中的常见错误与优化技巧

C语言编程避坑指南&#xff1a;SWUSTOJ期末题库中的常见错误与优化技巧 作为计算机专业学生必修的编程语言&#xff0c;C语言以其高效性和底层控制能力成为教学体系的核心。但在实际编程练习中&#xff0c;尤其是面对SWUSTOJ这类在线评测系统的题库时&#xff0c;初学者常常陷…...

黑丝空姐-造相Z-Turbo与ComfyUI工作流结合:实现可视化可控图像生成

黑丝空姐-造相Z-Turbo与ComfyUI工作流结合&#xff1a;实现可视化可控图像生成 1. 引言 如果你用过一些AI绘画工具&#xff0c;可能会遇到这样的困扰&#xff1a;脑子里有个很具体的画面&#xff0c;但试了好多次提示词&#xff0c;生成的图片总是不太对劲。要么是细节不对&a…...

Godot Engine集成ONLYOFFICE Docs:游戏开发中的文档处理完整指南

Godot Engine集成ONLYOFFICE Docs&#xff1a;游戏开发中的文档处理完整指南 【免费下载链接】DocumentServer ONLYOFFICE Docs is a free collaborative online office suite comprising viewers and editors for texts, spreadsheets and presentations, forms and PDF, full…...

AI生成视频短剧软件,大家知道哪个好啊?

温馨提示&#xff1a;文末有资源获取方式最近AI短剧彻底火了&#xff01;据行业数据&#xff0c;2025年仅下半年就有24部AI短剧播放量破千万&#xff0c;其中一部漫剧甚至达到2.7亿播放。当AI技术将制作成本压缩到传统短剧的10%&#xff0c;当几个人几天就能完成一部过去几十人…...

GHelper:华硕笔记本轻量级硬件调校工具全解析

GHelper&#xff1a;华硕笔记本轻量级硬件调校工具全解析 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops. Control tool for ROG Zephyrus G14, G15, G16, M16, Flow X13, Flow X16, TUF, Strix, Scar and other models 项目地址: https…...

Cowrie蜜罐插件开发教程:如何扩展自定义监控功能

Cowrie蜜罐插件开发教程&#xff1a;如何扩展自定义监控功能 【免费下载链接】cowrie Cowrie SSH/Telnet Honeypot https://cowrie.readthedocs.io 项目地址: https://gitcode.com/gh_mirrors/co/cowrie Cowrie是一款强大的开源SSH/Telnet蜜罐工具&#xff0c;能够模拟真…...

city-roads中的无障碍色彩设计:对比度与可读性优化

city-roads中的无障碍色彩设计&#xff1a;对比度与可读性优化 【免费下载链接】city-roads Visualization of all roads within any city 项目地址: https://gitcode.com/gh_mirrors/ci/city-roads city-roads作为一款城市道路可视化项目&#xff0c;通过直观展示城市道…...

TeslaMate驾驶效率评分:构建自定义评分模型的方法与示例

TeslaMate驾驶效率评分&#xff1a;构建自定义评分模型的方法与示例 【免费下载链接】teslamate 项目地址: https://gitcode.com/gh_mirrors/tes/teslamate TeslaMate是一款功能强大的开源Tesla数据记录与可视化工具&#xff0c;能够帮助车主深入了解车辆性能和驾驶习惯…...

nlp_structbert_sentence-similarity_chinese-large 在低资源语言上的迁移学习实验

nlp_structbert_sentence-similarity_chinese-large 在低资源语言上的迁移学习实验 最近在做一个多语言项目时&#xff0c;遇到了一个挺有意思的挑战&#xff1a;我们想为一些方言和少数民族语言&#xff08;比如粤语书面语、藏文&#xff09;开发一个能理解句子意思的模型。但…...

FlutterBoost与其他混合方案对比:谁才是性能王者?

FlutterBoost与其他混合方案对比&#xff1a;谁才是性能王者&#xff1f; 【免费下载链接】flutter_boost FlutterBoost is a Flutter plugin which enables hybrid integration of Flutter for your existing native apps with minimum efforts 项目地址: https://gitcode.c…...

被动蜂鸣器异步旋律驱动:嵌入式非阻塞音效实现

1. SimpleMelodyBuzzer 库深度解析&#xff1a;面向嵌入式工程师的被动蜂鸣器旋律驱动方案1.1 工程定位与核心价值SimpleMelodyBuzzer 是一个专为资源受限嵌入式平台设计的轻量级旋律播放库&#xff0c;其核心目标并非提供音频编解码或高保真音效&#xff0c;而是以最小的内存开…...

HP-Socket跨平台开发指南:Linux与Windows环境适配最佳实践

HP-Socket跨平台开发指南&#xff1a;Linux与Windows环境适配最佳实践 【免费下载链接】HP-Socket High Performance TCP/UDP/HTTP Communication Component 项目地址: https://gitcode.com/gh_mirrors/hp/HP-Socket HP-Socket是一款高性能的TCP/UDP/HTTP通信组件&#…...

FlutterBoost 4.0重磅发布:带来哪些革命性更新?

FlutterBoost 4.0重磅发布&#xff1a;带来哪些革命性更新&#xff1f; 【免费下载链接】flutter_boost FlutterBoost is a Flutter plugin which enables hybrid integration of Flutter for your existing native apps with minimum efforts 项目地址: https://gitcode.com…...

一个老登和AI的极端对话,不限于阿里AI,重新认识自己只需要一个晚上

其实大部分技术人晚上是最容易沉淀的时候场景一&#xff1a;A,B,C几个人在网上隔空干架, AI做阅读理解AI最终没有给出完美的文本&#xff0c;因为问题在于人而不是文本&#xff0c;一千个人心中有一千个哈姆雷特&#xff08;需要的关键是大众传播学&#xff0c;而不是为了写而写…...

OpenCore配置工具OCAT:让黑苹果配置变得简单的完整指南

OpenCore配置工具OCAT&#xff1a;让黑苹果配置变得简单的完整指南 【免费下载链接】OCAuxiliaryTools Cross-platform GUI management tools for OpenCore&#xff08;OCAT&#xff09; 项目地址: https://gitcode.com/gh_mirrors/oc/OCAuxiliaryTools OCAuxiliaryTool…...

FL Chart手势冲突处理终极指南:解决多组件间的触摸事件竞争问题

FL Chart手势冲突处理终极指南&#xff1a;解决多组件间的触摸事件竞争问题 【免费下载链接】fl_chart FL Chart is a highly customizable Flutter chart library that supports Line Chart, Bar Chart, Pie Chart, Scatter Chart, and Radar Chart. 项目地址: https://gitc…...

手机号逆向查询QQ号:终极完整指南,3分钟快速上手

手机号逆向查询QQ号&#xff1a;终极完整指南&#xff0c;3分钟快速上手 【免费下载链接】phone2qq 项目地址: https://gitcode.com/gh_mirrors/ph/phone2qq 你是否曾经因为忘记QQ号码而无法登录&#xff1f;或者需要验证手机号与QQ号的绑定关系&#xff1f;今天我要介…...

【Dify高级工程师认证核心考点】:异步任务调度、回调链路追踪、错误重试机制——这6个底层原理90%候选人答不全

第一章&#xff1a;Dify自定义节点异步处理概述Dify 的自定义节点&#xff08;Custom Node&#xff09;机制支持在工作流中嵌入开发者自主实现的逻辑单元&#xff0c;其中异步处理能力是构建高响应性、长周期任务&#xff08;如大文件解析、外部 API 轮询、模型微调回调&#x…...

RPA-Python与CircleCI集成:实现RPA工作流的持续集成自动化

RPA-Python与CircleCI集成&#xff1a;实现RPA工作流的持续集成自动化 【免费下载链接】RPA-Python Python package for doing RPA 项目地址: https://gitcode.com/gh_mirrors/rp/RPA-Python RPA-Python是一款强大的Python自动化工具包&#xff0c;能够帮助开发者轻松构…...

HP-Socket技术演讲QA常见问题库:准备与应对策略

HP-Socket技术演讲Q&A常见问题库&#xff1a;准备与应对策略 【免费下载链接】HP-Socket High Performance TCP/UDP/HTTP Communication Component 项目地址: https://gitcode.com/gh_mirrors/hp/HP-Socket HP-Socket作为一款高性能TCP/UDP/HTTP通信组件&#xff0c…...

machine_learning_basics:简单神经网络实现与梯度下降优化

machine_learning_basics&#xff1a;简单神经网络实现与梯度下降优化 【免费下载链接】machine_learning_basics Plain python implementations of basic machine learning algorithms 项目地址: https://gitcode.com/gh_mirrors/ma/machine_learning_basics machine_l…...