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

R语言:编写基于图网络的好友节点选择与计算函数求助

问题解决:用igraph实现好友网络节点选择与移除函数

需求回顾

需要实现一个函数完成以下步骤:

  • 随机选择一个初始节点
  • 随机选择一个“半径”(指与初始节点的最大路径距离)
  • 在初始节点的半径范围内,随机选择若干连通的节点(包含初始节点)
  • 计算这些节点的饼干总数
  • 若总数在50-100之间则结束,否则从步骤1重新开始
  • 将选中的节点从原图中移除

完整代码实现

set.seed(123)
library(igraph)

# 构建好友关系图
names <- c("John", "Alex", "Jason", "Matt", "Tim", "Luke", "Shawn", "Henry", "Steven", "Scott", "Adam", "Jeff", "Connor", "Peter", "Andrew", "Dave", "Daniel", "Benjamin", "Joseph", "Martin")
g <- make_empty_graph(20)
num_edges <- 40
edge_list <- sample(names, size = num_edges * 2, replace = TRUE)
edge_list <- matrix(edge_list, ncol = 2, byrow = TRUE)
g <- graph_from_edgelist(edge_list, directed = FALSE)
V(g)$name <- names

# 饼干数据框
cookies = data.frame(names = names, cookies = as.integer(rnorm(length(names), 20,10)))

# 定义核心函数
select_and_remove_nodes <- function(g, cookies) {
  repeat {
    # STEP 1: 随机选择初始节点
    original_node <- sample(V(g), 1)$name
    
    # STEP 2: 随机选择半径(最大路径距离)
    # 计算初始节点到所有连通节点的距离
    dists <- distances(g, original_node)
    # 只保留连通节点的距离(排除不连通的Inf值)
    valid_dists <- dists[!is.infinite(dists)]
    max_possible_radius <- max(valid_dists)
    # 随机选半径(0表示只选初始节点自己)
    radius <- sample(0:max_possible_radius, 1)
    
    # STEP 3: 获取半径范围内的所有连通节点
    # ego函数返回距离初始节点≤radius的节点集合
    radius_nodes <- ego(g, order = radius, nodes = original_node, mode = "all")[[1]]
    radius_node_names <- V(g)[radius_nodes]$name
    
    # 随机选择若干节点(至少包含初始节点)
    num_to_select <- sample(1:length(radius_node_names), 1)
    # 确保初始节点被选中,其余从半径范围内随机选
    selected_nodes <- c(original_node, sample(setdiff(radius_node_names, original_node), num_to_select - 1))
    
    # STEP 4: 计算饼干总数
    total_cookies <- sum(cookies$cookies[cookies$names %in% selected_nodes])
    
    # STEP 5: 判断是否符合条件
    if (total_cookies >= 50 && total_cookies <= 100) {
      cat("选中节点:", paste(selected_nodes, collapse = ", "), "\n")
      cat("饼干总数:", total_cookies, "\n")
      break
    }
  }
  
  # STEP 6: 从图中移除选中节点
  g <- delete_vertices(g, selected_nodes)
  return(g)
}

# 调用函数更新图
g_updated <- select_and_remove_nodes(g, cookies)
# 可视化更新后的图
plot(g_updated, vertex.label.cex = 0.7, vertex.label.color = "black")

关键代码说明

  1. 修正半径逻辑:之前的代码混淆了节点度数与路径距离,这里用distances()计算初始节点到所有连通节点的路径长度,以最大路径长度作为半径上限,匹配需求中的“半径”定义。
  2. 高效获取半径内节点:用ego()函数直接提取距离初始节点≤指定半径的所有连通节点,避免手动筛选的误差。
  3. 保证节点选择有效性:强制选中初始节点,再从半径范围内的其他节点中随机补充,确保选中集合与初始节点连通。
  4. 循环重试机制:用repeat循环实现步骤5的重试逻辑,直到找到符合饼干总数条件的节点集合。
  5. 节点移除操作:通过delete_vertices()完成节点移除,返回更新后的图对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 14:37:53