Changeset 15437 for branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/MctsSymbolicRegressionStatic.cs
- Timestamp:
- 10/27/17 18:42:04 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/MctsSymbolicRegressionStatic.cs
r15425 r15437 63 63 // TODO: Solve Poly-10 64 64 // TODO: After state unification the recursive backpropagation of results takes a lot of time. How can this be improved? 65 // TODO: Why is the algorithm so slow for rather greedy policies (e.g. low C value in UCB)?66 // TODO: check if we can use a quality measure with range [-1..1] in policies65 // ~~obsolete TODO: Why is the algorithm so slow for rather greedy policies (e.g. low C value in UCB)? 66 // ~~obsolete TODO: check if we can use a quality measure with range [-1..1] in policies 67 67 // TODO: unit tests for benchmark problems which contain log / exp / x^-1 but without numeric constants 68 68 // TODO: check if transformation of y is correct and works (Obj 2) … … 142 142 private readonly double[] predBuf, testPredBuf; 143 143 private readonly double[][] gradBuf; 144 145 // debugging stats146 // calculate for each level the number of alternatives the average 'inequality' of tries and 'inequality' of quality over the alternatives for each trie147 // inequality can be calculated using the Gini coefficient148 internal readonly double[] pathGiniCoeffs = new double[100];149 internal readonly double[] pathQs = new double[100];150 internal readonly double[] levelBestQ = new double[100];151 // internal readonly double[] levelMaxTries = new double[100];152 internal readonly double[] pathBestQ = new double[100]; // as long as pathBestQs = levelBestQs we are following the correct path153 internal readonly string[] levelBestAction = new string[100];154 internal readonly string[] curAction = new string[100];155 internal readonly double[] pathSelectedQ = new double[100];156 144 157 145 public State(IRegressionProblemData problemData, uint randSeed, int maxVariables, bool scaleVariables, … … 200 188 201 189 this.automaton = new Automaton(x, new SimpleConstraintHandler(maxVariables), allowProdOfVars, allowExp, allowLog, allowInv, allowMultipleTerms); 202 this.treePolicy = treePolicy ?? new Ucb();190 this.treePolicy = treePolicy ?? new EpsilonGreedy(); 203 191 this.tree = new Tree() { 204 192 state = automaton.CurrentState, … … 455 443 #endregion 456 444 457 #if DEBUG458 internal void ClearStats() {459 for (int i = 0; i < pathGiniCoeffs.Length; i++) pathGiniCoeffs[i] = -1;460 for (int i = 0; i < pathQs.Length; i++) pathGiniCoeffs[i] = -99;461 for (int i = 0; i < pathBestQ.Length; i++) pathBestQ[i] = -99;462 for (int i = 0; i < pathSelectedQ.Length; i++) pathSelectedQ[i] = -99;463 }464 internal void WriteGiniStats() {465 Console.WriteLine(string.Join("\t", pathGiniCoeffs.TakeWhile(x => x >= 0).Select(x => string.Format("{0:N3}", x))));466 }467 internal void WriteQs() {468 // Console.WriteLine(string.Join("\t", pathQs.TakeWhile(x => x >= -100).Select(x => string.Format("{0:N3}", x))));469 var sb = new StringBuilder();470 // length471 int i = 0;472 while (i < pathBestQ.Length && pathBestQ[i] > -99 && pathBestQ[i] == levelBestQ[i]) {473 i++;474 }475 sb.AppendFormat("{0,-3}",i);476 477 i = 0;478 // sb.AppendFormat("{0:N3}", levelBestQ[0]);479 while (i < pathSelectedQ.Length && pathSelectedQ[i] > -99) {480 sb.AppendFormat("\t{0:N3}", pathSelectedQ[i]);481 i++;482 }483 Console.WriteLine(sb.ToString());484 sb.Clear();485 i = 0;486 // sb.AppendFormat("{0:N3}", levelBestQ[0]);487 while (i < pathBestQ.Length && pathBestQ[i] > -99) {488 sb.AppendFormat("\t{0:N3}", pathBestQ[i]);489 i++;490 }491 Console.WriteLine(sb.ToString());492 sb.Clear();493 i = 0;494 while (i < pathBestQ.Length && pathBestQ[i] > -99) {495 sb.AppendFormat("\t{0:N3}", levelBestQ[i]);496 i++;497 }498 Console.WriteLine(sb.ToString());499 500 sb.Clear();501 i = 0;502 while (i < pathBestQ.Length && pathBestQ[i] > -99) {503 sb.AppendFormat("\t{0,-5}", (curAction[i] != null && curAction[i].Length > 5) ? curAction[i].Substring(0, 5) : curAction[i]);504 i++;505 }506 Console.WriteLine(sb.ToString());507 sb.Clear();508 i = 0;509 while (i < pathBestQ.Length && pathBestQ[i] > -99) {510 sb.AppendFormat("\t{0,-5}", (levelBestAction[i] != null && levelBestAction[i].Length > 5) ? levelBestAction[i].Substring(0, 5) : levelBestAction[i]);511 i++;512 }513 Console.WriteLine(sb.ToString());514 515 Console.WriteLine();516 }517 518 519 #endif520 445 521 446 } … … 578 503 bool success = false; 579 504 do { 580 #if DEBUG 581 mctsState.ClearStats(); 582 #endif 505 583 506 automaton.Reset(); 584 507 success = TryTreeSearchRec2(rand, tree, automaton, eval, treePolicy, mctsState, out q); … … 588 511 589 512 #if DEBUG 590 // mctsState.WriteGiniStats();591 513 Console.WriteLine(ExprStr(automaton)); 592 mctsState.WriteQs();593 // Console.WriteLine(WriteStatistics(tree, mctsState));594 595 514 #endif 596 //if (mctsState.effectiveRollouts % 100 == 1) {597 // Console.WriteLine(WriteTree(tree, mctsState));598 // Console.WriteLine(TraceTree(tree, mctsState));599 //}600 515 return q; 601 516 } … … 620 535 621 536 while (!automaton.IsFinalState(automaton.CurrentState)) { 537 Console.WriteLine(automaton.stateNames[automaton.CurrentState]); 622 538 if (state.children.ContainsKey(tree)) { 623 539 if (state.children[tree].All(ch => ch.Done)) { … … 631 547 selectedIdx = treePolicy.Select(state.children[tree].Select(ch => ch.actionStatistics), rand); 632 548 } 633 634 // STATS635 state.pathGiniCoeffs[tree.level] = InequalityCoefficient(state.children[tree].Select(ch => (double)ch.actionStatistics.AverageQuality));636 state.pathQs[tree.level] = tree.actionStatistics.AverageQuality;637 549 638 550 tree = state.children[tree][selectedIdx]; 639 551 640 552 // move the automaton forward until reaching the state 641 // all steps where no alternatives are possible are immediately taken553 // all steps where no alternatives could be taken immediately (without expanding the tree) 642 554 // TODO: simplification of the automaton 643 int[] possibleFollowStates ;555 int[] possibleFollowStates = new int[1000]; 644 556 int nFs; 645 automaton.FollowStates(automaton.CurrentState, out possibleFollowStates, out nFs); 646 // TODO! 647 // while (possibleFollowStates[0] != tree.state && nFs == 1 && 648 // !automaton.IsEvalState(possibleFollowStates[0]) && !automaton.IsFinalState(possibleFollowStates[0])) { 649 // automaton.Goto(possibleFollowStates[0]); 650 // automaton.FollowStates(automaton.CurrentState, out possibleFollowStates, out nFs); 651 // } 557 automaton.FollowStates(automaton.CurrentState, ref possibleFollowStates, out nFs); 652 558 Debug.Assert(possibleFollowStates.Contains(tree.state)); 653 559 automaton.Goto(tree.state); 654 560 } else { 655 561 // EXPAND 656 int[] possibleFollowStates ;562 int[] possibleFollowStates = new int[1000]; 657 563 int nFs; 658 564 string actionString = ""; 659 automaton.FollowStates(automaton.CurrentState, out possibleFollowStates, out nFs); 660 // TODO 661 // while (nFs == 1 && !automaton.IsEvalState(possibleFollowStates[0]) && !automaton.IsFinalState(possibleFollowStates[0])) { 662 // actionString += " " + automaton.GetActionString(automaton.CurrentState, possibleFollowStates[0]); 663 // // no alternatives -> just go to the next state 664 // automaton.Goto(possibleFollowStates[0]); 665 // automaton.FollowStates(automaton.CurrentState, out possibleFollowStates, out nFs); 666 // } 565 automaton.FollowStates(automaton.CurrentState, ref possibleFollowStates, out nFs); 566 667 567 if (nFs == 0) { 668 568 // stuck in a dead end (no final state and no allowed follow states) … … 676 576 // for selected states (EvalStates) we introduce state unification (detection of equivalent states) 677 577 if (automaton.IsEvalState(possibleFollowStates[i])) { 678 var hc = Hashcode(automaton); 578 var hc = Hashcode(automaton); // TODO fix unit test for structure enumeration 679 579 if (!state.nodes.TryGetValue(hc, out child)) { 680 580 child = new Tree() { … … 688 588 } 689 589 // only allow forward edges (don't add the child if we would go back in the graph) 690 else if (child.level > tree.level) 590 else if (child.level > tree.level) { 691 591 // whenever we join paths we need to propagate back the statistics of the existing node through the newly created link 692 592 // to all parents … … 696 596 Debug.Assert(child.level <= tree.level); 697 597 child = null; 698 } 598 } 699 599 } else { 700 600 child = new Tree() { … … 740 640 q = eval(code, nParams); 741 641 // Console.WriteLine("{0:N4}\t{1}", q*q, tree.expr); 742 q = TransformQuality(q);743 642 success = true; 744 BackpropagateQuality(tree, q, treePolicy, state); 643 BackpropagateQuality(tree, q, treePolicy, state); 745 644 } else { 746 645 // we got stuck in roll-out (not evaluation necessary!) … … 758 657 759 658 return success; 760 }761 762 private static double InequalityCoefficient(IEnumerable<double> xs) {763 var arr = xs.ToArray();764 var sad = 0.0;765 var sum = 0.0;766 767 for(int i=0;i<arr.Length;i++) {768 for(int j=0;j<arr.Length;j++) {769 sad += Math.Abs(arr[i] - arr[j]);770 sum += arr[j];771 }772 }773 return 0.5 * sad / sum;774 }775 776 private static double TransformQuality(double q) {777 // no transformation778 return q;779 780 // EXPERIMENTAL!781 782 // Fisher transformation783 // (assumes q is Correl(pred, target)784 785 q = Math.Min(q, 0.99999999);786 q = Math.Max(q, -0.99999999);787 return 0.5 * Math.Log((1 + q) / (1 - q));788 789 // optimal result: q = 1 -> return huge value790 // if (q >= 1.0) return 1E16;791 // // return number of 9s in R²792 // return -Math.Log10(1 - q);793 659 } 794 660 … … 840 706 } 841 707 842 state.pathSelectedQ[tree.level] = tree.actionStatistics.AverageQuality;843 state.pathBestQ[tree.level] = tree.actionStatistics.BestQuality;844 state.curAction[tree.level] = tree.expr;845 if (state.levelBestQ[tree.level] < tree.actionStatistics.BestQuality) {846 state.levelBestQ[tree.level] = tree.actionStatistics.BestQuality;847 state.levelBestAction[tree.level] = tree.expr;848 }849 708 } 850 709 … … 855 714 Tree minChild = children.First(); 856 715 for (int i = 1; i < children.Count; i++) { 857 if (children[i].state < minChild.state)716 if (children[i].state < minChild.state) 858 717 selectedChildIdx = i; 859 718 } … … 883 742 } else { 884 743 // EXPAND 885 int[] possibleFollowStates ;744 int[] possibleFollowStates = new int[1000]; 886 745 int nFs; 887 automaton.FollowStates(automaton.CurrentState, outpossibleFollowStates, out nFs);746 automaton.FollowStates(automaton.CurrentState, ref possibleFollowStates, out nFs); 888 747 if (nFs == 0) { 889 748 // stuck in a dead end (no final state and no allowed follow states) … … 1062 921 } 1063 922 1064 foreach (var tup in list) {923 foreach (var tup in list) { 1065 924 var ch = tup.Item3; 1066 925 var chId = tup.Item2; 1067 if (state.children.ContainsKey(ch) && state.children[ch].Count == 1) {926 if (state.children.ContainsKey(ch) && state.children[ch].Count == 1) { 1068 927 var chch = state.children[ch].First(); 1069 928 nextId++;
Note: See TracChangeset
for help on using the changeset viewer.