Changeset 14746 for branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/PushProgram.cs
- Timestamp:
- 03/11/17 20:07:13 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/PushProgram.cs
r14745 r14746 6 6 using System.Diagnostics; 7 7 8 using HeuristicLab.Problems.ProgramSynthesis.Push.Data.Pool; 9 8 10 using Interpreter; 9 11 10 public class PushProgram : StatefulExpression<Expression[]> { 12 [Serializable] 13 public sealed class PushProgram : Expression { 14 private static readonly Expression[] EmptyExpressions = new Expression[0]; 11 15 public static readonly PushProgram Empty = new PushProgram(); 12 16 … … 17 21 private const string Delimiter = " "; 18 22 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); 27 90 } 28 91 … … 32 95 get 33 96 { 34 if (string.IsNullOrEmpty(stringRepresentation)) 35 stringRepresentation = BuildString(); 97 if (stringRepresentation == null) stringRepresentation = BuildString(); 36 98 return stringRepresentation; 37 99 } 38 100 } 39 101 40 private int depth = -1; 102 103 private int? depth; 41 104 public int Depth 42 105 { 43 106 get 44 107 { 45 if (depth == -1) depth = CalcDepth();46 return depth ;108 if (depth == null) depth = CalcDepth(); 109 return depth.Value; 47 110 } 48 111 } … … 53 116 get 54 117 { 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; 67 127 } 68 128 69 129 //public PushProgram Copy() { 70 130 // // as the empty list is a static stateless expression, no copy required 71 // return ReferenceEquals(this, Empty) || this. State.IsEmpty131 // return ReferenceEquals(this, Empty) || this.expressions.IsEmpty 72 132 // ? Empty 73 // : new PushProgram(this. State.Copy());133 // : new PushProgram(this.expressions.Copy()); 74 134 //} 75 135 76 136 public override bool Eval(IPushInterpreter interpreter) { 77 interpreter.ExecStack.Push(this. State);137 interpreter.ExecStack.Push(this.expressions); 78 138 return true; 79 139 } 80 140 81 public override int GetHashCode() {82 return HashCode;83 }84 85 141 public override string ToString() { 86 return this.StringRepresentation;142 return StringRepresentation; 87 143 } 88 144 … … 103 159 104 160 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) { 107 163 var expandExpr = (PushProgram)expr; 108 164 … … 114 170 115 171 public PushProgram Copy() { 116 return IsEmpty ? this : new PushProgram(State) { 172 if (IsEmpty) return this; 173 174 var program = new PushProgram(this.expressions) { 117 175 stringRepresentation = this.stringRepresentation, 118 176 hashCode = this.hashCode, … … 120 178 treeIndex = this.treeIndex 121 179 }; 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); 130 217 131 218 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); 132 234 } 133 235 134 236 private int CalcDepth() { 135 237 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; 139 241 var expandExpression = (PushProgram)expression; 140 242 … … 149 251 // prevent too big string 150 252 return this.TotalCount > 50 151 ? PrefixReduced + this. State.Length+ PostfixReduced152 : 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; 153 255 } 154 256 155 257 private int[] BuildTreeIndex() { 156 var local_treeIndex = new int[ State.Length];258 var local_treeIndex = new int[Count]; 157 259 158 260 var next = 1; 159 261 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]; 162 264 163 265 local_treeIndex[i] = next; 164 266 165 if (subExpression. CanExpand) {267 if (subExpression.IsProgram) { 166 268 next += ((PushProgram)subExpression).TotalCount; 167 269 } else { … … 176 278 var hash = 19 * 31 + this.GetType().FullName.GetHashCode(); 177 279 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(); 180 282 } 181 283 … … 195 297 } 196 298 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) 199 301 continue; 200 302 201 var subExpression = current. State[i] as PushProgram;303 var subExpression = current.expressions[i] as PushProgram; 202 304 203 305 if (ReferenceEquals(target, subExpression)) { … … 231 333 if (index == 0) return resolver(parent, parent, this, 0, parentIndex); 232 334 233 var min = State.Length- 1;335 var min = Count - 1; 234 336 var max = 0; 235 337 var mid = (min + max) / 2; … … 243 345 244 346 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, 247 349 this, resolver); 248 350 }
Note: See TracChangeset
for help on using the changeset viewer.