#region License Information
/* HeuristicLab
* Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*/
#endregion
using System;
using System.Linq;
using HeuristicLab.Common;
using HeuristicLab.Core;
using HeuristicLab.Data;
using HeuristicLab.Operators;
using HeuristicLab.Parameters;
using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
namespace HeuristicLab.Encodings.ConditionActionEncoding {
[Item("CoveringOperator", "")]
[StorableClass]
public class CoveringOperator : SingleSuccessorOperator, ICovering {
#region Parameter Properties
public ILookupParameter> ActionsInMatchSetParameter {
get { return (ILookupParameter>)Parameters["ActionsInMatchSet"]; }
}
public ILookupParameter> PossibleActionsParameter {
get { return (ILookupParameter>)Parameters["PossibleActions"]; }
}
public ILookupParameter MinimalNumberOfUniqueActionsParameter {
get { return (ILookupParameter)Parameters["MinimalNumberOfUniqueActions"]; }
}
public IValueLookupParameter EvaluatorParameter {
get { return (IValueLookupParameter)Parameters["Evaluator"]; }
}
public IValueLookupParameter SolutionCreatorParameter {
get { return (IValueLookupParameter)Parameters["SolutionCreator"]; }
}
public ILookupParameter RandomParameter {
get { return (ILookupParameter)Parameters["Random"]; }
}
public ILookupParameter CurrentPopulationSizeParameter {
get { return (ILookupParameter)Parameters["CurrentPopulationSize"]; }
}
public IValueLookupParameter ParallelParameter {
get { return (IValueLookupParameter)Parameters["Parallel"]; }
}
private ScopeParameter CurrentScopeParameter {
get { return (ScopeParameter)Parameters["CurrentScope"]; }
}
public IScope CurrentScope {
get { return CurrentScopeParameter.ActualValue; }
}
#endregion
[StorableConstructor]
protected CoveringOperator(bool deserializing) : base(deserializing) { }
protected CoveringOperator(CoveringOperator original, Cloner cloner)
: base(original, cloner) {
}
public override IDeepCloneable Clone(Cloner cloner) {
return new CoveringOperator(this, cloner);
}
public CoveringOperator()
: base() {
Parameters.Add(new LookupParameter>("ActionsInMatchSet"));
Parameters.Add(new LookupParameter>("PossibleActions"));
Parameters.Add(new LookupParameter("MinimalNumberOfUniqueActions"));
Parameters.Add(new ValueLookupParameter("Evaluator"));
Parameters.Add(new ValueLookupParameter("SolutionCreator"));
Parameters.Add(new LookupParameter("Random"));
Parameters.Add(new ValueLookupParameter("Parallel", "True if the operator should be applied in parallel on all sub-scopes, otherwise false.", new BoolValue(true)));
Parameters.Add(new ScopeParameter("CurrentScope", "The current scope to which the new solutions are added as sub-scopes."));
Parameters.Add(new LookupParameter("CurrentPopulationSize"));
}
public override IOperation Apply() {
int count = MinimalNumberOfUniqueActionsParameter.ActualValue.Value - ActionsInMatchSetParameter.ActualValue.Count;
ICoveringSolutionCreator creator = SolutionCreatorParameter.ActualValue;
IOperator evaluator = EvaluatorParameter.ActualValue;
bool parallel = ParallelParameter.ActualValue.Value;
IItemSet clone = (IItemSet)PossibleActionsParameter.ActualValue.Clone();
clone.ExceptWith(ActionsInMatchSetParameter.ActualValue);
if (count > clone.Count) {
throw new ArgumentException("More classifiers with unique actions shall be created than unique actions are available.");
}
if (count > 0) {
CurrentPopulationSizeParameter.ActualValue.Value += count;
int current = CurrentScope.SubScopes.Count;
for (int i = 0; i < count; i++) {
CurrentScope.SubScopes.Add(new Scope((current + i).ToString()));
}
creator.ActionParameter.ActualName = "Action";
OperationCollection variableCreation = new OperationCollection() { Parallel = parallel };
OperationCollection creation = new OperationCollection();
OperationCollection evaluation = new OperationCollection() { Parallel = parallel };
for (int i = 0; i < count; i++) {
VariableCreator variableCreator = new VariableCreator();
int pos = RandomParameter.ActualValue.Next(clone.Count);
IAction action = clone.ElementAt(pos);
clone.Remove(action);
variableCreator.CollectedValues.Add(new ValueParameter("Action", action));
variableCreation.Add(ExecutionContext.CreateOperation(variableCreator, CurrentScope.SubScopes[current + i]));
creation.Add(ExecutionContext.CreateOperation(creator, CurrentScope.SubScopes[current + i]));
evaluation.Add(ExecutionContext.CreateOperation(evaluator, CurrentScope.SubScopes[current + i]));
}
OperationCollection next = new OperationCollection();
next.Add(variableCreation);
next.Add(creation);
next.Add(evaluation);
next.Add(base.Apply());
return next;
} else {
return base.Apply();
}
}
}
}