1  using HEAL.Attic;


2  using HeuristicLab.Collections;


3  using HeuristicLab.Common;


4  using HeuristicLab.Core;


5  using HeuristicLab.Optimization;


6  using HeuristicLab.Parameters;


7  using System;


8 


9  namespace HeuristicLab.Operators


10  {


11 


12  [Item("EngineAlgorithmOperator", "An operator the encapsulates a complete algorithm.")]


13  [StorableType("8BEF3D757DA3468395C5AF7B6AC0A810")]


14  public class EngineAlgorithmOperator : AlgorithmOperator


15  {


16 


17  [Storable]


18  private OperatorGraph algorithmOperatorGraph;


19 


20  [Storable]


21  protected EngineAlgorithm algorithm;


22  public EngineAlgorithm Algorithm


23  {


24  get { return algorithm; }


25  set


26  {


27  if (value == algorithm)


28  return;


29  if (algorithm != null)


30  {


31  DeregisterAlgorithmEvents();


32  if (algorithmOperatorGraph != null)


33  DeregisterOperatorGraphEvents();


34  OperatorGraph.InitialOperator = null;


35  OperatorGraph.Operators.Clear();


36  }


37  algorithm = value;


38  OnAlgorithmChanged();


39  if (algorithm != null)


40  {


41  foreach (IOperator op in algorithm.OperatorGraph.Operators)


42  OperatorGraph.Operators.Add(op);


43  OperatorGraph.InitialOperator = algorithm.OperatorGraph.InitialOperator;


44  RegisterAlgorithmEvents();


45  if (algorithm.OperatorGraph != null)


46  {


47  algorithmOperatorGraph = algorithm.OperatorGraph;


48  RegisterOperatorGraphEvents();


49  }


50  }


51  }


52  }


53 


54  #region Events


55  public event EventHandler AlgorithmChanged;


56 


57  protected virtual void OnAlgorithmChanged()


58  {


59  UpdateParameters();


60  EventHandler handler = AlgorithmChanged;


61  if (handler != null)


62  handler(this, EventArgs.Empty);


63  }


64 


65  private void RegisterAlgorithmEvents()


66  {


67  algorithm.OperatorGraphChanged += algorithm_OperatorGraphChanged;


68  algorithm.ProblemChanged += new EventHandler(algorithm_ProblemChanged);


69  }


70 


71  private void algorithm_ProblemChanged(object sender, EventArgs e)


72  {


73  UpdateParameters();


74  }


75 


76  private void DeregisterAlgorithmEvents()


77  {


78  algorithm.OperatorGraphChanged = algorithm_OperatorGraphChanged;


79  }


80 


81  private void algorithm_OperatorGraphChanged(object sender, EventArgs e)


82  {


83  if (algorithmOperatorGraph != null)


84  DeregisterOperatorGraphEvents();


85  algorithmOperatorGraph = null;


86  if (algorithm.OperatorGraph != null)


87  {


88  algorithmOperatorGraph = algorithm.OperatorGraph;


89  RegisterOperatorGraphEvents();


90  }


91  }


92 


93  private void RegisterOperatorGraphEvents()


94  {


95  algorithmOperatorGraph.InitialOperatorChanged += algorithmOperatorGraph_InitialOperatorChanged;


96  algorithmOperatorGraph.Operators.CollectionReset += algorithmOperatorGraph_Operators_Changed;


97  algorithmOperatorGraph.Operators.ItemsAdded += algorithmOperatorGraph_Operators_Changed;


98  algorithmOperatorGraph.Operators.ItemsRemoved += algorithmOperatorGraph_Operators_Changed;


99  }


100 


101  private void DeregisterOperatorGraphEvents()


102  {


103  algorithmOperatorGraph.InitialOperatorChanged = algorithmOperatorGraph_InitialOperatorChanged;


104  algorithmOperatorGraph.Operators.CollectionReset = algorithmOperatorGraph_Operators_Changed;


105  algorithmOperatorGraph.Operators.ItemsAdded = algorithmOperatorGraph_Operators_Changed;


106  algorithmOperatorGraph.Operators.ItemsRemoved = algorithmOperatorGraph_Operators_Changed;


107  }


108 


109  private void algorithmOperatorGraph_Operators_Changed(object sender, CollectionItemsChangedEventArgs<IOperator> e)


110  {


111  OperatorGraph.Operators.Clear();


112  foreach (IOperator op in algorithmOperatorGraph.Operators)


113  {


114  OperatorGraph.Operators.Add(op);


115  }


116  }


117 


118  private void algorithmOperatorGraph_InitialOperatorChanged(object sender, EventArgs e)


119  {


120  OperatorGraph.InitialOperator = algorithmOperatorGraph.InitialOperator;


121  }


122 


123  private void UpdateParameters()


124  {


125  // TODO: match previously set parameter values


126  IOperator successor = Successor;


127  Parameters.Clear();


128  Parameters.Add(new OperatorParameter("Successor", successor));


129  var alg = Algorithm as IParameterizedItem;


130  foreach (var param in alg.Parameters)


131  {


132  Parameters.Add(WrapParameter(param));


133  }


134  if (Algorithm.Problem != null)


135  {


136  foreach (var param in Algorithm.Problem.Parameters)


137  {


138  Parameters.Add(WrapParameter(param));


139  }


140  }


141  Parameters.Add(new ValueLookupParameter<NamedItemCollection<IResult>>("Results", "Results collection as passed through to the inner algorithn", "Results") { GetsCollected = false });


142  }


143 


144  private static IValueLookupParameter WrapParameter(IParameter param)


145  {


146  IValueLookupParameter v = (IValueLookupParameter)Activator.CreateInstance(typeof(ValueLookupParameter<>).MakeGenericType(param.DataType), new object[] { param.Name, param.Description });


147  v.ActualName = param.Name;


148  IValueParameter valueParam = param as IValueParameter;


149  if (valueParam != null)


150  v.Value = valueParam.Value;


151  return v;


152  }


153  #endregion


154 


155  #region Construction & Cloning


156  [StorableConstructor]


157  protected EngineAlgorithmOperator(StorableConstructorFlag _) : base(_) { }


158  protected EngineAlgorithmOperator(EngineAlgorithmOperator original, Cloner cloner)


159  : base(original, cloner)


160  {


161  this.algorithm = cloner.Clone(original.algorithm);


162  this.algorithmOperatorGraph = cloner.Clone(original.algorithmOperatorGraph);


163  }


164  public EngineAlgorithmOperator() { }


165  public override IDeepCloneable Clone(Cloner cloner)


166  {


167  return new EngineAlgorithmOperator(this, cloner);


168  }


169  #endregion


170 


171  public override IOperation Apply()


172  {


173  var alg = Algorithm as IParameterizedItem;


174  foreach (var param in alg.Parameters)


175  {


176  param.ActualValue = Parameters[param.Name].ActualValue;


177  }


178  if (Algorithm.Problem != null)


179  {


180  foreach (var param in Algorithm.Problem.Parameters)


181  {


182  param.ActualValue = Parameters[param.Name].ActualValue;


183  }


184  }


185  return base.Apply();


186  }


187 


188  }


189  }

