public void Traverse(StratTree node, int level, Action <StratTree> inFixAction) { if (node.Left != null) { Traverse(node.Left, level + 1, inFixAction); } inFixAction(node); if (node.Right != null) { Traverse(node.Right, level + 1, inFixAction); } }
public StratTree Copy() { StratTree target = this; StratTree copy = new StratTree(target.refName, target.Term); if (target.Right != null) { copy.Right = target.Right.Copy(); copy.Right.Parent = copy; } if (target.Left != null) { copy.Left = target.Left.Copy(); copy.Left.Parent = copy; } return(copy); }
override public void Preprocess() { stratForest.Clear(); var l = new List <Tuple <string, StratTerm> >(); foreach (KeyValuePair <string, StratTerm[]> kvp in stratCatalog) { string sn = kvp.Key; StratTerm[] ta = kvp.Value; for (int i = 0; i < ta.Length; i++) { l.Add(new Tuple <string, StratTerm>(sn, ta[i])); } } var sl = SortTermList(l); bool first = true; StratTree root = null; foreach (Tuple <string, StratTerm> tuple in sl) { if (first) { root = new StratTree(tuple.Item1, tuple.Item2); } else { root.InsertAtTop(new StratTree(tuple.Item1, tuple.Item2));//for a single composite decision tree } if (first && root != null) { stratForest.Add(root); } first = false; } Debug.Assert(stratForest.Count == 1 || stratForest.Count == 0, "Bad forest size in advanced Finder class"); }
virtual public void Preprocess() { stratForest.Clear(); foreach (KeyValuePair <string, StratTerm[]> kvp in stratCatalog) { string sn = kvp.Key; StratTerm[] ta = kvp.Value; StratTree root = null; for (int i = 0; i < ta.Length; i++) { if (root == null) { root = new StratTree(sn, ta[0]); } else { root.InsertSingleStrata(new StratTree(sn, ta[i]));//for a forest of single decision trees } } stratForest.Add(root); } }
public bool TryEval(Dictionary <string, string> parcelData, out bool strataWasFound, out string resultStrata) { StratTree target = this; string val; bool result = false; while (true) { //walk tree if (parcelData.TryGetValue(target.Term.variable, out val)) { //there is a condition for this variable, we can check it result = false; if (target.Term.TryEval(val, out result)) { //evaluation succeeded if (result) { //eval'd to T if (target.Right != null) { //go right target = target.Right; continue; } else {//leaf break; } } else { //eval'd to F if (target.Left != null) { //go left target = target.Left; continue; } else {//leaf break; } } } else {//evaluation failed resultStrata = null; strataWasFound = false; //this is an error; something went wrong in the evaluation of a tree node ie. data type error in operations return(false); } } else { //nothing to check; truth if (target.Right != null) { //nothing to check; must be true; go right target = target.Right; continue; } else {//nothing to check; hit leaf; done, return strata break; } } }//end tree walk strataWasFound = result; if (result) { //last node visit Eval'd to T resultStrata = target.refName; } else { //last node visit Eval'd to F resultStrata = null; } return(true); }
public void InsertSingleStrata(StratTree node) //for verification { StratTree target = this; while (true) { if (node.Term.variable == target.Term.variable) { //case: same var if (node.Term.condition != target.Term.condition) { //same var, diff cond if (target.Right != null) { target = target.Right; continue; } else { target.Right = node; break; } } else {//same var, same cond if (node.Term.condition == StratTermVal.gt || node.Term.condition == StratTermVal.lte) {//numer constant double nodec = 0.0; double targc = 0.0; try { nodec = Double.Parse(node.Term.constant); targc = Double.Parse(target.Term.constant); } catch { break; //skip invalid - correctness requires aprior validation i.e no type op issues } if (target.Right != null) { target = target.Right; continue; } else { target.Right = node; break; } } else {//categ constant i.e. IN { A,B } //ignored } } } else { //case: diff var if (target.Right != null) { //case: interior node target = target.Right; continue; } else {//case: leaf node target.Right = node; break; } } } }
public void InsertSort(StratTree node) { StratTree target = this; //DRY utils void SwapNodeData() { StratTerm t = node.Term; //struct so copy by value node.Term = target.Term; target.Term = t; string n = node.refName; node.refName = target.refName; target.refName = n; } while (true) { if (node.Term.variable == target.Term.variable) { //case: same var if (node.Term.condition != target.Term.condition) { //same var, diff cond if (target.Right != null) { target = target.Right; continue; } else { target.Right = node; break; } } else {//same var, same cond if (node.Term.condition == StratTermVal.gt || node.Term.condition == StratTermVal.lte) {//numer constant double nodec = 0.0; double targc = 0.0; try { nodec = Double.Parse(node.Term.constant); targc = Double.Parse(target.Term.constant); } catch { break; //skip invalid - correctness requires aprior validation i.e no type op issues } if (target.Right != null) { target = target.Right; continue; } else { target.Right = node; break; } } else {//categ constant i.e. IN { A,B } //ignored } } } else { //case: diff var if (target.Right != null) { //case: interior node if (String.Compare(target.Term.variable, node.Term.variable) > 0) { //target.refName follows node.refName in the sort order target = target.Right; } else { target = target.Right; } continue; } else { //case: leaf node if (String.Compare(target.Term.variable, node.Term.variable) > 0) { //target.refName follows node.refName in the sort order // so switch target and node i.e. target ends up being the right leaf if (target.Parent == null) {//data swap if target is root SwapNodeData(); target.Right = node; node.Parent = target; } else { target.Parent.Right = node; node.Parent = target.Parent; node.Right = target; } } else {//just add as a right leaf of target target.Right = node; node.Parent = target; } break; } } } }
public void InsertAtTop(StratTree node) {//insert a new decision tree node at the top StratTree target = this; Debug.Assert(node.Left == null && node.Right == null, "Not leaf node passed as node"); Debug.Assert(target.Parent == null, "Called on not root node"); //DRY locals void SwapNodeData() { StratTerm t = node.Term; //struct so copy by value node.Term = target.Term; target.Term = t; string n = node.refName; node.refName = target.refName; target.refName = n; } void SwapNodeLinks() {//node is the initial root, target is now the item being inserted on top, since SwapNodeData is called before this node.Parent = target; node.Right = target.Right; node.Left = target.Left; target.Right = node; target.Left = node.Copy(); } if (String.Compare(target.Term.variable, node.Term.variable) < 0) {//target-var precedes node-var in the sort order SwapNodeData(); SwapNodeLinks(); } else if (String.Compare(target.Term.variable, node.Term.variable) == 0) {//same var SwapNodeData(); SwapNodeLinks(); /* * the <= / lte are sorted in order of decreasing constant * x < 10 * x < 5 * ** ** the > / gt are sorted in order of increasing constant ** x > 8 ** x > 2 ** ** ** x < 10 ** x > 8 ** x < 5 ** x > 2 */ } else { throw new Exception("Variable names must be inserted in Sorted Order"); } }