Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
03/11/17 20:07:13 (7 years ago)
Author:
pkimmesw
Message:

#2665 PooledPushProgram reduces memory usage and increases performance

Location:
branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push
Files:
1 added
2 deleted
14 edited

Legend:

Unmodified
Added
Removed
  • branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/CodeExpressions.cs

    r14745 r14746  
    108108      var second = interpreter.CodeStack.Top;
    109109
    110       var isFirstList = first.CanExpand;
    111       var isSecondList = second.CanExpand;
    112 
    113       Expression[] result = null;
     110      var isFirstList = first.IsProgram;
     111      var isSecondList = second.IsProgram;
     112
     113      PushProgram result;
    114114
    115115      if (isFirstList) {
    116         var expand1 = first as PushProgram;
     116        var program1 = first as PushProgram;
    117117
    118118        if (isSecondList) {
    119           var expand2 = second as PushProgram;
    120           var size = expand2.State.Length + expand1.State.Length;
     119          var program2 = second as PushProgram;
     120          var size = program2.Expressions.Count + program1.Expressions.Count;
    121121
    122122          // if size > maxPointsInProgram this expressions results in a NOOP
    123123          if (size > interpreter.Configuration.MaxPointsInProgram) return false;
    124124
    125           result = new Expression[size];
    126 
    127           Array.Copy(expand2.State, result, expand2.State.Length);
    128           Array.Copy(
    129               expand1.State,
    130               0,
    131               result,
    132               expand2.State.Length,
    133               expand1.State.Length);
     125          result = PushProgram.Merge(interpreter.PushProgramPool, program2, program1);
    134126        } else {
    135           var size = expand1.State.Length + 1;
     127          var size = program1.Expressions.Count + 1;
    136128
    137129          // if size > maxPointsInProgram this expressions results in a NOOP
    138130          if (size > interpreter.Configuration.MaxPointsInProgram) return false;
    139131
    140           result = new Expression[size];
    141           result[0] = second;
    142 
    143           Array.Copy(expand1.State, 0, result, 1, expand1.State.Length);
     132          result = PushProgram.Merge(interpreter.PushProgramPool, second, program1);
    144133        }
    145134      } else if (isSecondList) {
    146         var expand2 = second as PushProgram;
    147 
    148         var size = expand2.State.Length + 1;
     135        var program2 = second as PushProgram;
     136        var size = program2.Expressions.Count + 1;
    149137
    150138        // if size > maxPointsInProgram this expressions results in a NOOP
    151139        if (size > interpreter.Configuration.MaxPointsInProgram) return false;
    152140
    153         result = new Expression[size];
    154         result[0] = first;
    155 
    156         Array.Copy(expand2.State as Expression[], 0, result, 1, expand2.State.Length);
     141        result = PushProgram.Merge(interpreter.PushProgramPool, first, program2);
    157142      } else {
    158         result = new[] { second, first };
     143        result = PushProgram.Create(interpreter.PushProgramPool, second, first);
    159144      }
    160145
    161       var expression = new PushProgram(result);
    162 
    163       interpreter.CodeStack.SetTop(expression);
     146      interpreter.CodeStack.SetTop(result);
    164147
    165148      return true;
     
    177160
    178161      var expression = interpreter.CodeStack.Pop();
    179       var isExpandExpression = expression.CanExpand;
     162      var isExpandExpression = expression.IsProgram;
    180163
    181164      interpreter.BooleanStack.Push(!isExpandExpression);
     
    199182
    200183      if (expand.IsEmpty) return false;
    201       var first = expand.State[expand.State.Length - 1];
     184      var first = expand.Expressions[expand.Expressions.Count - 1];
    202185
    203186      interpreter.CodeStack.SetTop(first);
     
    217200      if (interpreter.CodeStack.Count == 0) return false;
    218201
    219       PushProgram expandExpression;
     202      PushProgram result;
    220203      var top = interpreter.CodeStack.Top;
    221204
    222       if (top.CanExpand) {
    223         var expand = (PushProgram)top;
    224 
    225         if (expand.IsEmpty) return false;
    226         var length = expand.State.Length - 1;
    227         var newExpressions = new Expression[length];
    228 
    229         Array.Copy((Expression[])expand.State, 0, newExpressions, 0, length);
    230 
    231         expandExpression = new PushProgram(newExpressions);
     205      if (top.IsProgram) {
     206        var program = (PushProgram)top;
     207
     208        if (program.IsEmpty) return false;
     209
     210        result = program.Copy(interpreter.PushProgramPool, 0, program.Expressions.Count - 1);
    232211      } else {
    233         expandExpression = PushProgram.Empty;
     212        result = PushProgram.Empty;
    234213      }
    235214
    236       interpreter.CodeStack.SetTop(expandExpression);
     215      interpreter.CodeStack.SetTop(result);
    237216      return true;
    238217    }
     
    252231      PushProgram result;
    253232
    254       if (interpreter.CodeStack.Top.CanExpand) {
     233      if (interpreter.CodeStack.Top.IsProgram) {
    255234        var first = (PushProgram)interpreter.CodeStack.Pop();
    256         var size = first.State.Length + 1;
     235        var size = first.Expressions.Count + 1;
    257236
    258237        if (size > interpreter.Configuration.MaxPointsInProgram) return false;
     
    260239        var expressions = new Expression[size];
    261240
    262         expressions[first.State.Length] = interpreter.CodeStack.Top;
    263         Array.Copy(first.State as Expression[], expressions, first.State.Length);
    264 
    265         result = new PushProgram(expressions);
     241        first.CopyExpressionsTo(expressions);
     242        expressions[first.Expressions.Count] = interpreter.CodeStack.Top;
     243
     244        result = PushProgram.Create(interpreter.PushProgramPool, expressions);
    266245      } else {
    267         result = new PushProgram(interpreter.CodeStack.Pop(), interpreter.CodeStack.Top);
     246        result = PushProgram.Create(interpreter.PushProgramPool, interpreter.CodeStack.Top);
    268247      }
    269248
     
    303282
    304283      var subContainer =
    305           current.State.Where(e => e.CanExpand)
     284          current.Expressions.Where(e => e.IsProgram)
    306285              .Select(e => GetContainer(e as PushProgram, target))
    307286              .Where(e => e != null);
     
    309288      var execExpandExpressions = subContainer as IList<PushProgram> ?? subContainer.ToList();
    310289      return execExpandExpressions.Any()
    311           ? execExpandExpressions.OrderBy(c => c.State.Length).LastOrDefault()
    312           : current.State.Contains(target)
     290          ? execExpandExpressions.OrderBy(c => c.Expressions.Count).LastOrDefault()
     291          : current.Expressions.Contains(target)
    313292              ? current
    314293              : null;
     
    324303    public override bool Eval(IPushInterpreter interpreter) {
    325304      if (interpreter.CodeStack.Count < 2 ||
    326          !interpreter.CodeStack[interpreter.CodeStack.Count - 2].CanExpand)
     305         !interpreter.CodeStack[interpreter.CodeStack.Count - 2].IsProgram)
    327306        return false;
    328307
    329308      var values = interpreter.CodeStack.Pop(2);
    330309      var second = (PushProgram)values[0];
    331       var contains = second.State.Contains(values[1]);
     310      var contains = second.Expressions.Contains(values[1]);
    332311
    333312      interpreter.BooleanStack.Push(contains);
     
    413392
    414393    private void DetermineUniqueItems(Expression source, IDictionary<int, int> items) {
    415       if (source.CanExpand) {
    416         var expand = source as PushProgram;
    417 
    418         foreach (var e in expand.State) {
    419           var id = e.GetHashCode();
     394      if (source.IsProgram) {
     395        var program = source as PushProgram;
     396        var expressions = program.Expressions;
     397
     398        for (var i = 0; i < expressions.Count; i++) {
     399          var id = expressions[i].GetHashCode();
    420400          if (!items.ContainsKey(id)) items.Add(id, 1);
    421401          else items[id]++;
     
    442422      if (interpreter.IntegerStack.Count == 0 ||
    443423          interpreter.CodeStack.Count == 0 ||
    444           !interpreter.CodeStack.Top.CanExpand)
     424          !interpreter.CodeStack.Top.IsProgram)
    445425        return false;
    446426
     
    532512      if (interpreter.IntegerStack.Count == 0 ||
    533513          interpreter.CodeStack.Count < 2 ||
    534           !interpreter.CodeStack.Top.CanExpand)
     514          !interpreter.CodeStack.Top.IsProgram)
    535515        return false;
    536516
     
    540520
    541521      Expression[] newExpressions;
    542       if (target.State.Length > 0) {
    543         index = target.State.Length - 1 - Math.Abs(index % target.State.Length);
     522      if (!target.IsEmpty) {
     523        index = target.Expressions.Count - 1 - Math.Abs(index % target.Expressions.Count);
    544524
    545525        newExpressions = target.CopyExpressions();
    546         newExpressions[index] = source.CanExpand
    547             ? ((PushProgram)source).Copy()
     526        newExpressions[index] = source.IsProgram
     527            ? ((PushProgram)source).Copy(interpreter.PushProgramPool)
    548528            : source;
    549529      } else {
     
    551531      }
    552532
    553       var result = new PushProgram(newExpressions);
     533      var result = PushProgram.Create(interpreter.PushProgramPool, newExpressions);
    554534      interpreter.CodeStack.SetTop(result);
    555535
     
    572552      var count = 1;
    573553
    574       if (expression.CanExpand)
    575         count = ((PushProgram)expression).State.Length;
     554      if (expression.IsProgram)
     555        count = ((PushProgram)expression).Expressions.Count;
    576556
    577557      interpreter.IntegerStack.Push(count);
     
    591571      var first = interpreter.CodeStack.Pop();
    592572      var second = interpreter.CodeStack.Top;
    593       var expandExpression = new PushProgram(second, first);
     573      var expandExpression = PushProgram.Create(interpreter.PushProgramPool, second, first);
    594574
    595575      interpreter.CodeStack.SetTop(expandExpression);
     
    610590      var expressions = interpreter.CodeStack.Pop(2);
    611591
    612       var contains = expressions[1].CanExpand
    613           ? ((PushProgram)expressions[1]).State.Contains(expressions[0])
     592      var contains = expressions[1].IsProgram
     593          ? ((PushProgram)expressions[1]).Expressions.Contains(expressions[0])
    614594          : expressions[1].Equals(expressions[0]);
    615595
     
    635615      Expression nthExpression;
    636616
    637       if (expression.CanExpand) {
     617      if (expression.IsProgram) {
    638618        var subExpression = (PushProgram)expression;
    639619
     
    641621          nthExpression = PushProgram.Empty;
    642622        } else {
    643           var index = (int)(subExpression.State.Length - 1 -
    644                              Math.Abs(n % subExpression.State.Length));
    645 
    646           nthExpression = subExpression.State[index];
     623          var index = (int)(subExpression.Expressions.Count - 1 - Math.Abs(n % subExpression.Expressions.Count));
     624
     625          nthExpression = subExpression.Expressions[index];
    647626        }
    648627      } else {
     
    674653      Expression nthExpression;
    675654
    676       if (expression.CanExpand) {
    677         var subExpressions = ((PushProgram)expression).State;
    678 
    679         if (subExpressions.Length < 2) {
     655      if (expression.IsProgram) {
     656        var subExpressions = ((PushProgram)expression).Expressions;
     657
     658        if (subExpressions.Count < 2) {
    680659          nthExpression = PushProgram.Empty;
    681660        } else {
    682           var index = (int)(subExpressions.Length - 2 - Math.Abs(n % (subExpressions.Length - 1)));
     661          var index = (int)(subExpressions.Count - 2 - Math.Abs(n % (subExpressions.Count - 1)));
    683662
    684663          nthExpression = subExpressions[index];
     
    723702
    724703      var position = -1;
    725       if (first.CanExpand) {
    726         var expand = (PushProgram)first;
    727         position = expand.State.Length - 1
    728                    - Array.FindIndex((Expression[])expand.State, e => e.Equals(second));
     704      if (first.IsProgram) {
     705        var program = (PushProgram)first;
     706        position = program.Expressions.Count - 1 - program.IndexOf(second);
    729707      } else if (first.Equals(second)) {
    730708        position = 0;
     
    747725
    748726      var expression = interpreter.CodeStack.Pop();
    749       var points = expression.CanExpand
    750           ? ((PushProgram)expression).State.Length
     727      var points = expression.IsProgram
     728          ? ((PushProgram)expression).Expressions.Count
    751729          : 1;
    752730
     
    773751      var second = expressions[0];
    774752      var first = expressions[1] as PushProgram;
    775       var newExpressions = new Expression[first.State.Length];
    776 
    777       for (var i = 0; i < first.State.Length; i++)
    778         newExpressions[i] = first.State[i].Equals(third)
     753      var firstExpressions = first.Expressions;
     754      var newExpressions = new Expression[firstExpressions.Count];
     755
     756      for (var i = 0; i < firstExpressions.Count; i++)
     757        newExpressions[i] = firstExpressions[i].Equals(third)
    779758            ? second
    780759            /* no cloning needed here because first is removed and therefore newExpression is the only container of sub expressions */
    781             : first.State[i];
    782 
    783       var result = new PushProgram(newExpressions);
     760            : firstExpressions[i];
     761
     762      var result = PushProgram.Create(interpreter.PushProgramPool, newExpressions);
    784763
    785764      interpreter.CodeStack.SetTop(result);
  • branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/ExecExpressions.cs

    r14745 r14746  
    4141      var top = interpreter.ExecStack.Top;
    4242      var execYExpression = ExpressionTable.GetStatelessExpression<ExecYExpression>();
    43 
    44       var result = new PushProgram(top, execYExpression);
     43      var result = PushProgram.Create(interpreter.PushProgramPool, top, execYExpression);
    4544
    4645      interpreter.ExecStack.SetTop(result);
     
    8180      var c = interpreter.ExecStack.Top;
    8281
    83       var newTop = new PushProgram(c, b);
     82      var newTop = PushProgram.Create(interpreter.PushProgramPool, c, b);
    8483
    8584      interpreter.ExecStack.SetTop(newTop);
  • branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/Expression.cs

    r14745 r14746  
    77  using Interpreter;
    88
     9  [Serializable]
    910  public abstract class Expression {
    10     public bool CanExpand { get { return this.GetType() == typeof(PushProgram); } }
     11    public bool IsProgram { get { return this.GetType() == typeof(PushProgram); } }
    1112
    1213    public static readonly IReadOnlyCollection<Expression> EmptyContainer = new Expression[0];
  • branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/ExpressionTable.cs

    r14745 r14746  
    55
    66  using HeuristicLab.Problems.ProgramSynthesis.Push.Attributes;
     7  using HeuristicLab.Problems.ProgramSynthesis.Push.Data.Pool;
    78  using HeuristicLab.Problems.ProgramSynthesis.Push.Stack;
    89
     
    123124    }
    124125
    125     public static PushProgram GetProgram(int[] index) {
     126    public static PushProgram GetProgram(IManagedPool<PushProgram> pool, int[] index) {
    126127      var expressions = new Expression[index.Length];
    127128
     
    130131      }
    131132
    132       return new PushProgram(expressions);
     133      return PushProgram.Create(pool, expressions);
    133134    }
    134135
  • branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/PushProgram.bk.cs

    r14745 r14746  
    8888//    public IEnumerable<Expression> DepthFirst() {
    8989//      foreach (var expr in this.Expressions) {
    90 //        if (expr.CanExpand) {
     90//        if (expr.IsProgram) {
    9191//          var expandExpr = (PushProgram)expr;
    9292
     
    114114
    115115//    private int CalcDepth() {
    116 //      //var subExpressions = Expressions.Where(e => e.CanExpand);
     116//      //var subExpressions = Expressions.Where(e => e.IsProgram);
    117117//      //var depth = subExpressions.Any()
    118118//      //    ? subExpressions.Select(e => e as PushProgram).Max(e => e.State.Depth) + 1
     
    124124//      for (var i = 0; i < Expressions.Count; i++) {
    125125//        var expression = Expressions[i];
    126 //        if (!expression.CanExpand) continue;
     126//        if (!expression.IsProgram) continue;
    127127//        var expandExpression = (PushProgram)expression;
    128128
     
    151151//        local_treeIndex[i] = next;
    152152
    153 //        if (subExpression.CanExpand) {
     153//        if (subExpression.IsProgram) {
    154154//          next += ((PushProgram)subExpression).State.TotalCount;
    155155//        } else {
     
    184184
    185185//      for (var i = 0; i < current.State.Expressions.Count; i++) {
    186 //        if (current.State.Expressions[i].CanExpand)
     186//        if (current.State.Expressions[i].IsProgram)
    187187//          continue;
    188188
  • branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/PushProgram.cs

    r14745 r14746  
    66  using System.Diagnostics;
    77
     8  using HeuristicLab.Problems.ProgramSynthesis.Push.Data.Pool;
     9
    810  using Interpreter;
    911
    10   public class PushProgram : StatefulExpression<Expression[]> {
     12  [Serializable]
     13  public sealed class PushProgram : Expression {
     14    private static readonly Expression[] EmptyExpressions = new Expression[0];
    1115    public static readonly PushProgram Empty = new PushProgram();
    1216
     
    1721    private const string Delimiter = " ";
    1822
    19     public readonly bool IsEmpty;
    20 
    21     public PushProgram(params Expression[] state) : base(state) {
    22       IsEmpty = state.Length == 0;
    23     }
    24 
    25     public PushProgram(IEnumerable<Expression> state) : this(state.ToArray()) {
    26       // TODO: lazy evaluation of ToArray()
     23    private Expression[] expressions;
     24
     25    public PushProgram() : this(EmptyExpressions) {
     26    }
     27
     28    public PushProgram(Expression[] expressions) {
     29      this.expressions = expressions;
     30    }
     31
     32    public bool IsEmpty { get { return Count == 0; } }
     33    public int Count { get { return expressions.Length; } }
     34
     35    public IReadOnlyList<Expression> Expressions { get { return this.expressions; } }
     36
     37    public static PushProgram Create(IManagedPool<PushProgram> pool, params Expression[] expressions) {
     38      var program = pool.Get();
     39
     40      program.expressions = expressions;
     41      program.Reset();
     42
     43      return program;
     44    }
     45
     46    private void Reset() {
     47      stringRepresentation = null;
     48      depth = null;
     49      treeIndex = null;
     50      hashCode = null;
     51    }
     52
     53    public static PushProgram Merge(IManagedPool<PushProgram> pool, PushProgram first, Expression second) {
     54      var program = pool.Get();
     55
     56      program.Reset();
     57      program.expressions = new Expression[first.Expressions.Count + 1];
     58      first.CopyExpressionsTo(program.expressions);
     59      program.expressions[0] = first;
     60
     61      return program;
     62    }
     63
     64    public static PushProgram Merge(IManagedPool<PushProgram> pool, Expression first, PushProgram second) {
     65      var program = pool.Get();
     66
     67      program.Reset();
     68
     69      program.expressions = new Expression[second.Expressions.Count + 1];
     70      program.expressions[0] = first;
     71      second.CopyExpressionsTo(program.expressions, 0, 1, second.Count);
     72
     73      return program;
     74    }
     75
     76    public static PushProgram Merge(IManagedPool<PushProgram> pool, PushProgram first, PushProgram second) {
     77      var program = pool.Get();
     78
     79      program.Reset();
     80      program.expressions = new Expression[first.Count + second.Count];
     81
     82      first.CopyExpressionsTo(program.expressions);
     83      second.CopyExpressionsTo(program.expressions, 0, first.Count, second.Count);
     84
     85      return program;
     86    }
     87
     88    public int IndexOf(Expression expression) {
     89      return Array.IndexOf(this.expressions, expression);
    2790    }
    2891
     
    3295      get
    3396      {
    34         if (string.IsNullOrEmpty(stringRepresentation))
    35           stringRepresentation = BuildString();
     97        if (stringRepresentation == null) stringRepresentation = BuildString();
    3698        return stringRepresentation;
    3799      }
    38100    }
    39101
    40     private int depth = -1;
     102
     103    private int? depth;
    41104    public int Depth
    42105    {
    43106      get
    44107      {
    45         if (depth == -1) depth = CalcDepth();
    46         return depth;
     108        if (depth == null) depth = CalcDepth();
     109        return depth.Value;
    47110      }
    48111    }
     
    53116      get
    54117      {
    55         return treeIndex ?? (treeIndex = BuildTreeIndex());
    56       }
    57     }
    58 
    59     private int hashCode;
    60     private int HashCode
    61     {
    62       get
    63       {
    64         if (hashCode == default(int)) hashCode = HashExpressions();
    65         return hashCode;
    66       }
     118        if (treeIndex == null) treeIndex = BuildTreeIndex();
     119        return treeIndex;
     120      }
     121    }
     122
     123    private int? hashCode;
     124    public override int GetHashCode() {
     125      if (hashCode == null) hashCode = HashExpressions();
     126      return hashCode.Value;
    67127    }
    68128
    69129    //public PushProgram Copy() {
    70130    //  // as the empty list is a static stateless expression, no copy required
    71     //  return ReferenceEquals(this, Empty) || this.State.IsEmpty
     131    //  return ReferenceEquals(this, Empty) || this.expressions.IsEmpty
    72132    //    ? Empty
    73     //    : new PushProgram(this.State.Copy());
     133    //    : new PushProgram(this.expressions.Copy());
    74134    //}
    75135
    76136    public override bool Eval(IPushInterpreter interpreter) {
    77       interpreter.ExecStack.Push(this.State);
     137      interpreter.ExecStack.Push(this.expressions);
    78138      return true;
    79139    }
    80140
    81     public override int GetHashCode() {
    82       return HashCode;
    83     }
    84 
    85141    public override string ToString() {
    86       return this.StringRepresentation;
     142      return StringRepresentation;
    87143    }
    88144
     
    103159
    104160    public IEnumerable<Expression> DepthFirst() {
    105       foreach (var expr in this.State) {
    106         if (expr.CanExpand) {
     161      foreach (var expr in this.expressions) {
     162        if (expr.IsProgram) {
    107163          var expandExpr = (PushProgram)expr;
    108164
     
    114170
    115171    public PushProgram Copy() {
    116       return IsEmpty ? this : new PushProgram(State) {
     172      if (IsEmpty) return this;
     173
     174      var program = new PushProgram(this.expressions) {
    117175        stringRepresentation = this.stringRepresentation,
    118176        hashCode = this.hashCode,
     
    120178        treeIndex = this.treeIndex
    121179      };
    122     }
    123 
    124     public Expression[] CopyExpressions()
    125     {
    126       if (IsEmpty) return Empty.State;
    127 
    128       var copy = new Expression[State.Length];
    129       State.CopyTo(copy, 0);
     180
     181      return program;
     182    }
     183
     184    public PushProgram Copy(IManagedPool<PushProgram> pool) {
     185      if (IsEmpty) return this;
     186
     187      var program = pool.Get();
     188      program.expressions = this.expressions;
     189      program.stringRepresentation = stringRepresentation;
     190      program.hashCode = hashCode;
     191      program.depth = depth;
     192      program.treeIndex = treeIndex;
     193
     194      return program;
     195    }
     196
     197    public PushProgram Copy(IManagedPool<PushProgram> pool, int startIndex, int length) {
     198      if (IsEmpty) return this;
     199
     200      var program = pool.Get();
     201      program.expressions = CopyExpressions(startIndex, length);
     202
     203      program.Reset();
     204
     205      return program;
     206    }
     207
     208    public Expression[] CopyExpressions() {
     209      return CopyExpressions(Count);
     210    }
     211
     212    public Expression[] CopyExpressions(int length) {
     213      if (IsEmpty) return EmptyExpressions;
     214
     215      var copy = new Expression[length];
     216      this.expressions.CopyTo(copy, 0);
    130217
    131218      return copy;
     219    }
     220
     221    public Expression[] CopyExpressions(int startIndex, int length) {
     222      if (IsEmpty) return EmptyExpressions;
     223
     224      var copy = new Expression[length];
     225      CopyExpressionsTo(copy, startIndex, 0, length);
     226
     227      return copy;
     228    }
     229
     230    public void CopyExpressionsTo(Expression[] destination, int? sourceIndex = null, int? destinationIndex = null, int? length = null) {
     231      if (IsEmpty) return;
     232
     233      Array.Copy(this.expressions, sourceIndex ?? 0, destination, destinationIndex ?? 0, length ?? Count);
    132234    }
    133235
    134236    private int CalcDepth() {
    135237      var maxDepth = 1;
    136       for (var i = 0; i < State.Length; i++) {
    137         var expression = State[i];
    138         if (!expression.CanExpand) continue;
     238      for (var i = 0; i < Count; i++) {
     239        var expression = this.expressions[i];
     240        if (!expression.IsProgram) continue;
    139241        var expandExpression = (PushProgram)expression;
    140242
     
    149251      // prevent too big string
    150252      return this.TotalCount > 50
    151         ? PrefixReduced + this.State.Length + PostfixReduced
    152         : Prefix + string.Join(Delimiter, this.State.Where(e => !string.IsNullOrWhiteSpace(e.StringRepresentation))) + Postfix;
     253        ? PrefixReduced + this.Count + PostfixReduced
     254        : Prefix + string.Join(Delimiter, this.expressions.Where(e => !string.IsNullOrWhiteSpace(e.StringRepresentation))) + Postfix;
    153255    }
    154256
    155257    private int[] BuildTreeIndex() {
    156       var local_treeIndex = new int[State.Length];
     258      var local_treeIndex = new int[Count];
    157259
    158260      var next = 1;
    159261
    160       for (var i = State.Length - 1; i >= 0; i--) {
    161         var subExpression = State[i];
     262      for (var i = Count - 1; i >= 0; i--) {
     263        var subExpression = this.expressions[i];
    162264
    163265        local_treeIndex[i] = next;
    164266
    165         if (subExpression.CanExpand) {
     267        if (subExpression.IsProgram) {
    166268          next += ((PushProgram)subExpression).TotalCount;
    167269        } else {
     
    176278      var hash = 19 * 31 + this.GetType().FullName.GetHashCode();
    177279
    178       for (var i = 0; i < State.Length; i++) {
    179         hash = hash * 31 + State[i].GetHashCode();
     280      for (var i = 0; i < Count; i++) {
     281        hash = hash * 31 + this.expressions[i].GetHashCode();
    180282      }
    181283
     
    195297      }
    196298
    197       for (var i = 0; i < current.State.Length; i++) {
    198         if (current.State[i].CanExpand)
     299      for (var i = 0; i < current.Count; i++) {
     300        if (current.expressions[i].IsProgram)
    199301          continue;
    200302
    201         var subExpression = current.State[i] as PushProgram;
     303        var subExpression = current.expressions[i] as PushProgram;
    202304
    203305        if (ReferenceEquals(target, subExpression)) {
     
    231333      if (index == 0) return resolver(parent, parent, this, 0, parentIndex);
    232334
    233       var min = State.Length - 1;
     335      var min = Count - 1;
    234336      var max = 0;
    235337      var mid = (min + max) / 2;
     
    243345
    244346      return TreeIndex[mid] == index
    245           ? resolver(parent, this, State[mid], mid, parentIndex)
    246           : (State[mid + 1] as PushProgram).GetFromTree(index - TreeIndex[mid + 1], mid + 1,
     347          ? resolver(parent, this, this.expressions[mid], mid, parentIndex)
     348          : (this.expressions[mid + 1] as PushProgram).GetFromTree(index - TreeIndex[mid + 1], mid + 1,
    247349              this, resolver);
    248350    }
  • branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/RandExpressions.cs

    r14744 r14746  
    6969
    7070      var size = (int)(interpreter.IntegerStack.Pop() % interpreter.Configuration.MaxPointsInRandomExpression);
    71       var program = CodeGenerator.RandomExpandExpression(
     71      var program = CodeGenerator.RandomProgram(
     72        interpreter.PushProgramPool,
    7273        size,
    7374        interpreter.Random,
  • branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/StatefulExpression.cs

    r14745 r14746  
    22  public abstract class StatefulExpression<T> : Expression {
    33    public readonly T State;
    4 
    5     private int hashCode;
    6     private int HashCode
    7     {
    8       get
    9       {
    10         if (hashCode == default(int)) hashCode = CalcHashCode();
    11         return hashCode;
    12       }
    13     }
     4    private int? hashCode;
    145
    156    protected StatefulExpression(T state) {
     
    3425    }
    3526
     27    public bool Equals(StatefulExpression<T> obj) {
     28      if (ReferenceEquals(this, obj))
     29        return true;
     30
     31      if (GetType() != obj.GetType())
     32        return false;
     33
     34      return ReferenceEquals(State, obj.State) ||
     35             GetHashCode() == obj.GetHashCode();
     36    }
     37
    3638    public override int GetHashCode() {
    37       return HashCode;
     39      if (hashCode == null) hashCode = CalcHashCode();
     40      return hashCode.Value;
    3841    }
    3942  }
  • branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Generators/CodeGenerator.cs

    r14745 r14746  
    55  using HeuristicLab.Core;
    66  using HeuristicLab.Problems.ProgramSynthesis.Push.Configuration;
     7  using HeuristicLab.Problems.ProgramSynthesis.Push.Data.Pool;
    78  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
    89  using HeuristicLab.Random;
     
    1819  public static class CodeGenerator {
    1920
    20     public static PushProgram RandomProgram(int maxPoints, IRandom random = null, IReadonlyPushConfiguration pushGpConfiguration = null, IDictionary<string, Expression> customExpressions = null) {
     21    public static PushProgram RandomProgram(IManagedPool<PushProgram> pool, int maxPoints, IRandom random = null, IReadonlyPushConfiguration pushGpConfiguration = null, IDictionary<string, Expression> customExpressions = null) {
    2122      var code = RandomCode(maxPoints, random, pushGpConfiguration, customExpressions);
    2223
    23       return new PushProgram(code.ToArray());
    24     }
    25 
    26     public static PushProgram RandomExpandExpression(int maxPoints, IRandom random = null, IReadonlyPushConfiguration pushGpConfiguration = null, IDictionary<string, Expression> customExpressions = null) {
    27       var program = RandomProgram(maxPoints, random, pushGpConfiguration, customExpressions);
    28 
    29       return new PushProgram(program);
     24      return PushProgram.Create(pool, code.ToArray());
    3025    }
    3126
  • branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/IPushInterpreter.cs

    r14745 r14746  
    77
    88  using HeuristicLab.Problems.ProgramSynthesis.Push.Configuration;
     9  using HeuristicLab.Problems.ProgramSynthesis.Push.Data.Pool;
    910
    1011  using Stack;
     
    2324
    2425    IReadonlyPushConfiguration Configuration { get; }
     26
     27    IManagedPool<PushProgram> PushProgramPool { get; }
    2528
    2629    bool IsNameQuoteFlagSet { get; set; }
  • branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/PushInterpreter.cs

    r14745 r14746  
    22  using System;
    33  using System.Collections.Generic;
     4#if DEBUG
     5  using System.Linq;
     6#endif
    47  using System.Runtime.CompilerServices;
    58  using System.Threading;
     
    710  using HeuristicLab.Core;
    811  using HeuristicLab.Problems.ProgramSynthesis.Push.Configuration;
     12  using HeuristicLab.Problems.ProgramSynthesis.Push.Data.Pool;
    913  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
    1014  using HeuristicLab.Problems.ProgramSynthesis.Push.Parser;
     
    8286    }
    8387
     88    public IManagedPool<PushProgram> PushProgramPool { get; set; }
     89
    8490    public IReadonlyPushConfiguration Configuration { get; protected set; }
    8591
     
    249255    }
    250256
     257#if DEBUG
     258    private Expression last;
     259    private bool DoStep() {
     260      var expression = ExecStack.Pop();
     261
     262      if (ExecStack.Any(e => e == null)) {
     263        throw new InvalidProgramException();
     264      }
     265
     266      var succ = expression.Eval(this);
     267      last = expression;
     268
     269      return succ;
     270    }
     271#else
    251272    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    252273    private bool DoStep() {
    253274      return ExecStack.Pop().Eval(this);
    254275    }
     276#endif
    255277
    256278    private Task InterpretAsync() {
  • branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Problem/PushEncoding.cs

    r14744 r14746  
    4242
    4343    public static PushProgram MapToPushProgram(this IntegerVector vector, IReadOnlyList<string> enabledExpressions) {
    44       var expressions = vector
    45         .Select(i => ExpressionTable.GetExpression(enabledExpressions[i]))
    46         .ToArray();
     44      //var expressions = vector
     45      //  .Select(i => ExpressionTable.GetExpression(enabledExpressions[i]))
     46      //  .ToArray();
     47
     48      var expressions = new Expression[vector.Length];
     49      for (var i = 0; i < vector.Length; i++)
     50      {
     51        expressions[i] = ExpressionTable.GetExpression(enabledExpressions[vector[i]]);
     52      }
    4753
    4854      return new Expressions.PushProgram(expressions);
  • branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Problem/PushProblem.cs

    r14745 r14746  
    1212  using HeuristicLab.BenchmarkSuite;
    1313  using HeuristicLab.Data;
     14  using HeuristicLab.Problems.ProgramSynthesis.Push.Data.Pool;
     15
    1416  using Instances;
    1517  using Interpreter;
     
    2628    private readonly PushConfiguration config;
    2729    private PushInterpreterPool pool;
     30    private ManagedPoolProvider<PushProgram> pushProgramPoolProvider;
    2831
    2932    public PushProblem() {
    3033      config = new PushConfiguration();
    3134      pool = new PushInterpreterPool(config);
     35
     36      pushProgramPoolProvider = new ManagedPoolProvider<PushProgram>(1024);
     37      pushProgramPoolProvider.InitDummyPartition(() => new PushProgram());
    3238
    3339      InitEvents();
     
    5662      pool = new PushInterpreterPool(config);
    5763      Instructions = config;
     64
     65      pushProgramPoolProvider = new ManagedPoolProvider<PushProgram>(1024);
     66      pushProgramPoolProvider.InitDummyPartition(() => new PushProgram());
    5867
    5968      InitEvents();
     
    404413
    405414    public override double Evaluate(Individual individual, IRandom random) {
     415      if (DataBounds[0, 1] <= 0) return default(double);
    406416
    407417      var program = individual.PushProgram(config.EnabledExpressions as IReadOnlyList<string>);
    408       var expandExpression = new PushProgram(program);
    409       var results = new List<double>();
     418      var result = 0d;
    410419
    411420      using (var interpreter = pool.GetInstance(random)) {
    412421        for (var i = DataBounds[0, 0]; i < DataBounds[0, 1]; i++) {
    413           var example = this.DataDescriptor.Examples[i];
     422          var example = DataDescriptor.Examples[i];
    414423
    415424          interpreter.BooleanStack.Push(example.InputBoolean);
     
    417426          interpreter.FloatStack.Push(example.InputFloat);
    418427
    419           interpreter.Run(expandExpression);
    420 
    421           var diff = GetDiff(example.OutputInt, interpreter.IntegerStack, this.DataDescriptor.WorstResult, LongDiffer) +
    422                      GetDiff(example.OutputFloat, interpreter.FloatStack, this.DataDescriptor.WorstResult, DoubleDiffer) +
    423                      GetDiff(example.OutputBoolean, interpreter.BooleanStack, this.DataDescriptor.WorstResult, BooleanDiffer);
    424 
    425           results.Add(diff);
     428          using (interpreter.PushProgramPool = pushProgramPoolProvider.CreatePool()) {
     429            interpreter.Run(program);
     430          }
     431
     432          result += GetDiff(example.OutputInt, interpreter.IntegerStack, DataDescriptor.WorstResult, LongDiffer)
     433                  + GetDiff(example.OutputFloat, interpreter.FloatStack, DataDescriptor.WorstResult, DoubleDiffer)
     434                  + GetDiff(example.OutputBoolean, interpreter.BooleanStack, DataDescriptor.WorstResult, BooleanDiffer);
     435
    426436          interpreter.Clear();
    427437        }
    428438      }
    429439
    430       return results.Count == 0 ? 0d : results.Average();
     440      return result / DataBounds[0, 1];
    431441    }
    432442
  • branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Simplifier/RandomSimplifier.cs

    r14745 r14746  
    1 namespace HeuristicLab.Problems.ProgramSynthesis.Push.Simplifier {
    2   using System;
    3   using HeuristicLab.Core;
    4   using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
     1//namespace HeuristicLab.Problems.ProgramSynthesis.Push.Simplifier {
     2//  using System;
     3//  using HeuristicLab.Core;
     4//  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
    55
    6   public class RandomSimplifier : ISimplifier {
    7     public int Trys { get; set; }
     6//  public class RandomSimplifier : ISimplifier {
     7//    public int Trys { get; set; }
    88
    9     public PushProgram Simplify(PushProgram program, IRandom random, Predicate<PushProgram> isBetter) {
     9//    public PushProgram Simplify(PushProgram program, IRandom random, Predicate<PushProgram> isBetter) {
    1010
    11       if (program.TotalCount == 1) {
    12         return isBetter(PushProgram.Empty) ? PushProgram.Empty : program;
    13       }
     11//      if (program.TotalCount == 1) {
     12//        return isBetter(PushProgram.Empty) ? PushProgram.Empty : program;
     13//      }
    1414
    15       var copy = program.Copy();
    16       var maxTries = Math.Min(Trys, program.TotalCount - 2);
    17       var successfulRemoves = 0;
     15//      var copy = program.Copy();
     16//      var maxTries = Math.Min(Trys, program.TotalCount - 2);
     17//      var successfulRemoves = 0;
    1818
    19       for (var i = 0; i < maxTries; i++) {
    20         var rndIndex = random.Next(1, program.TotalCount - 1 - successfulRemoves);
    21         var node = copy.GetFromTree(
    22           rndIndex,
    23           (super, parent, child, childIndex, parentIndex) => new {
    24             Super = super,
    25             Parent = parent,
    26             ChildIndex = childIndex,
    27             ParentIndex = parentIndex
    28           });
     19//      for (var i = 0; i < maxTries; i++) {
     20//        var rndIndex = random.Next(1, program.TotalCount - 1 - successfulRemoves);
     21//        var node = copy.GetFromTree(
     22//          rndIndex,
     23//          (super, parent, child, childIndex, parentIndex) => new {
     24//            Super = super,
     25//            Parent = parent,
     26//            ChildIndex = childIndex,
     27//            ParentIndex = parentIndex
     28//          });
    2929
    30         var oldParentExpressions = node.Parent.State;
    31         var newParentExpressions = RemoveAt(oldParentExpressions, node.ChildIndex);
    32         var newParent = new PushProgram(newParentExpressions);
     30//        var oldParentExpressions = node.Parent.State;
     31//        var newParentExpressions = RemoveAt(oldParentExpressions, node.ChildIndex);
     32//        var newParent = new PushProgram(newParentExpressions);
    3333
    34         var superExpressions = node.Super == null ? copy.State : node.Super.State;
    35         superExpressions[node.ParentIndex] = newParent;
     34//        var superExpressions = node.Super == null ? copy.State : node.Super.State;
     35//        superExpressions[node.ParentIndex] = newParent;
    3636
    37         if (isBetter(copy)) {
    38           successfulRemoves++;
    39         } else {
    40           superExpressions[node.ParentIndex] = node.Parent;
    41         }
    42       }
     37//        if (isBetter(copy)) {
     38//          successfulRemoves++;
     39//        } else {
     40//          superExpressions[node.ParentIndex] = node.Parent;
     41//        }
     42//      }
    4343
    44       return copy;
    45     }
     44//      return copy;
     45//    }
    4646
    47     private static T[] RemoveAt<T>(T[] source, int index) {
    48       var dest = new T[source.Length - 1];
    49       if (index > 0)
    50         Array.Copy(source, 0, dest, 0, index);
     47//    private static T[] RemoveAt<T>(T[] source, int index) {
     48//      var dest = new T[source.Length - 1];
     49//      if (index > 0)
     50//        Array.Copy(source, 0, dest, 0, index);
    5151
    52       if (index < source.Length - 1)
    53         Array.Copy(source, index + 1, dest, index, source.Length - index - 1);
     52//      if (index < source.Length - 1)
     53//        Array.Copy(source, index + 1, dest, index, source.Length - index - 1);
    5454
    55       return dest;
    56     }
    57   }
    58 }
     55//      return dest;
     56//    }
     57//  }
     58//}
Note: See TracChangeset for help on using the changeset viewer.