【问题标题】:Building N-ary tree in R在 R 中构建 N-ary 树
【发布时间】:2016-01-10 12:35:30
【问题描述】:

如何在 R 中为给定数量的分支和深度构建 N 叉树,例如深度为 3 的二叉树?

编辑:将源问题与问题和答案分开。

【问题讨论】:

  • igraph 包中有 make_tree 函数
  • @user20650 我认为这是我需要的另一种东西。我需要一个可以存储没有方向的树数据的数据结构。 igraph 是我任务的复杂解决方案,我更喜欢 data.tree 这对我来说更简单。感谢您的建议!
  • 对于那些投票结束的人 - 我认为这个问题提供了足够的信息来回答,他们确实提供了一个可能对其他用户有用的答案
  • 为什么我的问题跑题了?这个问题stackoverflow.com/questions/33768841/r-tree-with-n-branches 也是题外话吗?
  • 嗨 V. Gai - 我认为在您编辑原始问题之前收到了一些要关闭的选票,将其拆分为明确定义的 Q 和单独的 A。还有一些人这样做 总是希望在问题中看到一些代码/努力 - 鉴于您已经提供了答案,我认为在这里它的应用有点过分热心。不过,话虽如此,您的问题已经获得了四票可以重新讨论,而且还需要一票,所以应该去那里。

标签: r tree


【解决方案1】:

我想介绍一个解决方案,我用它来构建一个带有 leafAmn 分支因子的树数据结构。为了在树中存储数据,使用了 myData 字段。还定义了打印树内容的功能。它还存在此任务的递归解决方案:R Tree With n Branches

# function to build N-ary tree
makeTree <- function(depth, leafAmn)  
{
## leafAmn - branching factor
## depth   - depth of tree
library(data.tree)

myTree <- Node$new("root", myData = c(-1)) # root node
for (i in 1:depth) # loop by tree depth
{
    if (i == 1)
    # create a set of nodes with depth 1
    {
        chldArr1 <- matrix("", 1, leafAmn)
        for (j in 1:leafAmn)
        {
            # create children nodes
            myTree$AddChild(j, myData = c())
            # save links to children nodes to array 'chldArr1'
            # this array is used to generate tree without using recursion
            chldArr1[j] <- sprintf("myTree$children[[%d]]$", j)
        }
    }
    else
    # add childs at level 'i' to nodes at level 'i-1' using 
    # method AddChild
    {
        chldArr2 <- matrix("", 1, (leafAmn ^ i))
        k <- 1
        for (j in 1:(leafAmn ^ (i - 1)))
        {
            for (m in 1:leafAmn)
            {
                # create string which contains a command to execute
                # this command is used to add child to nodes at previous level
                commStr <- paste(chldArr1[j], sprintf("AddChild(%d, myData = c())", m), sep = "")
                eval(parse(text = commStr))
                print(commStr)
                # save command to array 'chldArr2'
                chldArr2[k] <- paste(chldArr1[j], sprintf("children[[%d]]$", m), sep = "")
                k <- k + 1
            }
        }
        chldArr1 <- chldArr2
    }
}

## Make a tree with depth of '3' and 2 branches from each node
myTree <- makeTree(3, 2)
print(myTree, "myData")

>     myTree <- makeTree(3, 2)
[1] "myTree$children[[1]]$AddChild(1, myData = c())"
[1] "myTree$children[[1]]$AddChild(2, myData = c())"
[1] "myTree$children[[2]]$AddChild(1, myData = c())"
[1] "myTree$children[[2]]$AddChild(2, myData = c())"
[1] "myTree$children[[1]]$children[[1]]$AddChild(1, myData = c())"
[1] "myTree$children[[1]]$children[[1]]$AddChild(2, myData = c())"
[1] "myTree$children[[1]]$children[[2]]$AddChild(1, myData = c())"
[1] "myTree$children[[1]]$children[[2]]$AddChild(2, myData = c())"
[1] "myTree$children[[2]]$children[[1]]$AddChild(1, myData = c())"
[1] "myTree$children[[2]]$children[[1]]$AddChild(2, myData = c())"
[1] "myTree$children[[2]]$children[[2]]$AddChild(1, myData = c())"
[1] "myTree$children[[2]]$children[[2]]$AddChild(2, myData = c())"
>     print(myTree, "myData")
       levelName myData
1  root              -1
2   ¦--1             NA
3   ¦   ¦--1         NA
4   ¦   ¦   ¦--1     NA
5   ¦   ¦   °--2     NA
6   ¦   °--2         NA
7   ¦       ¦--1     NA
8   ¦       °--2     NA
9   °--2             NA
10      ¦--1         NA
11      ¦   ¦--1     NA
12      ¦   °--2     NA
13      °--2         NA
14          ¦--1     NA
15          °--2     NA

【讨论】:

  • 仅供参考,包已经这样做了。检查例如创建RegularTree(3,2)
【解决方案2】:

好吧,很久以前,当 Q-BASIC 没有任何指针选项时,有一种方法可以在没有指针的情况下表达二叉树。这是简单的数学技巧。当您将 1 分配给 root 时,它有两个孩子 - 2,3。 “2”有两个孩子“4, 5”,可以表示为“index*2”和“index*2+1”这样,我们可以只用数组来表示二叉树。这是我的代码。

#Binomial option pricing (2)
#We can expand the tree to more than 3rd depth.
#U = exp(volatility)
#D = exp(-volatility)
#p = 0.5 (We have the equal chance of making or losing money)
#Risk free rate = 0.02 => exp(0.02)
#For those who are not familiar with data structure, I deliberately used just array.
#I'll make a new code for those who are familiar with tree data structure

library(igraph)

#Define the variable
depth<-3 #How many steps (tree depth) do you want to make
rate <-0.02 #Risk Free rate
volatility <- 0.35
exercise_price <- 35
stock_price <- 47.5
upside_probability<-(exp(rate)-exp(-volatility))/(exp(volatility)-exp(-volatility))
rate <- exp(rate)

total_node<-2^depth-1 #Total number of node
G <- graph.tree(n=total_node, children=2) #I'll make a graph whose nodes are 7, and each node has two children
stock_tree <- (1:total_node)

stock_tree[1]<-stock_price
tree_traverse <- 2^(depth-1) -1

for(i in 1:tree_traverse) {
    #We are going to use mathematical trick to represent tree.
    stock_tree[i*2] <- stock_tree[i] * exp(volatility)
    stock_tree[i*2 + 1] <- stock_tree[i] * exp(-volatility)
}

V(G)$name <- round(stock_tree) #Name of the tree
lay <- layout.reingold.tilford(G) #It's tree. You can try other shape with other layout options
plot(G, layout=lay, vertex.size=15, edge.arrow.size=0.1) #Draw the tree.

#As opposed to the stock price, the option pricing starts out with end nodes (bottom nodes)
#I already explained the logic. Just follow it from one by one.
option_price<-(1:total_node)
bottom_node<-tree_traverse + 1

#In order to value the option, we need to calculate bottom line first.
for(i in bottom_node:total_node) {
  after_option <- stock_tree[i] - exercise_price

  if( after_option >0 ) {
    option_price[i] <- after_option
  } else {
    option_price[i] <- 0
  }
}

#Discount it back to current time while considering the probabilty of up and down
for(i in tree_traverse:1) {
    option_price[i]<-upside_probability*option_price[i*2]
    option_price[i]<-option_price[i]+(1-upside_probability)*option_price[i*2+1]
    option_price[i]<-option_price[i]/rate
}

V(G)$name <- round(option_price)
plot(G, layout=lay, vertex.size=15, edge.arrow.size=0.1)

【讨论】:

    猜你喜欢
    • 2014-04-18
    • 2017-10-21
    • 2014-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-06
    • 2017-11-28
    相关资源
    最近更新 更多