Python路径搜索函数转R代码调试:解决条件长度大于1错误
调试R版图路径搜索函数的条件长度错误
问题描述
有一个Python实现的get_all_best_routes函数,用于在图结构中从指定起点出发,搜索最大深度内到达指定终点的所有最优路径。转换为R代码时出现错误:Error in if (adjacent %in% end) { : 条件长度大于1
1. Python原函数
nodes=['A7', 'A9', 'A6', 'A1', 'A3', 'A4', 'A5', 'A8', 'A2'] graph={'A7': ['A8', 'A9', 'A6', 'A5'], 'A9': ['A8', 'A5', 'A4', 'A7'], 'A6': ['A7', 'A3', 'A5', 'A8', 'A2'], 'A1': ['A3', 'A4', 'A2'], 'A3': ['A6', 'A1', 'A4', 'A5'], 'A4': ['A9', 'A3', 'A1', 'A5'], 'A5': ['A7', 'A9', 'A6', 'A3', 'A4'], 'A8': ['A7', 'A9', 'A6', 'A2'], 'A2': ['A8', 'A6', 'A1']} start = 'A9' end = ['A1'] max_depth=5 def get_all_best_routes(graph,start,end,max_depth): past_path = [] # maintain a queue of paths queue = [] # push the first path into the queue queue.append([start]) while queue: # get the first path from the queue path = queue.pop(0) # get the last node from the path node = path[-1] # enumerate all adjacent nodes, construct a new path and push it into the queue for adjacent in graph.get(node, []): new_path = list(path) ## end the current loop if we already reach the point if adjacent in end: new_path.append(adjacent) past_path.append(new_path) continue if adjacent in new_path: continue new_path.append(adjacent) if len(new_path) >= max_depth and new_path[-1] not in end: break queue.append(new_path) past_path.append(new_path) best_paths = [] for l in past_path: if l[-1] in end: best_paths.append(l) return best_paths
2. R环境输入数据
# Define the nodes and graph node <- list("A9", "A8", "A4", "A5", "A7", "A2", "A6", "A1", "A3") graph <- list() graph[["A9"]] <- list("A8", "A4", "A5", "A7") graph[["A8"]] <- list("A2", "A6", "A7", "A9") graph[["A4"]] <- list("A5", "A9", "A1", "A3") graph[["A5"]] <- list("A3", "A6", "A7", "A9", "A4") graph[["A7"]] <- list("A6", "A8", "A9", "A5") graph[["A2"]] <- list("A8", "A1", "A6") graph[["A6"]] <- list("A2", "A8", "A3", "A5", "A7") graph[["A1"]] <- list("A2", "A3", "A4") graph[["A3"]] <- list("A4", "A6", "A1", "A5") max_depth <- 5 start <- "A9" end <- c("A1")
3. 存在问题的R函数
get_all_best_routes <- function(graph, start, end, max_depth) { past_path <- list() queue <- list() queue[[1]] <- list(start) while (length(queue) > 0) { path <- queue[[1]] queue <- queue[-1] node <- tail(path, 1) for (adjacent in graph[names(graph) %in% node]) { new_path <- list(path) if (adjacent %in% end) { new_path <- c(new_path, adjacent) past_path <- c(past_path, list(new_path)) next } if (adjacent %in% new_path) { next } new_path <- c(new_path, adjacent) if (length(new_path) >= max_depth && !(new_path[length(new_path)] %in% end)) { break } queue <- c(queue, new_path) past_path <- c(past_path, new_path) } } best_paths <- list() for (l in past_path) { if (l[length(l)] %in% end) { best_paths <- c(best_paths, l) } } return(best_paths) }
4. 错误信息
Error in if (adjacent %in% end) { : 条件长度大于1
5. 问题原因与修复
核心问题
graph[names(graph) %in% node]返回的是整个邻接节点列表(比如当node是"A9"时,返回list("A8", "A4", "A5", "A7")),而非逐个取出的单个节点。循环中adjacent每次拿到的是完整列表,导致adjacent %in% end返回长度大于1的逻辑向量,触发if条件判断错误。
关键修复点
- 正确获取邻接节点:用
graph[[node]]直接提取当前节点的邻接列表,而非布尔索引 - 路径存储格式:将路径存储为字符向量,避免嵌套列表导致的节点判断错误
- 队列管理:确保队列中每个元素都是字符向量形式的路径
- 循环逻辑对齐:严格对齐Python原函数的FIFO队列、路径去重、深度判断逻辑
6. 修正后的R函数
get_all_best_routes <- function(graph, start, end, max_depth) { past_path <- list() queue <- list() # 初始化队列,路径用字符向量存储 queue[[1]] <- c(start) while (length(queue) > 0) { # 取出队列第一个路径(FIFO,模拟Python的pop(0)) path <- queue[[1]] queue <- queue[-1] node <- tail(path, 1) # 获取当前节点的邻接节点,转为字符向量 adj_nodes <- unlist(graph[[node]]) for (adjacent in adj_nodes) { new_path <- path # 如果邻接节点是终点,直接加入已探索路径 if (adjacent %in% end) { new_path <- c(new_path, adjacent) past_path <- c(past_path, list(new_path)) next } # 避免循环路径(节点已在当前路径中) if (adjacent %in% new_path) { next } new_path <- c(new_path, adjacent) # 如果路径长度达到最大深度且未到终点,仅加入已探索路径,不加入队列 if (length(new_path) >= max_depth && !(tail(new_path, 1) %in% end)) { past_path <- c(past_path, list(new_path)) next } queue <- c(queue, list(new_path)) past_path <- c(past_path, list(new_path)) } } # 筛选所有以终点结尾的路径 best_paths <- Filter(function(x) tail(x, 1) %in% end, past_path) return(best_paths) }
7. 验证调用
# 调用函数 result <- get_all_best_routes(graph, start, end, max_depth) # 打印结果 for (path in result) { cat(paste(path, collapse = " -> "), "\n") }
内容的提问来源于stack exchange,提问作者Rakesh Nandi
相关产品推荐
相关产品推荐

