Algorithm 生成二叉树的所有可能子树

Algorithm 生成二叉树的所有可能子树,algorithm,Algorithm,我有一个二叉树,我想从中生成所有可能的子树。 例如: 1 / \ 2 3 / \ 4 5 可能的输出为: 1, 2, 3, 4, 5. (1,2) (1,3) (1,3,4) (1,3,5) 这可能吗?我需要一个算法来生成输出 让我用伪代码发布答案: 首先,让我向您展示如何实现三个: Node{ Node rightNode; Node leftNode; String value; } 然后是算法: Algoritm{

我有一个二叉树,我想从中生成所有可能的子树。 例如:

   1
  /  \
2     3 
     /  \
    4    5 
可能的输出为:

1, 2, 3, 4, 5.
(1,2) (1,3) 
(1,3,4) (1,3,5) 

这可能吗?我需要一个算法来生成输出

让我用伪代码发布答案:

首先,让我向您展示如何实现三个:

Node{
 Node rightNode;
 Node leftNode;
 String value;
}
然后是算法:

Algoritm{
    String[] posibleThrees;

    String getPosibleThrees(Node root){
        getPosibleThree(root, "");
        return posibleThrees;
    }

    void getPosibleThree(Node node, String nodesBefore){
        posibleThrees[] = nodesBefore; //adding nodes before

        if (node.rightNode != null){
            getPosibleThree(node.rightNode, nodesBefore+" "+node.value);
        } 

        if (node.leftNode != null) {
           getPosibleThree(node.leftNode, nodesBefore+" "+node.value);
        }
    }
}

系统发育学必须做很多这方面的工作

类似这样的程序可以解决此问题:

鉴于:

  • 进化模型(突变的可能性等)
  • 当前几种物种的遗传序列(从中可以找到每对物种之间进化距离的矩阵)
发现:最大似然进化树

您从猜测开始,搜索树空间,根据您的模型查找可能性更高的排列。当达到局部最小值时停止。再次尝试几个不同的起始树,希望找到一个全局最小值

已经为系统发育学编写了大量迭代可能的树的代码,所以如果您需要类似的东西,这是一个寻找想法的好地方


对于给定的起始树,我自己的库(和示例前端)可以为您提供通过一个子树修剪/重新移植可以到达的所有可能的树。它只进行树的重新排列,并且没有代码与似然计算混杂在一起。我很久以前写过它,有些是在2004年,有些是在2007年,但它仍然可能比非程序员编写的典型系统发育软件更具可读性

我差不多完成了,我想一些代码可能已经找到了它的方法。我认为让procov使用这个库是我开始写它时的想法

它没有经过修饰,代码有点凌乱,我基本上是在编写API时编写的。使用它的人可能需要定制它。我整理了一些最令人困惑的部分,因为8年前我似乎从未做出过最后几次改变

无论如何,对于给定的树,理论上有一个最大可能的SPR数,其中许多SPR将生成重复的树

  • 给定此范围内的数字,
    spr.c:spr\u sprnum(struct spr\u tree*tree,int-coded\u sprnum)
    将其解码为一个spr,并尝试应用它

  • spr.c:int-spr\u next\u spr(struct spr\u tree*tree)
    尝试编号的spr,直到找到合法的spr,或返回到开头

它会记住刚刚执行的SPR,因此它首先撤消最后一个SPR,然后执行新的SPR

为了以随机顺序迭代所有SPR,我的代码找到一个将生成从1到N的所有数字的函数,该函数只生成一次,然后重复。找到LCG参数需要找到合适的素数,因此在
LCG.c

brontler
是一个演示前端,可以在命令行上或从文件中获取Newick格式的树。e、 g

./brontler '(((a,b),c),(d,e))'
tree: taxa: 5, nodes: 9, possible SPRs <= 72
1: tree 1.45: (c,(((a,b),d),e));
2: tree 1.10: (a,((b,c),(d,e)));
3: tree 1.59: (c,(d,((a,b),e)));
4: tree 1.29: (((a,c),b),(d,e));
5: tree 1.60: ((b,c),(d,(a,e)));
6: tree 1.61: ((a,c),(d,(e,b)));
7: tree 1.69: (((a,(b,e)),c),d);
8: tree 1.53: ((((d,a),b),c),e);
9: tree 1.46: ((b,c),((a,d),e));
10: tree 1.54: (e,((a,(d,b)),c));
11: tree 1.68: (d,(((a,e),b),c));
12: tree 1.47: ((a,c),((d,b),e));
tree iteration 1 gave 12 new trees
/brontler'((a,b,c),(d,e))'

树:分类群:5,节点:9,可能的SPR简单答案:是和是。你能帮我一个简单的算法吗?我会很高兴,因为我很困惑。(3,4)和(3,5)在我看来也像子树。(顺便说一句:查找加泰罗尼亚数字)Yes@wildplasser:这也是一个可能的输出…(3,4)和(3,5)也是一个答案这只是对树的宽度优先遍历,在发现每个节点时打印路径。非常感谢carlos。这可以扩展到深度>3吗?我还没有试过Carlos的伪代码,但我猜是可以使用的。我使用这个(二叉树问题有点类似,但我只是链接到这个代码来解释递归的使用)难道没有一个通用算法来从给定的二叉树生成所有子树吗?我觉得phyml也是complex@Ashwin:当我是达尔豪西的系统发育学小组的系统管理员和全能计算机极客时,我用C编写了一个简单的全spr(子树修剪/重植)库。我想我已经达到了它正常工作的程度,但我认为没有人使用过它。我会把它放到github上,以防万一。对于一棵开始的树,它应该给你所有的树,你可以达到一个修剪/重新种植。我需要它。这会有很大的帮助!请在发布链接时告诉我。@AshwinVenkataraman:它不是开箱即用的。现在整理一下:P。整理好后我会再评论。非常感谢@PeterCordes