如何在循环中正确使用convex_hull()函数构建凸包序列图
问题分析与修正方案
你的代码出现节点重复使用的核心问题是凸包索引未正确映射到原图节点,同时存在语法错误,以下是具体修正:
核心问题点
- 错误的索引映射:
convex_hull(xy[in_points, ])$resverts返回的是当前未连接节点子集(in_points)内的索引,直接+1会错误对应到原图节点,应该用in_points[cp]来获取原图中真正的凸包节点ID。 - 循环终止条件语法错误:
length(in_points)=1是赋值操作,需改为比较运算符==。 - 边构造逻辑冗余:原代码的边生成方式可以简化,避免不必要的嵌套操作。
修正后的代码
library(igraph) set.seed(5) n = 15 g <- graph.empty(n) xy <- cbind(runif(n), runif(n)) in_points <- V(g)[degree(g) == 0] repeat { # 获取当前未连接节点的凸包子集索引(子集内的位置) cp_idx <- convex_hull(xy[in_points, ])$resverts # 映射回原图的节点ID cp_nodes <- in_points[cp_idx] # 生成凸包的边:相邻节点相连,最后一个连回第一个 edges <- as.vector(t(cbind(cp_nodes, c(cp_nodes[-1], cp_nodes[1])))) g <- as.undirected(add_edges(g, edges)) # 更新未连接节点集合 in_points <- V(g)[degree(g) == 0] # 终止条件:仅剩余1个未连接节点时停止 if (length(in_points) == 1) { break } } plot(g, vertex.size = 10, layout = xy)
关键修正说明
- 索引映射修正:通过
cp_nodes <- in_points[cp_idx],把凸包函数返回的子集索引转换成原图的实际节点ID,确保每次添加的边都对应正确的未连接节点。 - 边构造简化:用
cbind生成相邻节点对,再转成向量,逻辑更清晰,避免原代码中embed和手动拼接的冗余操作。 - 语法错误修复:将赋值操作
=改为比较操作==,确保循环能正确终止。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

