You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

igraph实现每条边中点添加新节点并赋予平均海拔属性

为igraph图的每条边中点添加新节点并设置属性

我有一个igraph图,其中每个节点和边都具备独立属性(例如节点拥有不同海拔,边拥有不同直径和长度)。现在需要在每条边的中点添加新节点,并将该新节点的海拔设为其连接的两个节点的平均海拔,希望通过循环实现以适配节点和边数量较多的大型网络。

示例图加载与属性设置

方式1:从RDS文件加载

如果已有g.rds文件,可通过以下代码加载:

library(igraph)
g = readRDS("g.rds")
plot(g)

方式2:直接构建示例图

若没有g.rds,可使用以下代码构建包含属性的示例图:

library(igraph)
# 从dput结构构建图
g <- structure(list(4, FALSE, c(3, 2, 2, 1), c(0, 0, 1, 0), c(3, 1, 
2, 0), c(3, 1, 0, 2), c(0, 0, 1, 3, 4), c(0, 3, 4, 4, 4), list(
    c(1, 0, 1), structure(list(), names = character(0)), list(
        name = c("J-1", "J-2", "J-3", "R-1"), XCoord = c(1248.164, 
        5991.189, 2246.696, -631.424), YCoord = c(5976.505, 5741.557, 
        3113.069, 7621.145), color = c("gray", "gray", "gray", 
        "orange"), shape = c("circle", "circle", "circle", "square"
        ), elevation = c(10L, 50L, 30L, 10L), Elevation = c(10L, 
        50L, 30L, 30L)), list(label = c("P-1", "P-2", "P-3", 
    "P-4"), Diameter = c(500L, 500L, 500L, 500L), Lenght = c(1000L, 
    1000L, 1000L, 1000L), label_no_P = c(1, 2, 3, 4), Length = c(1000L, 
    1000L, 1000L, 1000L))), environment(), class = "igraph")

# 确保属性正确(若构建后属性缺失可重新设置)
E(g)$Length = c(1000, 1000, 1000, 1000)
E(g)$Diameter = c(500, 500, 500, 500)
V(g)$Elevation = c(10, 50, 30, 30)

解决方案:循环添加中点节点

以下代码通过循环遍历每条边,完成中点节点的添加与属性设置,适配大型网络:

# 复制原图避免修改原数据
g_new <- g

# 获取边的数量
edge_count <- ecount(g_new)

# 倒序遍历边,避免删除边后索引错乱
for (i in rev(1:edge_count)) {
  # 获取当前边的两端节点
  endpoints <- ends(g_new, i)
  node1 <- endpoints[1]
  node2 <- endpoints[2]
  
  # 计算两端节点的平均海拔
  avg_elevation <- mean(c(V(g_new)$Elevation[node1], V(g_new)$Elevation[node2]))
  
  # 添加新节点并设置属性
  new_node_id <- add_vertices(g_new, 1, 
                              name = paste0("Mid-", i),
                              Elevation = avg_elevation,
                              color = "blue",  # 可选:设置新节点颜色方便区分
                              shape = "triangle")
  
  # 删除原边
  g_new <- delete_edges(g_new, i)
  
  # 添加两条新边,继承原边的属性
  g_new <- add_edges(g_new, c(node1, new_node_id, node2, new_node_id),
                     attr = list(
                       Length = E(g)$Length[i],
                       Diameter = E(g)$Diameter[i],
                       label = paste0("P-", i, "-1"),
                       label_no_P = paste0(i, "-1")
                     ))
}

# 查看处理后的图
plot(g_new)
# 检查新节点的海拔属性
print(V(g_new)$Elevation)

代码说明

  • 倒序遍历边:删除原边会改变后续边的索引,倒序遍历可避免索引错乱问题。
  • 新节点属性:除海拔外,可自定义颜色、形状等属性,方便区分新节点与原节点。
  • 边属性继承:将原边的长度、直径等属性传递给新边,保留原有边的属性信息。

内容的提问来源于stack exchange,提问作者Mohammad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 10:05:29