/// <summary> /// Initializes a new instance of the <see cref="TreeNode"/> class. /// </summary> /// <param name="parent"> /// Parent node. /// </param> /// <param name="content"> /// Content of the this node. /// </param> /// <param name="table"> /// Parameters table. /// </param> /// <exception cref="ArgumentNullException"> /// Thrown if parent is null. /// </exception> public TreeNode(AbstractNode parent, IBaseObject content, PhantomTable table) { if (parent == null) { throw new ArgumentNullException("parent", "Parent node is null"); } this.parent = parent; Level = this.parent.Level + 1; Volume = table[Level + 1].Volume; id = content; StartPosition = table.StartPositions[Level]; }
/// <summary> /// Initializes a new instance of the <see cref="TreeTop"/> class, /// representing root element of the tree. /// </summary> /// <param name="source"> /// The input chain. /// </param> /// <param name="generator"> /// The gen. /// </param> public TreeTop(BaseChain source, IGenerator generator) { table = new PhantomTable(source); this.generator = generator; StartPosition = 0; Volume = table[0].Volume; Level = -1; if ((table[1].Content[0] is ValueString) || (table[1].Content[0] is BaseChain)) { isString = true; } if ((source != null) && (source.GetLength() != 0)) { var temp = (ValuePhantom)source[0]; for (int i = 0; i < temp.Cardinality; i++) { Children.Add(new TreeNode(this, temp[i], table)); } } }
/// <summary> /// Choosing which child will generate next element of sequence. /// </summary> /// <param name="result"> /// Intermediate result. /// </param> /// <param name="generator"> /// Random numbers generator. /// </param> /// <param name="table"> /// Phantom sequence parameters table. /// </param> protected void Find(BaseChain result, IGenerator generator, PhantomTable table) { // if not leaf node if (Children.Count != 0) { double val = generator.Next(); ulong curVal = 0; foreach (TreeNode child in Children) { curVal += child.Volume; if (val <= ((double)curVal / Volume)) { child.FillChain(result, generator, table); return; } } } else { // if there is no children nodes then generation is done and decrement procedure is started Decrement(); } }
/// <summary> /// Method adds new element into generated sequence. /// And calls the same method of one of the children if sequence is incomplete. /// </summary> /// <param name="result"> /// Generated sequence. /// </param> /// <param name="generator"> /// Random number generator. /// </param> /// <param name="table"> /// Parameters table. /// </param> public void FillChain(BaseChain result, IGenerator generator, PhantomTable table) { if ((table.Length != (Level + 2)) && (Children.Count == 0)) { ValuePhantom temp = table[Level + 2].Content; for (int i = 0; i < temp.Cardinality; i++) { Children.Add(new TreeNode(this, temp[i], table)); } } if ((id is BaseChain) || (id is ValueString)) { string amino = id.ToString(); for (int k = 0; k < amino.Length; k++) { result[StartPosition + k] = new ValueString(amino[k]); } } else { result[StartPosition] = id; } Find(result, generator, table); }