多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

cytoscape.js 集合邻域关系判定:`eles.allAreNeighbors()` 全量邻接检测实战与源码解析

cytoscape.js 集合邻域关系判定:`eles.allAreNeighbors()` 全量邻接检测实战与源码解析 数据可视化【免费下载链接】cytoscape.jsGraph theory (network) library for visualisation and analysis项目地址https://gitcode.com/gh_mirrors/cy/cytoscape.js点击查看免费下载导读在 cytoscape.js 的图分析场景中经常需要回答目标节点集合是否全部与当前元素直接相连这类邻接关系问题。eles.allAreNeighbors( collection )正是为此设计的集合比较方法它以当前元素集合为参照判断传入集合中的每一个元素是否都在当前集合的邻域之内并返回布尔结果。本文以官方文档 allAreNeighbors.md 为核心骨架结合源码 comparators.mjs、traversing.mjs 与测试用例 collection-comparison.mjs完整讲解该方法的使用方式、底层实现原理、边界行为及与same()、anySame()、contains()等相关方法的区别帮助你准确、高效地在复杂图数据上做邻接判定。方法签名与语义allAreNeighbors属于集合比较comparison系列方法签名如下eles.allAreNeighbors( collection ) → booleaneles调用方可以是单个元素节点或边构成的集合也可以是多个元素构成的集合collection待检测的目标集合可以是另一个集合、元素或能被构造为集合的输入返回值当且仅当目标集合中的每一个元素都属于eles的邻域neighborhood时返回true否则返回false。官方文档 allAreNeighbors.md 给出的示例var j cy.$(#j); var gAndK cy.$(#g, #k); console.log( all neighbours ? j.allAreNeighbors(gAndK) );这段代码的含义是以节点#j为参照检查节点#g和#k是否全部都是#j的邻居。如果#j同时与#g、#k直接相连通过一条边控制台将输出all neighbours ? true只要其中任何一个不是#j的直接邻居就输出false。与allAre()的对照注意区分两个名字相近的方法allAreNeighbors()判断的是全部属于邻域而allAre( selector )见 allAre.md判断的是全部满足某个选择器条件。前者面向集合之间的邻接关系后者面向元素属性/类型筛选两者语义不同、适用场景也不同var jAndE cy.$(#j, #e); // 判断 j、e 是否都是 weight 50 的节点 console.log( j and e all have weight 50 ? jAndE.allAre([weight 50]) );源码实现逐行拆解allAreNeighbors的实现位于 src/collection/comparators.mjs完整代码如下allAreNeighbors: function( collection ){ collection this.cy().collection( collection ); let nhood this.neighborhood(); return collection.every(function( ele ){ return nhood.hasElementWithId( ele.id() ); }); },实现逻辑可以拆解为三步参数规范化this.cy().collection( collection )将传入的目标集合统一转换为标准的Collection实例无论传入的是集合、单元素还是 JSON 数组确保后续遍历接口一致计算开放邻域this.neighborhood()一次性求出eles的邻域集合nhood详见下一节该结果带缓存同一集合多次调用不会重复遍历图全量成员判定用collection.every(...)对目标集合逐元素检查——只要有一个元素不在nhood中hasElementWithId返回falseevery立即短路返回false全部命中才返回true。其中every的短路语义见 comparators.mjs 中every的实现保证了一个不满足即提前退出在目标集合很大、且第一个元素就不相邻的场景下可以省去大量无谓的邻域查询。而hasElementWithId并非线性查找它基于集合内部维护的Map见 src/collection/index.mjselesfn.hasElementWithId function( id ){ id id; // id must be string return this._private.map.has( id ); };也就是说每个元素的 ID 都会先被字符串化然后在 O(1) 的哈希表内完成存在性判断。整条判定链邻域计算一次 每个目标元素一次哈希查找的效率是相当高的这也是该方法可以放心用于较大集合的原因。邻域到底包含什么开放邻域与连接边allAreNeighbors的判定结果完全取决于neighborhood()的定义这一点非常关键。官方文档 neighborhood.md 明确说明该函数返回的邻域与传统图论定义略有不同返回的邻域包含连接该集合与邻域的边这提供了更大的灵活性。开放邻域open neighbourhood不包含原集合本身未指定时默认返回开放邻域。闭合邻域closed neighbourhood包含原集合本身。从源码 src/collection/traversing.mjs 可以印证这一行为neighborhood: cache(function( selector ){ let elements []; let nodes this.nodes(); for( let i 0; i nodes.length; i ){ // for all nodes let node nodes[ i ]; let connectedEdges node.connectedEdges(); // for each connected edge, add the edge and the other node for( let j 0; j connectedEdges.length; j ){ let edge connectedEdges[ j ]; let src edge.source(); let tgt edge.target(); let otherNode node src ? tgt : src; // need check in case of loop if( otherNode.length 0 ){ elements.push( otherNode[0] ); // add node 1 hop away } // add connected edge elements.push( edge[0] ); } } return ( this.spawn( elements, true ) ).filter( selector ); }, neighborhood),从实现可以看到两个直接决定allAreNeighbors判定结果的要点邻域里既有节点也有边对eles中的每个节点其每条连接边connectedEdges()都会被加入邻域同时边另一端的一跳节点也会被加入。因此边元素也可以作为目标集合的成员被判定为邻居——例如判断某条边是否与当前节点直接相连默认是开放邻域this本身不包含在邻域内。如果想连自身一起参与判定需要改用闭合邻域closedNeighborhood()即neighborhood().add( this )。allAreNeighbors直接调用this.neighborhood()因此它内部使用的是开放邻域、且包含连接边的语义。测试用例验证行为仓库测试 test/collection-comparison.mjs 为allAreNeighbors提供了三组精确断言是理解其行为的最佳佐证。测试图结构为三个节点两条边n1 — n2 — n3边n1n2、n2n3。it(eles.allAreNeighbors(), function(){ expect( cy.$(#n2).allAreNeighbors( cy.$(#n1, #n3) ) ).to.be.true; expect( cy.$(#n1).allAreNeighbors( cy.$(#n2, #n3) ) ).to.be.false; expect( cy.$(#n1).allAreNeighbors( cy.$(#n1n2, #n2) ) ).to.be.true; });逐条解读#n2与#n1、#n3都直接相连n1、n3均在#n2的邻域内 →true#n1只与#n2相连#n3与#n1之间隔着#n2不在邻域内 → 全量条件不满足 →false#n1的邻域包含节点#n2和边#n1n2邻域含连接边所以目标集合#n1n2, #n2两个成员都在邻域内 →true。第 3 条断言特别值得注意它验证了邻域包含连接边这一非传统语义——一条边只要一端连着#n1就会被判为#n1的邻居。边界情况与实用细节空集合的行为从实现可知目标集合为空时collection.every(...)遍历零个元素、不会触发短路因此allAreNeighbors对空集合返回true数学上全称命题对空集恒真。在编码时应留意这一约定必要时先判断目标集合的size()再使用。英式拼写别名源码 comparators.mjs 为英式拼写注册了别名elesfn.allAreNeighbours elesfn.allAreNeighbors;即allAreNeighbours()双 u与allAreNeighbors()完全等价代码风格偏好英式拼写的团队可以直接使用前者。集合的不可变性与纯函数特性cytoscape.js 的集合默认不可变见 collection.mdallAreNeighbors不会修改任何元素或集合只是读取邻域并返回布尔值因此可以安全地用于函数式链式调用、与其他集合运算如union、intersection、difference自由组合。与相关集合比较方法的选型allAreNeighbors位于比较方法的全量 邻域维度与同文件comparators.mjs中的其他方法形成清晰的对照方法判定语义典型用途allAreNeighbors(collection)目标集合全部元素都在当前集合的开放邻域内批量确认一组节点是否全部直连当前节点/子图anySame(collection)两个集合是否至少有一个相同元素快速探测两个子图是否有交集same(collection)两个集合是否完全相等元素与数量均一致严格集合相等判断contains(collection)目标集合全部元素都被当前集合包含has别名子集判断如nodes().contains(subset)allAre(selector)当前集合是否全部匹配某个选择器类型/属性/状态批量断言is(selector)当前集合是否至少一个元素匹配选择器存在性断言选型建议判断是否直接相邻优先allAreNeighbors判断是否包含/相等用contains/same判断是否有重叠用anySame。它们共享this.cy().collection(...)的规范化输入方式可以互相搭配完成复杂的图结构校验。实战示例子图连通性校验综合以上知识一个典型的实战场景是校验候选节点是否全部与核心节点直接相连例如社团检测前过滤邻居候选var core cy.$(#core); var candidates cy.$(#a, #b, #c); if( candidates.nonempty() core.allAreNeighbors( candidates ) ){ // 所有候选节点都与 core 直接相连 console.log( All candidates are direct neighbors of core. ); } else { console.log( Some candidates are NOT direct neighbors of core. ); }若还要验证候选节点之间的互连关系可与contains()、anySame()组合使用若要排除候选就是 core 自身的情况可用candidates.difference( core )先做差集再交给allAreNeighbors判定。这种比较方法 集合运算的组合模式正是 cytoscape.js 不可变集合设计所鼓励的写法。小结eles.allAreNeighbors( collection )是一个语义清晰、实现高效的全量邻接判定方法语义上它要求目标集合每一个元素都落在当前集合的开放邻域含连接边、不含自身内实现上它由一次性邻域计算 基于哈希表的逐元素判定 短路遍历三部分组成见 comparators.mjs性能表现稳定行为上有三条来自 collection-comparison.mjs 的测试断言精确背书包括边也是邻居这一容易被忽略的细节使用上注意空集合返回true的约定、allAreNeighbours英式别名以及与same()、anySame()、contains()、allAre()的差异化选型。在涉及邻居批量校验、子图连通性检查、图结构过滤等场景中它都是值得优先考虑的基础工具方法。赞分享数据可视化【免费下载链接】cytoscape.jsGraph theory (network) library for visualisation and analysis项目地址https://gitcode.com/gh_mirrors/cy/cytoscape.js点击查看免费下载相关推荐免费开源压缩包密码恢复工具终极指南快速找回遗忘的加密文件免费开源压缩包密码恢复工具终极指南快速找回遗忘的加密文件 你是否曾经面对一个重要的加密压缩文件明明记得密码就在脑海边缘却怎么也想不起来或者接手了一个老项数据可视化Semantica Distance Intelligence 实战指南语义邻域、距离矩阵与邻近度混合检索Semantica Distance Intelligence 实战指南语义邻域、距离矩阵与邻近度混合检索 导读本文围绕 Semantica 自 v0.5.人工智能大模型知识图谱RAGAI 可解释性后端MCP 服务hello-algo 图Graph数据结构详解邻接矩阵与邻接表表示及源码实现hello algo 图Graph数据结构详解邻接矩阵与邻接表表示及源码实现 本篇基于 hello algo 仓库《Hello 算法》中的 图Graph教程文档示例工程教育上一篇【限时免费】 BootstrapBlazor 9.4.10版本发布组件功能增强与优化下一篇【限时免费】 【nebula-admin】开源下载和安装教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表