gpt4 book ai didi

Java - 沿二叉树评估节点值

转载 作者:搜寻专家 更新时间:2023-11-01 03:35:53 24 4
gpt4 key购买 nike

我是树结构的新手。我正在尝试设计一种将预定树作为输入的算法。
然后它应该用我自己设计的对象(我认为它与算法的设计无关,但该对象是一个 ArrayList)为树的根做种子,并使用“更改运算符”来修改该对象沿着树的每个分支。更改运算符的传递次数取决于分支长度。
必须在树的每个节点上评估对象,然后使用该节点值评估其子节点的值。因此,我不能简单地使用从根到尖端的总长度来评估每个尖端的值,因为我使用的更改运算符是随机的,而不是确定性的。因此,每个子节点的值取决于其父节点的值。

我试图自己设计这个。我首先创建了一个时间数组,在这些时间中,单个分支将拆分为其子项。

int[] times = new int[branchnumber];
times[0] = 1;
times[1] = 5;

然后,我创建了一个方法,它获取应该发生分支的时间(我将其解释为分支长度)、ArrayList 对象、当前时间和分支总数。
public static void Brancher(int[] times, List<double[][]> sequences, int t){
boolean checker = false;
for (int i = 0; i < times.length; i++) {
if (times[i] == t) {
checker = true;
}
}
if (checker == true) {
double[][] seq = sequences.get(sequences.size() - 1);
sequences.add(seq);
}
}

Brancher 方法实现如下:
for (int j = 0; j <= loopnumber; j++) {
MathsOperators.Brancher(times, sequences, t);

for (int i = 0; i < sequences.size(); i++) {
double[][] sequenceholder = sequences.get(i);
MathsOperators.PrintOutput(sequenceholder, t);
ComplexInput.evolvesequence(sequenceholder, frequencies, transitionrate, transversionrate, random);
sequences.set(i, sequenceholder);
}

t = t + dt;
}

因此,我将树中所有对象的当前状态保存为序列 ArrayList 中保存的数组。
这些对象然后由进化方法处理,更新的对象替换 ArrayList 中的原始对象。
当要添加一个分支时,Brancher 方法获取 ArrayList 中的最后一个 Array 对象,将其复制,然后将副本添加到列表中。这实际上模拟了将最后一个对象拆分为两个对象。然后在模拟循环的下一次迭代中更新和演化副本。

这种做事的方法虽然不漂亮,但导致树看起来像这样: http://content.science20.com/files/Tree3A.jpg .这是一个相对简单的结构。

但是,创建这种形状的树是不可能的: http://content.science20.com/files/Tree4.jpg .这棵树在最右边有多个 split 。我不知道描述这里树之间差异的确切术语,但它相当明显。

我想我在这里混淆了自己。任何关于如何思考这个问题的建议将不胜感激。

(如果它对上下文有帮助,输入对象是一个遗传序列(ACGT)。这个想法是沿着树的每个分支进化序列,每个尖端代表原始祖先(输入)序列的后代)

编辑

输入对象是一个 ArrayList,包含多个 (n x 2) 数组。每个数组的第一列包含集合 {1,2,3,4} 中的 n 个整数,频率由我控制。但是,这些字符在列中的顺序是随机的。每个整数代表 DNA 序列中的字符 A、C、G、T 之一。第二列包含代表每个 DNA 位点进化速率的 double 值,因此每个整数条目一个速率条目。初始数组是使用我称为 DNASEQ 的函数生成的,它很长,对这个问题没有影响。

首先,我生成这些数组之一,并将其​​添加到称为序列的 ArrayList。使用上面显示的模拟循环,然后我将进化序列方法应用于 ArrayList 中的每个数组。

当 Brancher 检测到每次循环后以 1 为增量更新的时间等于指定的分支次数之一时,它会取 ArrayList 中的最后一个 Array 并将该数组的副本添加到 Arraylist 中。如果模拟在那里停止,则 Array 将与从中复制的 Array 相同。但是,现在它在ArrayList中,它受evolvesequence方法的约束。由于进化序列是一种随机/概率方法,那么对于给定的输入,没有两个输出保证是相同的。因此,经过几次模拟循环迭代后,复制的 Array 将与原始数组大不相同。

The original sequence is displayed, and then copied by Brancher. Now I have two sequences of identical origin, evolving independently. This is the same as a branch of a tree.

最佳答案

通过对特定任务的孤立 View ,为您非常特殊的树实现非常特殊的算法可能会有所帮助。

但是,正如您在评论中看到的那样,这使得局外人更难理解您的代码,但只有自己才能帮助您。因此,我建议你使用这个结构:Java tree data-structure? .

好处是这是一个众所周知的结构,每个对数据结构有一定了解的人都应该能够帮助你。该结构足够通用,它应该能够反射(reflect)您尝试构建的树的所有变体。

此外,您似乎正在构建树,同时用数据填充它,这是正确的吗?这就是我刚才发生的。这两个步骤看起来并不相互依赖,因此您可以先创建树,然后在第二个循环中遍历它以填充数据?如果你能把这两个步骤分开,你的代码就会变得更加清晰易懂。

如果你只想要一个二叉树(即每个节点最多有两个 child 的树),你甚至可以通过没有 ArrayList<Node<T>> 来简化结构。作为 child ,但一个leftChild和一个 rightChild .

之后,您将根节点的数据设置为初始 double[][] ,然后按照适合您的任务的顺序遍历树并修改每个节点的数据。从每个节点,您可以访问其子节点和父节点,即从树中的每个节点,您可以访问存储在树中的完整信息,这些信息应该为您提供更新节点数据所需的所有信息。当然,您必须对树进行可视化,并确切地知道您现在所在的节点、您需要什么信息以及如何访问它(即,如何导航到您需要的信息)。

关于Java - 沿二叉树评估节点值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31725292/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com