【问题标题】:R: creating a recursive binary tree in RR:在 R 中创建递归二叉树
【发布时间】:2020-08-20 10:11:03
【问题描述】:

我对编写递归二叉树算法很感兴趣。鉴于以下数据,我已经对协变量进行了排序 x

mydata <- data.frame(x = c(10, 20, 25, 35), y = c(-10.5, 6.5, 7.5, -7.5))
> mydata
   x     y
1 10 -10.5
2 20   6.5
3 25   7.5
4 35  -7.5

我会拆分树,让左节点始终包含父节点的第一个实例,右节点包含父节点中的其余实例(拆分方式很奇怪,但请多多包涵)。本质上,我希望我的树看起来像这样,最大高度 = 3。

          [-10.5, 6.5, 7.5, -7.5]
                /         \
           [-10.5]        [6.5, 7.5, -7.5]
                            /      \
                       [6.5]       [7.5, -7.5]

我希望我的函数的最终输出返回一个包含所有节点的列表:

> final_tree
[[1]]
[[1]][[1]]
   x     y
1 10 -10.5
2 20   6.5
3 25   7.5
4 35  -7.5


[[2]]
[[2]][[1]]
   x     y
1 10 -10.5


[[2]][[2]]
   x     y
1 20   6.5
2 25   7.5
3 35  -7.5


[[3]]
[[3]][[1]]
NULL

[[3]][[2]]
NULL

[[3]][[3]]
   x     y
1 20   6.5


[[3]][[4]]
   x     y
1 25   7.5
2 35  -7.5

这是我目前所拥有的:

# Initialize empty tree
create_empty_tree <- function(max_height) sapply(1:max_height, function(k) replicate(2**(k-1),c()))

# Create empty tree with max_height = 3
tree_struc <- create_empty_tree(max_height = 3)

grow_tree <- function(node_parent, max_height, tree_struc, height){
  # Sort x
  sorted_x <- sort(node_parent$x)

  # Fix best split index at 1
  best_split_ind <- 1

  # Assign instances to left or right nodes
  group <- ifelse(node_parent$x <= node_parent$x[best_split_ind], "left", "right")
  node_left <- node_parent[which(group == "left"), ]
  node_right <- node_parent[which(group == "right"), ]

  # Recursive call on left and right nodes
  if(height < max_height){
  tree_struc[[height]] <- node_parent
  tree_struc[[height + 1]][[1]] <- grow_tree(node_parent = node_left, max_height = max_height, tree_struc = tree_struc, height = height + 1)
  tree_struc[[height + 1]][[2]] <- grow_tree(node_parent = node_right, max_height = max_height, tree_struc = tree_struc, height = height + 1)
  }

  return(tree_struc)
}

grow_tree(node_parent = mydata, max_height = 3, tree_struc = tree_struc, height = 1)

生成的树不正确。我认为这与我如何递归调用左右子节点上的函数有关。谁能指出我正确的方向?

【问题讨论】:

    标签: r algorithm recursion tree


    【解决方案1】:

    或许你可以试试下面的函数grow_tree

    create_empty_tree <- function(max_height) sapply(1:max_height, function(k) replicate(2**(k-1),c()))
    
    grow_tree <- function(node_parent,max_height = nrow(node_parent)) {
      tree_struc <- create_empty_tree(max_height)
      for (i in 1:length(tree_struc)) {
        tree_struc[[i]][[2**(i-1)]] <- `row.names<-`(tail(node_parent,nrow(node_parent)-i+1),NULL)
        if (i > 1) tree_struc[[i]][[2**(i-1)-1]] <- `row.names<-`(node_parent[i-1,],NULL)
      }
      tree_struc
    }
    

    示例

    > grow_tree(mydata,3)
    [[1]]
    [[1]][[1]]
       x     y
    1 10 -10.5
    2 20   6.5
    3 25   7.5
    4 35  -7.5
    
    
    [[2]]
    [[2]][[1]]
       x     y
    1 10 -10.5
    
    [[2]][[2]]
       x    y
    1 20  6.5
    2 25  7.5
    3 35 -7.5
    
    
    [[3]]
    [[3]][[1]]
    NULL
    
    [[3]][[2]]
    NULL
    
    [[3]][[3]]
       x   y
    1 20 6.5
    
    [[3]][[4]]
       x    y
    1 25  7.5
    2 35 -7.5
    

    > grow_tree(mydata)
    [[1]]
    [[1]][[1]]
       x     y
    1 10 -10.5
    2 20   6.5
    3 25   7.5
    4 35  -7.5
    
    
    [[2]]
    [[2]][[1]]
       x     y
    1 10 -10.5
    
    [[2]][[2]]
       x    y
    1 20  6.5
    2 25  7.5
    3 35 -7.5
    
    
    [[3]]
    [[3]][[1]]
    NULL
    
    [[3]][[2]]
    NULL
    
    [[3]][[3]]
       x   y
    1 20 6.5
    
    [[3]][[4]]
       x    y
    1 25  7.5
    2 35 -7.5
    
    
    [[4]]
    [[4]][[1]]
    NULL
    
    [[4]][[2]]
    NULL
    
    [[4]][[3]]
    NULL
    
    [[4]][[4]]
    NULL
    
    [[4]][[5]]
    NULL
    
    [[4]][[6]]
    NULL
    
    [[4]][[7]]
       x   y
    1 25 7.5
    
    [[4]][[8]]
       x    y
    1 35 -7.5
    

    【讨论】:

    • 谢谢。如果我不是每次都与best_split_ind &lt;- 1 分手怎么办?例如,每个节点的best_split_ind 都会发生变化,即best_split_ind &lt;- sample(1:(nrow(node_parent) - 1), 1)。如果best_split_ind = 2,则表示父节点中的前 2 个实例转到左侧子节点,其余实例转到右侧。如果best_split_ind = 3,则表示父节点中的前3个实例去左子节点,其余的去其余的,以此类推。
    • 我在这里修改了我的问题:stackoverflow.com/questions/61621974/….
    猜你喜欢
    • 2011-05-08
    • 2019-07-27
    • 1970-01-01
    • 2020-08-22
    • 2016-04-19
    • 2014-03-29
    • 2019-10-13
    • 1970-01-01
    • 2020-08-22
    相关资源
    最近更新 更多