Open HeuristicLab-Trac-Bot opened 5 years ago
Please attach a minimal sample (multi-encoding with two symbolic expression tree encodings and vastly different grammars) that reproduces the issue for debugging purposes.
Genetic Algorithm (GA) - Syntax Expression Tree MultiEncoding sample.hl
(153.7 KiB)Syntax expression tree multi-encoding sample
Unfortunately the provided example cannot be loaded with a standard version of HL, because it uses a proprietary plugin HeuristicLab.Problems.Matlab.ModelLearning or HeuristicLab.Problems.Matlab.ModelLearning.Optimization and maybe even others.
Genetic Algorithm (GA) - Syntax Expression Tree MultiEncoding sample - update.hl
(104.7 KiB)Syntax expression tree multi-encoding sample
Here is another small example where I have just spotted the same bug. Trees for t2 also contain terminals x,y,z instead of a,b,c.
#!csharp namespace HeuristicLab.Problems.Programmable { public class CompiledSingleObjectiveProblemDefinition : CompiledProblemDefinition, ISingleObjectiveProblemDefinition { public bool Maximization { get { return false; } } public override void Initialize() { var g1 = new SimpleSymbolicExpressionGrammar(); var g2 = new SimpleSymbolicExpressionGrammar(); g1.AddSymbols(new string[] {"max", "add"}, 2, 2); g1.AddTerminalSymbols(new string[] {"x", "y", "z"}); g2.AddSymbols(new string[] {"max", "add"}, 2, 2); g2.AddTerminalSymbols(new string[] {"a", "b", "c"}); Encoding = new MultiEncoding() .Add(new SymbolicExpressionTreeEncoding("t1", g1, 50, 12)) .Add(new SymbolicExpressionTreeEncoding("t2", g2, 50, 12)) ; } public double Evaluate(Individual individual, IRandom random) { var trees # individual.Values.Select(v> v.Value).OfType<ISymbolicExpressionTree>().ToArray(); var numAs = 0; var numXs = 0; foreach(var n in trees[0].Root.IterateNodesPrefix()) { if(n.Symbol.Name == "x") numXs++; else if(n.Symbol.Name == "a") numAs++; } foreach(var n in trees[1].Root.IterateNodesPrefix()) { if(n.Symbol.Name == "x") numXs++; else if(n.Symbol.Name == "a") numAs++; } return numAs + numXs; } public void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, IRandom random) { } public IEnumerable<Individual> GetNeighbors(Individual individual, IRandom random) { return Enumerable.Empty<Individual>(); } } }
I have investigated this issue as it is a blocker for the correct development of #3136.
The reason for this faulty behavior is that during the first execution of any tree creator the used grammar is cloned and put in the global scope. From now on only this cloned grammar is used for tree creation. In the case of a multi-encoding the cloning is performed only once and the tree creators for the other encoding parts detect the cloned grammar and wrongly use the cloned grammar, which could be vastly different from the configured one.
The reason for this strange behavior is AFAIK to avoid grammar manipulations when the algorithm is paused. Currently the grammar is set to readonly before it is cloned, thus preventing any manipulation. The readonly flag is afterwards removed in the ClearState method of the grammar, which is an IStatefulItem.
IMHO the best solution is to remove this awkward and unusual cloning of grammars all together and work directly with the configured grammar object. Hence, we could also remove the IStatefulItem interface from grammars, which further simplifies the tree creation.
Additionally, the current behavior that tree creators use a cloned grammar is not consistent, because all other operators that require a grammar use the normal grammar or the one within the tree.
The only thing that does not work after the proposed changed is that grammar manipulations during algorithm execution (while it is in a paused state) is possible. However, this is a larger issue which affects all parameters of an algorithm / problem and should be tackled more generally. E.g. the GA's population size / manipulation rate / ... can all be modified during algorithm execution.
r18064: Simplified tree creator interface and removed cloning of grammars,
Issue migrated from trac ticket # 2997
milestone: HeuristicLab 3.3.17 | component: Encodings.SymbolicExpressionTreeEncoding | priority: medium
2019-03-19 12:30:54: rhanghof created the issue