Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/ArchitectureAlteringOperators/SubroutineDeleter.cs @ 3294

Last change on this file since 3294 was 3294, checked in by gkronber, 14 years ago

Added first version of architecture altering operators for ADFs. #290 (Implement ADFs)

File size: 5.3 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Linq;
24using HeuristicLab.Core;
25using HeuristicLab.Data;
26using HeuristicLab.Operators;
27using HeuristicLab.Optimization;
28using HeuristicLab.Parameters;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.GeneralSymbols;
31using System.Collections.Generic;
32using System.Text;
33using System.Diagnostics;
34
35namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.ArchitectureAlteringOperators {
36  /// <summary>
37  /// Manipulates a symbolic expression by deleting a preexisting function-defining branch.
38  /// As described in Koza, Bennett, Andre, Keane, Genetic Programming III - Darwinian Invention and Problem Solving, 1999, pp. 108
39  /// </summary>
40  [Item("SubroutineDeleter", "Manipulates a symbolic expression by deleting a preexisting function-defining branch.")]
41  [StorableClass]
42  public sealed class SubroutineDeleter : SymbolicExpressionTreeArchitectureAlteringOperator {
43    private const int MAX_TRIES = 100;
44    public override sealed void ModifyArchitecture(
45      IRandom random,
46      SymbolicExpressionTree symbolicExpressionTree,
47      ISymbolicExpressionGrammar grammar,
48      IntValue maxTreeSize, IntValue maxTreeHeight,
49      IntValue maxFunctionDefiningBranches, IntValue maxFunctionArguments,
50      out bool success) {
51      success = DeleteSubroutine(random, symbolicExpressionTree, grammar, maxTreeSize.Value, maxTreeHeight.Value, maxFunctionDefiningBranches.Value, maxFunctionArguments.Value);
52    }
53
54    public static bool DeleteSubroutine(
55      IRandom random,
56      SymbolicExpressionTree symbolicExpressionTree,
57      ISymbolicExpressionGrammar grammar,
58      int maxTreeSize, int maxTreeHeight,
59      int maxFunctionDefiningBranches, int maxFunctionArguments) {
60      var functionDefiningBranches = symbolicExpressionTree.IterateNodesPrefix().OfType<DefunTreeNode>();
61
62      if (functionDefiningBranches.Count() == 0)
63        // no ADF to delete => abort
64        return false;
65      var selectedDefunBranch = (DefunTreeNode)SelectRandomBranch(random, functionDefiningBranches);
66      // remove the selected defun
67      int defunSubtreeIndex = symbolicExpressionTree.Root.SubTrees.IndexOf(selectedDefunBranch);
68      symbolicExpressionTree.Root.RemoveSubTree(defunSubtreeIndex);
69
70      // get all cut points that contain an invokation of the deleted defun
71      var invocationCutPoints = from node in symbolicExpressionTree.IterateNodesPrefix()
72                                where node.SubTrees.Count > 0
73                                from argIndex in Enumerable.Range(0, node.SubTrees.Count)
74                                let subtree = node.SubTrees[argIndex] as InvokeFunctionTreeNode
75                                where subtree != null
76                                where subtree.InvokedFunctionName == selectedDefunBranch.Name
77                                select new { Parent = node, ReplacedChildIndex = argIndex, ReplacedChild = subtree };
78      // deletion by random regeneration
79      foreach (var cutPoint in invocationCutPoints) {
80        SymbolicExpressionTreeNode replacementTree = null;
81        int targetSize = random.Next(cutPoint.ReplacedChild.GetSize());
82        int targetHeight = cutPoint.ReplacedChild.GetHeight();
83        int tries = 0;
84        do {
85          try {
86            replacementTree = ProbabilisticTreeCreator.PTC2(random, grammar, cutPoint.Parent.Symbol, targetSize, targetHeight);
87          }
88          catch (ArgumentException) {
89            // try different size
90            targetSize = random.Next(cutPoint.ReplacedChild.GetSize());
91            if (tries++ > MAX_TRIES) throw;
92          }
93        } while (replacementTree == null);
94        cutPoint.Parent.RemoveSubTree(cutPoint.ReplacedChildIndex);
95        cutPoint.Parent.InsertSubTree(cutPoint.ReplacedChildIndex, replacementTree);
96      }
97      // remove references to deleted function
98      foreach (var subtree in symbolicExpressionTree.Root.SubTrees) {
99        if (subtree.DynamicSymbols.Contains(selectedDefunBranch.Name)) {
100          subtree.RemoveDynamicSymbol(selectedDefunBranch.Name);
101        }
102      }
103      Debug.Assert(grammar.IsValidExpression(symbolicExpressionTree));
104      return true;
105    }
106
107    private static SymbolicExpressionTreeNode SelectRandomBranch(IRandom random, IEnumerable<DefunTreeNode> branches) {
108      var list = branches.ToList();
109      return list[random.Next(list.Count)];
110    }
111  }
112}
Note: See TracBrowser for help on using the repository browser.