我有一个txt文件,其中包含一系列数字,如下所示:
1 1 3 2
2 2 1 1
3 2 3 1
2 2 2 2
1 1 1 1
3 2 3 2
1 1 3 1
2 1 1 1
(这只是解释我的问题的一个例子。)文件txt中的每一行有四个以空格分隔的位置。第一个和第三个可以假设三个值:1,2或3。 其余的位置只能假设两个值:1或2.
每行代表树的路径。树由根节点和形成层次结构的附加节点的级别组成:第一级和第三级可以具有三个节点(1,2或3),依此类推,如前所述。
然后,前面例子描述的树如下:
我会修剪树,如下图所示:
以红色圈出的节点必须缩减为一个节点,因为圈子中的每个节点只有一个叶子。
答案 0 :(得分:1)
您可以通过查看表/矩阵中的每对相邻列来确定哪些节点只有一个子节点,并观察每个数字旁边显示的次数。假设您的数据存储在mat
:
> mat
[,1] [,2] [,3] [,4]
[1,] 1 1 3 2
[2,] 2 2 1 1
[3,] 3 2 3 1
[4,] 2 2 2 2
[5,] 1 1 1 1
[6,] 3 2 3 2
[7,] 1 1 3 1
[8,] 2 1 1 1
对于前两列,我们删除所有重复项(即相同的子路径),我们查看每个数字与其邻居的出现次数,并计算有多少不同的路径:
> table(mat[,c(1,2)][!duplicated(mat[,c(1,2)]),1])
1 2 3
1 2 1
正如你所看到的,1有一条路径,因此可以修剪,也可以3.最后,2有2条路径,所以我们不会修剪它。
下一部分很棘手,因为你只想看看子树(因为例如1 - > 1可能出现在树的一部分而1 - > 2可能出现在另一部分但是如果他们不共享父母,我们可能仍希望修剪他们)。类似的东西:
table(mat[mat[,newLevel]==newRoot,c(2,3)][!duplicated(mat[mat[,newLevel]==newRoot,c(2,3)]),1])
其中newLevel是您要使用的矩阵的列,newRoot是该级别中将成为子树根的节点的值。例如,使用树的第一级中的节点,值为2作为根:
> table(mat[mat[,1]==2,c(2,3)][!duplicated(mat[mat[,1]==2,c(2,3)]),1])
1 2
1 2
正如您所看到的,它发现1应该被修剪,2不应该,对于前2个节点正下方的节点。然后,您将通过树迭代它(例如,您可以递归地实现它。)