[10753] | 1 | #region License Information
|
---|
| 2 | /* HeuristicLab
|
---|
| 3 | * Copyright (C) 2002-2014 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 |
|
---|
| 22 | using System;
|
---|
[10850] | 23 | using System.Collections.Generic;
|
---|
[10753] | 24 | using System.Drawing;
|
---|
| 25 | using System.Linq;
|
---|
| 26 | using HeuristicLab.Analysis;
|
---|
| 27 | using HeuristicLab.Common;
|
---|
| 28 | using HeuristicLab.Core;
|
---|
| 29 | using HeuristicLab.Data;
|
---|
| 30 | using HeuristicLab.Encodings.BinaryVectorEncoding;
|
---|
| 31 | using HeuristicLab.Encodings.IntegerVectorEncoding;
|
---|
| 32 | using HeuristicLab.Encodings.PermutationEncoding;
|
---|
| 33 | using HeuristicLab.Encodings.RealVectorEncoding;
|
---|
| 34 | using HeuristicLab.Optimization;
|
---|
| 35 | using HeuristicLab.Parameters;
|
---|
| 36 | using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
|
---|
[10850] | 37 | using HeuristicLab.PluginInfrastructure;
|
---|
[10753] | 38 |
|
---|
| 39 | namespace HeuristicLab.Problems.Programmable {
|
---|
| 40 | [Item("Programmable Problem (single-objective)", "Represents a single-objective problem that can be programmed.")]
|
---|
| 41 | [Creatable("Problems")]
|
---|
| 42 | [StorableClass]
|
---|
[10850] | 43 | public class SingleObjectiveProgrammableProblem : SingleObjectiveHeuristicOptimizationProblem<ISingleObjectiveProgrammableProblemEvaluator, ISolutionCreator>, IParameterizedNamedItem, IStorableContent {
|
---|
[10753] | 44 | public string Filename { get; set; }
|
---|
| 45 |
|
---|
| 46 | public static new Image StaticItemImage {
|
---|
[10856] | 47 | get { return Common.Resources.VSImageLibrary.Script; }
|
---|
[10753] | 48 | }
|
---|
| 49 |
|
---|
[10850] | 50 | public new ParameterCollection Parameters {
|
---|
| 51 | get { return base.Parameters; }
|
---|
[10753] | 52 | }
|
---|
[10850] | 53 | IKeyedItemCollection<string, IParameter> IParameterizedItem.Parameters {
|
---|
| 54 | get { return Parameters; }
|
---|
[10753] | 55 | }
|
---|
| 56 |
|
---|
[11484] | 57 | public IValueParameter<ISingleObjectiveProblemDefinition> ProblemDefinitionParameter {
|
---|
| 58 | get { return (IValueParameter<ISingleObjectiveProblemDefinition>)Parameters["ProblemDefinition"]; }
|
---|
[10753] | 59 | }
|
---|
| 60 |
|
---|
[11550] | 61 | protected IValueParameter<IEncoding> EncodingParameter {
|
---|
| 62 | get { return (IValueParameter<IEncoding>)Parameters["Encoding"]; }
|
---|
[10753] | 63 | }
|
---|
| 64 |
|
---|
[11550] | 65 |
|
---|
[11484] | 66 | public ISingleObjectiveProblemDefinition ProblemDefinition {
|
---|
[11393] | 67 | get { return ProblemDefinitionParameter.Value; }
|
---|
| 68 | set { ProblemDefinitionParameter.Value = value; }
|
---|
| 69 | }
|
---|
| 70 |
|
---|
[10753] | 71 | [Storable]
|
---|
[11484] | 72 | protected List<IParameter> DynamicEncodingParameters;
|
---|
[10753] | 73 |
|
---|
[11550] | 74 | protected override IEnumerable<IItem> GetOperators() {
|
---|
| 75 | return base.GetOperators().Concat(ProblemDefinition.Encoding.Operators);
|
---|
| 76 | }
|
---|
| 77 |
|
---|
[10753] | 78 | [StorableConstructor]
|
---|
[10850] | 79 | protected SingleObjectiveProgrammableProblem(bool deserializing) : base(deserializing) { }
|
---|
[10753] | 80 |
|
---|
[10850] | 81 | protected SingleObjectiveProgrammableProblem(SingleObjectiveProgrammableProblem original, Cloner cloner)
|
---|
[10753] | 82 | : base(original, cloner) {
|
---|
[11484] | 83 | DynamicEncodingParameters = original.DynamicEncodingParameters.Select(cloner.Clone).ToList();
|
---|
[10753] | 84 | RegisterEventHandlers();
|
---|
| 85 | }
|
---|
| 86 | public SingleObjectiveProgrammableProblem()
|
---|
[11484] | 87 | : base(new SingleObjectiveEvaluator(), new MultiEncodingCreator()) {
|
---|
| 88 | Parameters.Add(new ValueParameter<ISingleObjectiveProblemDefinition>("ProblemDefinition", "Defines the problem.", new SingleObjectiveProblemScript() { Name = Name }));
|
---|
[11550] | 89 | Parameters.Add(new ValueParameter<IEncoding>("Encoding", "Describes the configuration of the encoding, what the variables are called, what type they are and their bounds if any."));
|
---|
[10753] | 90 |
|
---|
[11484] | 91 | DynamicEncodingParameters = new List<IParameter>();
|
---|
[10753] | 92 |
|
---|
| 93 | Operators.Add(new BestScopeSolutionAnalyzer());
|
---|
[11396] | 94 | Operators.Add(new SingleObjectiveAnalyzer());
|
---|
[10753] | 95 | Operators.Add(Evaluator);
|
---|
| 96 | Operators.Add(SolutionCreator);
|
---|
| 97 |
|
---|
| 98 | RegisterEventHandlers();
|
---|
| 99 | }
|
---|
| 100 |
|
---|
| 101 | public override IDeepCloneable Clone(Cloner cloner) {
|
---|
| 102 | return new SingleObjectiveProgrammableProblem(this, cloner);
|
---|
| 103 | }
|
---|
| 104 |
|
---|
| 105 | [StorableHook(HookType.AfterDeserialization)]
|
---|
[10856] | 106 | // ReSharper disable UnusedMember.Local
|
---|
[10753] | 107 | private void AfterDeserialization() {
|
---|
| 108 | RegisterEventHandlers();
|
---|
| 109 | }
|
---|
[10856] | 110 | // ReSharper restore UnusedMember.Local
|
---|
[10753] | 111 |
|
---|
| 112 | private void RegisterEventHandlers() {
|
---|
[11393] | 113 | ProblemDefinitionParameter.ValueChanged += ProblemDefinitionParameterOnValueChanged;
|
---|
[11546] | 114 | RegisterProblemDefinitionEventHandlers();
|
---|
[10753] | 115 | }
|
---|
| 116 |
|
---|
[11393] | 117 | private void ProblemDefinitionParameterOnValueChanged(object sender, EventArgs eventArgs) {
|
---|
[11546] | 118 | RegisterProblemDefinitionEventHandlers();
|
---|
[11393] | 119 | Parameterize();
|
---|
[10753] | 120 | }
|
---|
| 121 |
|
---|
[11546] | 122 | private void RegisterProblemDefinitionEventHandlers() {
|
---|
[11484] | 123 | ProblemDefinitionParameter.Value.ProblemDefinitionChanged += ProblemDefinitionChanged;
|
---|
[11546] | 124 | ProblemDefinitionParameter.Value.NameChanged += ProblemDefinitionNameChanged;
|
---|
[10753] | 125 | }
|
---|
| 126 |
|
---|
[11546] | 127 | private void ProblemDefinitionNameChanged(object sender, EventArgs eventArgs) {
|
---|
[11393] | 128 | if (sender != ProblemDefinitionParameter.Value) return;
|
---|
| 129 | Name = ProblemDefinitionParameter.Value.Name;
|
---|
[10753] | 130 | }
|
---|
| 131 |
|
---|
| 132 | protected override void OnNameChanged() {
|
---|
| 133 | base.OnNameChanged();
|
---|
[11393] | 134 | ProblemDefinitionParameter.Value.Name = Name;
|
---|
[10753] | 135 | }
|
---|
| 136 |
|
---|
[11396] | 137 | protected override void OnEvaluatorChanged() {
|
---|
| 138 | base.OnEvaluatorChanged();
|
---|
| 139 | Parameterize();
|
---|
| 140 | }
|
---|
| 141 |
|
---|
[11484] | 142 | protected virtual void ProblemDefinitionChanged(object sender, EventArgs eventArgs) {
|
---|
[11393] | 143 | Parameterize();
|
---|
| 144 | }
|
---|
| 145 |
|
---|
| 146 | protected virtual void Parameterize() {
|
---|
[11484] | 147 | var definition = ProblemDefinitionParameter.Value;
|
---|
| 148 | if (definition == null) return;
|
---|
[10753] | 149 |
|
---|
[11550] | 150 | IEncoding encoding = definition.Encoding;
|
---|
[11543] | 151 |
|
---|
[11484] | 152 | EncodingParameter.Value = encoding;
|
---|
| 153 | Maximization.Value = definition.IsMaximizationProblem;
|
---|
[10753] | 154 |
|
---|
[11484] | 155 | Evaluator.EncodingParameter.ActualName = EncodingParameter.Name;
|
---|
[11396] | 156 | Evaluator.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
|
---|
| 157 | foreach (var evalOp in Operators.OfType<ISingleObjectiveProgrammableProblemEvaluator>()) {
|
---|
[11484] | 158 | evalOp.EncodingParameter.ActualName = EncodingParameter.Name;
|
---|
[11396] | 159 | evalOp.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
|
---|
| 160 | }
|
---|
| 161 | foreach (var analyzeOp in Operators.OfType<ISingleObjectiveProgrammableProblemAnalyzer>()) {
|
---|
[11484] | 162 | analyzeOp.EncodingParameter.ActualName = EncodingParameter.Name;
|
---|
[11396] | 163 | analyzeOp.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
|
---|
| 164 | analyzeOp.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
|
---|
| 165 | }
|
---|
| 166 |
|
---|
[11484] | 167 | foreach (var param in DynamicEncodingParameters)
|
---|
| 168 | if (Parameters.Contains(param)) Parameters.Remove(param);
|
---|
| 169 | DynamicEncodingParameters.Clear();
|
---|
[10856] | 170 |
|
---|
[11484] | 171 | var creator = ConfigureCreator(encoding);
|
---|
| 172 |
|
---|
| 173 | foreach (var param in DynamicEncodingParameters) {
|
---|
| 174 | param.Hidden = true;
|
---|
| 175 | Parameters.Add(param);
|
---|
| 176 | }
|
---|
| 177 |
|
---|
| 178 | var multiEncoding = encoding as MultiEncoding;
|
---|
| 179 | if (multiEncoding != null) {
|
---|
| 180 | ConfigureMultiVectorEncodingOperators((MultiEncodingCreator)creator, multiEncoding);
|
---|
[10856] | 181 | } else {
|
---|
[11484] | 182 | ConfigureSingleEncodingOperators(creator, encoding);
|
---|
[10856] | 183 | }
|
---|
[11405] | 184 | UpdateImprovementOperators();
|
---|
[11363] | 185 | UpdateMoveOperators();
|
---|
[10856] | 186 | }
|
---|
| 187 |
|
---|
[11550] | 188 | protected virtual ISolutionCreator ConfigureCreator(IEncoding encoding) {
|
---|
[11546] | 189 | #region Configure RealVector Creator
|
---|
| 190 | var realEnc = encoding as RealEncoding;
|
---|
| 191 | if (realEnc != null) {
|
---|
[11550] | 192 | DynamicEncodingParameters.AddRange(realEnc.Parameters);
|
---|
[11546] | 193 | return realEnc.DefaultSolutionCreator;
|
---|
| 194 | }
|
---|
| 195 | #endregion
|
---|
[11553] | 196 | #region Configure BinaryVector Creator
|
---|
| 197 | var binEnc = encoding as BinaryEncoding;
|
---|
| 198 | if (binEnc != null) {
|
---|
| 199 | DynamicEncodingParameters.AddRange(binEnc.Parameters);
|
---|
| 200 | return binEnc.DefaultSolutionCreator;
|
---|
| 201 | }
|
---|
| 202 | #endregion
|
---|
[11561] | 203 | #region Configure IntegerVector Creator
|
---|
| 204 | var intEnc = encoding as IntegerEncoding;
|
---|
| 205 | if (intEnc != null) {
|
---|
| 206 | DynamicEncodingParameters.AddRange(intEnc.Parameters);
|
---|
| 207 | return intEnc.DefaultSolutionCreator;
|
---|
| 208 | }
|
---|
| 209 | #endregion
|
---|
[11484] | 210 | #region Configure MultiEncoding Creator
|
---|
| 211 | var multiEncoding = encoding as MultiEncoding;
|
---|
| 212 | if (multiEncoding != null) {
|
---|
| 213 | var creator = new MultiEncodingCreator();
|
---|
| 214 | foreach (var enc in multiEncoding.Encodings) {
|
---|
| 215 | if (enc is MultiEncoding) throw new InvalidOperationException("MultiEncoding within a MultiEncoding is not supported.");
|
---|
| 216 | creator.Operators.Add(ConfigureCreator(enc));
|
---|
[10850] | 217 | }
|
---|
[11484] | 218 | return creator;
|
---|
| 219 | }
|
---|
| 220 | #endregion
|
---|
| 221 | #region Configure Permutation Creator
|
---|
| 222 | var permEnc = encoding as PermutationEncoding;
|
---|
| 223 | if (permEnc != null) {
|
---|
| 224 | var l = new ValueParameter<IntValue>(permEnc.Name + "Length", permEnc.Length);
|
---|
| 225 | DynamicEncodingParameters.Add(l);
|
---|
[10753] | 226 |
|
---|
[11484] | 227 | var creator = new RandomPermutationCreator();
|
---|
| 228 | creator.PermutationParameter.ActualName = permEnc.Name;
|
---|
| 229 | creator.LengthParameter.ActualName = l.Name;
|
---|
| 230 | creator.PermutationTypeParameter.Value = permEnc.Type;
|
---|
| 231 | return creator;
|
---|
[10753] | 232 | }
|
---|
[11484] | 233 | #endregion
|
---|
| 234 | throw new ArgumentException(string.Format("Encoding {0} is unknown.", encoding != null ? encoding.GetType().FullName : "(null)"));
|
---|
[10856] | 235 | }
|
---|
[10753] | 236 |
|
---|
[11546] | 237 |
|
---|
[11550] | 238 | private IEnumerable<IOperator> GetDiscoveredOperators<T>() where T : class,IOperator {
|
---|
| 239 | return ApplicationManager.Manager.GetInstances<T>()
|
---|
| 240 | .Except(Operators.OfType<T>(), new TypeEqualityComparer<T>());
|
---|
[11546] | 241 | }
|
---|
[11550] | 242 | protected virtual void ConfigureSingleEncodingOperators(ISolutionCreator newCreator, IEncoding encoding) {
|
---|
[11484] | 243 | // remove all multiencoding operators
|
---|
| 244 | Operators.RemoveAll(x => x is MultiEncodingCrossover
|
---|
| 245 | || x is MultiEncodingManipulator
|
---|
| 246 | || x is MultiEncodingCreator);
|
---|
| 247 |
|
---|
[11546] | 248 | #region Configure Operators for RealVectorEncoding
|
---|
| 249 | var realEncoding = encoding as RealEncoding;
|
---|
| 250 | if (realEncoding != null) {
|
---|
| 251 | // do not replace a real vector creator that was manually set
|
---|
| 252 | if (!(SolutionCreator is IRealVectorCreator)
|
---|
[11553] | 253 | || ((IRealVectorCreator)SolutionCreator).RealVectorParameter.ActualName != realEncoding.Name) {
|
---|
[11546] | 254 | Operators.Remove(SolutionCreator);
|
---|
| 255 | SolutionCreator = newCreator;
|
---|
| 256 | }
|
---|
| 257 |
|
---|
[11550] | 258 | foreach (var su in realEncoding.Operators.OfType<IRealVectorSwarmUpdater>()) {
|
---|
[11546] | 259 | su.MaximizationParameter.ActualName = MaximizationParameter.Name;
|
---|
| 260 | }
|
---|
[11553] | 261 | }
|
---|
[11546] | 262 | #endregion
|
---|
[11398] | 263 | #region Configure Operators for BinaryVectorEncoding
|
---|
[11553] | 264 | var binEncoding = encoding as BinaryEncoding;
|
---|
| 265 | if (binEncoding != null) {
|
---|
[10856] | 266 | // do not replace a binary vector creator that was manually set
|
---|
[11553] | 267 | if (!(SolutionCreator is IBinaryVectorCreator) || ((IBinaryVectorCreator)SolutionCreator).BinaryVectorParameter.ActualName != binEncoding.Name) {
|
---|
[10856] | 268 | Operators.Remove(SolutionCreator);
|
---|
| 269 | SolutionCreator = newCreator;
|
---|
[10850] | 270 | }
|
---|
[10856] | 271 | }
|
---|
[11398] | 272 | #endregion
|
---|
| 273 | #region Configure Operators for IntegerVectorEncoding
|
---|
[11561] | 274 | var intEncoding = encoding as IntegerEncoding;
|
---|
| 275 | if (intEncoding != null) {
|
---|
[10856] | 276 | // do not replace an integer vector creator that was manually set
|
---|
| 277 | if (!(SolutionCreator is IIntegerVectorCreator)
|
---|
[11561] | 278 | || ((IIntegerVectorCreator)SolutionCreator).IntegerVectorParameter.ActualName != intEncoding.Name) {
|
---|
[10856] | 279 | Operators.Remove(SolutionCreator);
|
---|
| 280 | SolutionCreator = newCreator;
|
---|
| 281 | }
|
---|
| 282 | }
|
---|
[11398] | 283 | #endregion
|
---|
| 284 | #region Configure Operators for PermutationEncoding
|
---|
[10856] | 285 | var permCreator = newCreator as IPermutationCreator;
|
---|
| 286 | if (permCreator != null) {
|
---|
| 287 | var paramName = permCreator.PermutationParameter.ActualName;
|
---|
| 288 | // do not replace a permutation creator that was manually set
|
---|
| 289 | if (!(SolutionCreator is IPermutationCreator)
|
---|
| 290 | || ((IPermutationCreator)SolutionCreator).PermutationParameter.ActualName != permCreator.PermutationParameter.ActualName) {
|
---|
| 291 | Operators.Remove(SolutionCreator);
|
---|
| 292 | SolutionCreator = newCreator;
|
---|
| 293 | Operators.Add(SolutionCreator);
|
---|
| 294 | }
|
---|
[11398] | 295 |
|
---|
| 296 | #region Wire Permutation Crossovers
|
---|
[11484] | 297 | var crossovers = Operators.OfType<IPermutationCrossover>()
|
---|
| 298 | .Union(ApplicationManager.Manager.GetInstances<IPermutationCrossover>(), new TypeEqualityComparer<IPermutationCrossover>())
|
---|
| 299 | .ToList();
|
---|
[10856] | 300 | foreach (var xo in crossovers) {
|
---|
| 301 | xo.ChildParameter.ActualName = permCreator.PermutationParameter.ActualName;
|
---|
[11398] | 302 | xo.ChildParameter.Hidden = true;
|
---|
[10856] | 303 | xo.ParentsParameter.ActualName = permCreator.PermutationParameter.ActualName;
|
---|
[11398] | 304 | xo.ParentsParameter.Hidden = true;
|
---|
[10856] | 305 | }
|
---|
[11484] | 306 | Operators.AddRange(crossovers.Except(Operators.OfType<IPermutationCrossover>()));
|
---|
[11398] | 307 | #endregion
|
---|
| 308 | #region Wire Permutation Manipulators
|
---|
[11484] | 309 | var manipulators = Operators.OfType<IPermutationManipulator>()
|
---|
| 310 | .Union(ApplicationManager.Manager.GetInstances<IPermutationManipulator>(), new TypeEqualityComparer<IPermutationManipulator>())
|
---|
| 311 | .ToList();
|
---|
[11398] | 312 | foreach (var m in manipulators) {
|
---|
[10856] | 313 | m.PermutationParameter.ActualName = permCreator.PermutationParameter.ActualName;
|
---|
[11398] | 314 | m.PermutationParameter.Hidden = true;
|
---|
| 315 | }
|
---|
[11484] | 316 | Operators.AddRange(manipulators.Except(Operators.OfType<IPermutationManipulator>()));
|
---|
[11398] | 317 | #endregion
|
---|
[11484] | 318 | #region Wire Permutation ShakingOperators
|
---|
| 319 | var shakingOperators = Operators.OfType<IPermutationMultiNeighborhoodShakingOperator>()
|
---|
| 320 | .Union(ApplicationManager.Manager.GetInstances<IPermutationMultiNeighborhoodShakingOperator>(), new TypeEqualityComparer<IPermutationMultiNeighborhoodShakingOperator>())
|
---|
| 321 | .ToList();
|
---|
[11398] | 322 | foreach (var op in shakingOperators) {
|
---|
| 323 | op.PermutationParameter.ActualName = paramName;
|
---|
| 324 | op.PermutationParameter.Hidden = true;
|
---|
| 325 | }
|
---|
[11484] | 326 | Operators.AddRange(shakingOperators.Except(Operators.OfType<IPermutationMultiNeighborhoodShakingOperator>()));
|
---|
[11398] | 327 | #endregion
|
---|
| 328 | } else {
|
---|
| 329 | Operators.RemoveAll(x => x is IPermutationCrossover
|
---|
| 330 | || x is IPermutationManipulator
|
---|
| 331 | || x is IPermutationMultiNeighborhoodShakingOperator);
|
---|
[10856] | 332 | }
|
---|
[11398] | 333 | #endregion
|
---|
[10856] | 334 | }
|
---|
| 335 |
|
---|
[11484] | 336 | protected virtual void ConfigureMultiVectorEncodingOperators(MultiEncodingCreator newCreator, MultiEncoding encoding) {
|
---|
| 337 | var newBinParams = new HashSet<string>(newCreator.Operators.OfType<IBinaryVectorCreator>().Select(x => x.BinaryVectorParameter.ActualName));
|
---|
| 338 | var newIntParams = new HashSet<string>(newCreator.Operators.OfType<IIntegerVectorCreator>().Select(x => x.IntegerVectorParameter.ActualName));
|
---|
| 339 | var newRealParams = new HashSet<string>(newCreator.Operators.OfType<IRealVectorCreator>().Select(x => x.RealVectorParameter.ActualName));
|
---|
| 340 | var newPermParams = new HashSet<string>(newCreator.Operators.OfType<IPermutationCreator>().Select(x => x.PermutationParameter.ActualName));
|
---|
[10856] | 341 |
|
---|
[11484] | 342 | var oldCreator = SolutionCreator as MultiEncodingCreator;
|
---|
| 343 | if (oldCreator == null) SolutionCreator = newCreator;
|
---|
| 344 | else {
|
---|
| 345 | #region Configure BinaryVector Creator
|
---|
| 346 | var oldBinParams = new HashSet<string>(oldCreator.Operators.OfType<IBinaryVectorCreator>().Select(x => x.BinaryVectorParameter.ActualName));
|
---|
| 347 | foreach (var toAdd in newBinParams.Except(oldBinParams)) {
|
---|
| 348 | oldCreator.Operators.Add(newCreator.Operators.OfType<IBinaryVectorCreator>().Single(x => x.BinaryVectorParameter.ActualName == toAdd));
|
---|
[10856] | 349 | }
|
---|
[11484] | 350 | foreach (var toRemove in oldBinParams.Except(newBinParams)) {
|
---|
| 351 | var op = oldCreator.Operators.OfType<IBinaryVectorCreator>().SingleOrDefault(x => x.BinaryVectorParameter.ActualName == toRemove);
|
---|
[10856] | 352 | if (op != null) oldCreator.Operators.Remove(op);
|
---|
| 353 | }
|
---|
[11484] | 354 | #endregion
|
---|
| 355 |
|
---|
| 356 | #region Configure IntegerVector Creator
|
---|
| 357 | var oldIntParams = new HashSet<string>(oldCreator.Operators.OfType<IIntegerVectorCreator>().Select(x => x.IntegerVectorParameter.ActualName));
|
---|
| 358 | foreach (var toAdd in newIntParams.Except(oldIntParams)) {
|
---|
| 359 | oldCreator.Operators.Add(newCreator.Operators.OfType<IIntegerVectorCreator>().Single(x => x.IntegerVectorParameter.ActualName == toAdd));
|
---|
[10856] | 360 | }
|
---|
[11484] | 361 | foreach (var toRemove in oldIntParams.Except(newIntParams)) {
|
---|
| 362 | var op = oldCreator.Operators.OfType<IIntegerVectorCreator>().SingleOrDefault(x => x.IntegerVectorParameter.ActualName == toRemove);
|
---|
[10856] | 363 | if (op != null) oldCreator.Operators.Remove(op);
|
---|
| 364 | }
|
---|
[11484] | 365 | #endregion
|
---|
| 366 |
|
---|
| 367 | #region Configure RealVector Creator
|
---|
| 368 | var oldRealParams = new HashSet<string>(oldCreator.Operators.OfType<IRealVectorCreator>().Select(x => x.RealVectorParameter.ActualName));
|
---|
| 369 | foreach (var toAdd in newRealParams.Except(oldRealParams)) {
|
---|
| 370 | oldCreator.Operators.Add(newCreator.Operators.OfType<IRealVectorCreator>().Single(x => x.RealVectorParameter.ActualName == toAdd));
|
---|
[10856] | 371 | }
|
---|
[11484] | 372 | foreach (var toRemove in oldRealParams.Except(newRealParams)) {
|
---|
| 373 | var op = oldCreator.Operators.OfType<IRealVectorCreator>().SingleOrDefault(x => x.RealVectorParameter.ActualName == toRemove);
|
---|
[10856] | 374 | if (op != null) oldCreator.Operators.Remove(op);
|
---|
| 375 | }
|
---|
[11484] | 376 | #endregion
|
---|
| 377 |
|
---|
| 378 | #region Configure Permutation Creator
|
---|
| 379 | var oldPermParams = new HashSet<string>(oldCreator.Operators.OfType<IPermutationCreator>().Select(x => x.PermutationParameter.ActualName));
|
---|
| 380 | foreach (var toAdd in newPermParams.Except(oldPermParams)) {
|
---|
| 381 | oldCreator.Operators.Add(newCreator.Operators.OfType<IPermutationCreator>().Single(x => x.PermutationParameter.ActualName == toAdd));
|
---|
[10856] | 382 | }
|
---|
[11484] | 383 | foreach (var toRemove in oldPermParams.Except(newPermParams)) {
|
---|
| 384 | var op = oldCreator.Operators.OfType<IPermutationCreator>().SingleOrDefault(x => x.PermutationParameter.ActualName == toRemove);
|
---|
[10856] | 385 | if (op != null) oldCreator.Operators.Remove(op);
|
---|
| 386 | }
|
---|
| 387 | // we also have to sync the permutation type (in case this changes, as it is a value parameter)
|
---|
[11484] | 388 | foreach (var intersect in newPermParams.Intersect(oldPermParams)) {
|
---|
| 389 | var oldPermCreator = oldCreator.Operators.OfType<IPermutationCreator>().Single(x => x.PermutationParameter.ActualName == intersect);
|
---|
| 390 | var newPermCreator = newCreator.Operators.OfType<IPermutationCreator>().Single(x => x.PermutationParameter.ActualName == intersect);
|
---|
[10856] | 391 | oldPermCreator.PermutationTypeParameter.Value = newPermCreator.PermutationTypeParameter.Value;
|
---|
| 392 | }
|
---|
[11484] | 393 | #endregion
|
---|
| 394 |
|
---|
[10856] | 395 | }
|
---|
| 396 |
|
---|
| 397 | // crossover and manipulator for multi-vector encoding
|
---|
| 398 | // the condition checks if a multi-vector encoding is to be updated (there already exists ParameterVectorCrossover and ParameterVectorManipulator)
|
---|
[11484] | 399 | if (Operators.OfType<MultiEncodingCrossover>().Any() && Operators.OfType<MultiEncodingManipulator>().Any()) {
|
---|
[11398] | 400 | #region Update existing multi-vector encoding
|
---|
| 401 | #region Update ParameterVector Crossover ...
|
---|
[11484] | 402 | foreach (var oldXo in Operators.OfType<MultiEncodingCrossover>()) {
|
---|
[11398] | 403 | #region ... for binary parameters
|
---|
[11484] | 404 | var oldBinParams = new HashSet<string>(oldXo.Operators.OfType<IBinaryVectorCrossover>().Select(x => x.ChildParameter.ActualName));
|
---|
[10856] | 405 | foreach (var toAdd in newBinParams.Except(oldBinParams))
|
---|
[11484] | 406 | oldXo.Operators.Add(GetDefaultBinaryCrossover(toAdd, encoding));
|
---|
[10856] | 407 | foreach (var toRemove in oldBinParams.Except(newBinParams)) {
|
---|
[11484] | 408 | var op = oldXo.Operators.OfType<IBinaryVectorCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
|
---|
[10856] | 409 | if (op != null) oldXo.Operators.Remove(op);
|
---|
[10850] | 410 | }
|
---|
[11398] | 411 | #endregion
|
---|
| 412 | #region ... for integer parameters
|
---|
[11484] | 413 | var oldIntParams = new HashSet<string>(oldXo.Operators.OfType<IIntegerVectorCrossover>().Select(x => x.ChildParameter.ActualName));
|
---|
[10856] | 414 | foreach (var toAdd in newIntParams.Except(oldIntParams))
|
---|
[11484] | 415 | oldXo.Operators.Add(GetDefaultIntegerCrossover(toAdd, encoding));
|
---|
[10856] | 416 | foreach (var toRemove in oldIntParams.Except(newIntParams)) {
|
---|
[11484] | 417 | var op = oldXo.Operators.OfType<IIntegerVectorCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
|
---|
[10856] | 418 | if (op != null) oldXo.Operators.Remove(op);
|
---|
[10850] | 419 | }
|
---|
[11398] | 420 | #endregion
|
---|
| 421 | #region ... for real parameters
|
---|
[11484] | 422 | var oldRealParams = new HashSet<string>(oldXo.Operators.OfType<IRealVectorCrossover>().Select(x => x.ChildParameter.ActualName));
|
---|
[10856] | 423 | foreach (var toAdd in newRealParams.Except(oldRealParams))
|
---|
[11484] | 424 | oldXo.Operators.Add(GetDefaultRealCrossover(toAdd, encoding));
|
---|
[10856] | 425 | foreach (var toRemove in oldRealParams.Except(newRealParams)) {
|
---|
[11484] | 426 | var op = oldXo.Operators.OfType<IRealVectorCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
|
---|
[10856] | 427 | if (op != null) oldXo.Operators.Remove(op);
|
---|
[10850] | 428 | }
|
---|
[11398] | 429 | #endregion
|
---|
| 430 | #region ... for permutation parameters
|
---|
[11484] | 431 | var oldPermParams = new HashSet<string>(oldXo.Operators.OfType<IPermutationCrossover>().Select(x => x.ChildParameter.ActualName));
|
---|
[10856] | 432 | foreach (var toAdd in newPermParams.Except(oldPermParams))
|
---|
[11484] | 433 | oldXo.Operators.Add(GetDefaultPermutationCrossover(toAdd, encoding));
|
---|
[10856] | 434 | foreach (var toRemove in oldPermParams.Except(newPermParams)) {
|
---|
[11484] | 435 | var op = oldXo.Operators.OfType<IPermutationCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
|
---|
[10856] | 436 | if (op != null) oldXo.Operators.Remove(op);
|
---|
[10850] | 437 | }
|
---|
[11398] | 438 | #endregion
|
---|
[10850] | 439 | }
|
---|
[11398] | 440 | #endregion
|
---|
| 441 | #region Update ParameterVector Manipulator ...
|
---|
[11484] | 442 | foreach (var oldM in Operators.OfType<MultiEncodingManipulator>()) {
|
---|
[11398] | 443 | #region ... for binary parameters
|
---|
[11484] | 444 | var oldBinParams = new HashSet<string>(oldM.Operators.OfType<IBinaryVectorManipulator>().Select(x => x.BinaryVectorParameter.ActualName));
|
---|
[10856] | 445 | foreach (var toAdd in newBinParams.Except(oldBinParams))
|
---|
[11484] | 446 | oldM.Operators.Add(GetDefaultBinaryManipulator(toAdd, encoding));
|
---|
[10856] | 447 | foreach (var toRemove in oldBinParams.Except(newBinParams)) {
|
---|
[11484] | 448 | var op = oldM.Operators.OfType<IBinaryVectorManipulator>().SingleOrDefault(x => x.BinaryVectorParameter.ActualName == toRemove);
|
---|
[10856] | 449 | if (op != null) oldM.Operators.Remove(op);
|
---|
[10850] | 450 | }
|
---|
[11398] | 451 | #endregion
|
---|
| 452 | #region ... for integer parameters
|
---|
[11484] | 453 | var oldIntParams = new HashSet<string>(oldM.Operators.OfType<IIntegerVectorManipulator>().Select(x => x.IntegerVectorParameter.ActualName));
|
---|
[10856] | 454 | foreach (var toAdd in newIntParams.Except(oldIntParams))
|
---|
[11484] | 455 | oldM.Operators.Add(GetDefaultIntegerManipulator(toAdd, encoding));
|
---|
[10856] | 456 | foreach (var toRemove in oldIntParams.Except(newIntParams)) {
|
---|
[11484] | 457 | var op = oldM.Operators.OfType<IIntegerVectorManipulator>().SingleOrDefault(x => x.IntegerVectorParameter.ActualName == toRemove);
|
---|
[10856] | 458 | if (op != null) oldM.Operators.Remove(op);
|
---|
[10850] | 459 | }
|
---|
[11398] | 460 | #endregion
|
---|
| 461 | #region ... for real parameters
|
---|
[11484] | 462 | var oldRealParams = new HashSet<string>(oldM.Operators.OfType<IRealVectorManipulator>().Select(x => x.RealVectorParameter.ActualName));
|
---|
[10856] | 463 | foreach (var toAdd in newRealParams.Except(oldRealParams))
|
---|
[11484] | 464 | oldM.Operators.Add(GetDefaultRealManipulator(toAdd, encoding));
|
---|
[10856] | 465 | foreach (var toRemove in oldRealParams.Except(newRealParams)) {
|
---|
[11484] | 466 | var op = oldM.Operators.OfType<IRealVectorManipulator>().SingleOrDefault(x => x.RealVectorParameter.ActualName == toRemove);
|
---|
[10856] | 467 | if (op != null) oldM.Operators.Remove(op);
|
---|
[10850] | 468 | }
|
---|
[11398] | 469 | #endregion
|
---|
| 470 | #region ... for permutation parameters
|
---|
[11484] | 471 | var oldPermParams = new HashSet<string>(oldM.Operators.OfType<IPermutationManipulator>().Select(x => x.PermutationParameter.ActualName));
|
---|
[10856] | 472 | foreach (var toAdd in newPermParams.Except(oldPermParams))
|
---|
[11484] | 473 | oldM.Operators.Add(GetDefaultPermutationManipulator(toAdd, encoding));
|
---|
[10856] | 474 | foreach (var toRemove in oldPermParams.Except(newPermParams)) {
|
---|
[11484] | 475 | var op = oldM.Operators.OfType<IPermutationManipulator>().SingleOrDefault(x => x.PermutationParameter.ActualName == toRemove);
|
---|
[10856] | 476 | if (op != null) oldM.Operators.Remove(op);
|
---|
[10850] | 477 | }
|
---|
[11398] | 478 | #endregion
|
---|
[10856] | 479 | }
|
---|
[11398] | 480 | #endregion
|
---|
| 481 | #endregion
|
---|
[10856] | 482 | } else {
|
---|
[11398] | 483 | #region Handle transition from single-vector to multi-vector encoding
|
---|
[10856] | 484 | Operators.RemoveAll(x => x is ICrossover);
|
---|
| 485 | Operators.RemoveAll(x => x is IManipulator);
|
---|
[11398] | 486 | Operators.RemoveAll(x => x is IStrategyParameterCreator || x is IStrategyParameterManipulator || x is IStrategyParameterCrossover);
|
---|
| 487 | Operators.RemoveAll(x => x is IParticleCreator);
|
---|
| 488 | Operators.RemoveAll(x => x is IParticleUpdater);
|
---|
| 489 | Operators.RemoveAll(x => x is ISwarmUpdater);
|
---|
| 490 | Operators.RemoveAll(x => x is IMultiNeighborhoodShakingOperator);
|
---|
| 491 |
|
---|
[11484] | 492 | var crossover = new MultiEncodingCrossover();
|
---|
| 493 | var manipulator = new MultiEncodingManipulator();
|
---|
| 494 | foreach (var enc in encoding.Encodings) {
|
---|
| 495 | if (enc is BinaryEncoding) {
|
---|
| 496 | crossover.Operators.Add(GetDefaultBinaryCrossover(enc.Name, encoding));
|
---|
| 497 | manipulator.Operators.Add(GetDefaultBinaryManipulator(enc.Name, encoding));
|
---|
[10856] | 498 | continue;
|
---|
[10850] | 499 | }
|
---|
[11484] | 500 | var intConfig = enc as IntegerEncoding;
|
---|
[10856] | 501 | if (intConfig != null) {
|
---|
[11484] | 502 | crossover.Operators.Add(GetDefaultIntegerCrossover(enc.Name, encoding));
|
---|
| 503 | manipulator.Operators.Add(GetDefaultIntegerManipulator(enc.Name, encoding));
|
---|
[10856] | 504 | continue;
|
---|
[10850] | 505 | }
|
---|
[11484] | 506 | var realConfig = enc as RealEncoding;
|
---|
[10856] | 507 | if (realConfig != null) {
|
---|
[11484] | 508 | crossover.Operators.Add(GetDefaultRealCrossover(enc.Name, encoding));
|
---|
| 509 | manipulator.Operators.Add(GetDefaultRealManipulator(enc.Name, encoding));
|
---|
[10856] | 510 | continue;
|
---|
[10850] | 511 | }
|
---|
[11484] | 512 | var permConfig = enc as PermutationEncoding;
|
---|
[10856] | 513 | if (permConfig != null) {
|
---|
[11484] | 514 | crossover.Operators.Add(GetDefaultPermutationCrossover(enc.Name, encoding));
|
---|
| 515 | manipulator.Operators.Add(GetDefaultPermutationManipulator(enc.Name, encoding));
|
---|
[10856] | 516 | continue;
|
---|
[10855] | 517 | }
|
---|
[11484] | 518 | throw new InvalidOperationException("Unknown type for parameter " + enc.Name);
|
---|
[10855] | 519 | }
|
---|
[10856] | 520 | Operators.Add(crossover);
|
---|
| 521 | Operators.Add(manipulator);
|
---|
[11398] | 522 | #endregion
|
---|
[10753] | 523 | }
|
---|
| 524 | }
|
---|
[10856] | 525 |
|
---|
[11405] | 526 | protected virtual void UpdateImprovementOperators() {
|
---|
[11484] | 527 | if (!Operators.Any(x => x is SingleObjectiveImprover))
|
---|
| 528 | Operators.Add(new SingleObjectiveImprover());
|
---|
| 529 | foreach (var improver in Operators.OfType<SingleObjectiveImprover>()) {
|
---|
| 530 | improver.EncodingParameter.ActualName = EncodingParameter.Name;
|
---|
[11405] | 531 | improver.MaximizationParameter.ActualName = MaximizationParameter.Name;
|
---|
| 532 | improver.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
|
---|
| 533 | improver.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
|
---|
| 534 | }
|
---|
| 535 | }
|
---|
[11363] | 536 | protected virtual void UpdateMoveOperators() {
|
---|
[11484] | 537 | if (!Operators.Any(x => x is SingleObjectiveMoveGenerator))
|
---|
| 538 | Operators.Add(new SingleObjectiveMoveGenerator());
|
---|
| 539 | if (!Operators.Any(x => x is SingleObjectiveMoveEvaluator))
|
---|
| 540 | Operators.Add(new SingleObjectiveMoveEvaluator());
|
---|
| 541 | if (!Operators.Any(x => x is SingleObjectiveMoveMaker))
|
---|
| 542 | Operators.Add(new SingleObjectiveMoveMaker());
|
---|
[11363] | 543 |
|
---|
[11484] | 544 | foreach (var generator in Operators.OfType<SingleObjectiveMoveGenerator>()) {
|
---|
| 545 | generator.EncodingParameter.ActualName = EncodingParameter.Name;
|
---|
[11424] | 546 | generator.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
|
---|
| 547 | }
|
---|
[11484] | 548 | foreach (var evaluator in Operators.OfType<SingleObjectiveMoveEvaluator>()) {
|
---|
| 549 | evaluator.EncodingParameter.ActualName = EncodingParameter.Name;
|
---|
[11424] | 550 | evaluator.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
|
---|
| 551 | evaluator.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
|
---|
| 552 | }
|
---|
[11484] | 553 | foreach (var maker in Operators.OfType<SingleObjectiveMoveMaker>()) {
|
---|
| 554 | maker.EncodingParameter.ActualName = EncodingParameter.Name;
|
---|
| 555 | maker.MoveQualityParameter.ActualName = Operators.OfType<SingleObjectiveMoveEvaluator>().First().MoveQualityParameter.ActualName;
|
---|
[11424] | 556 | maker.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
|
---|
| 557 | }
|
---|
[11363] | 558 | }
|
---|
| 559 |
|
---|
[11398] | 560 | #region GetDefaultOperators for Crossovers and Manipulators
|
---|
[10856] | 561 | // ReSharper disable RedundantNameQualifier
|
---|
[11484] | 562 | protected virtual IBinaryVectorCrossover GetDefaultBinaryCrossover(string paramName, MultiEncoding config) {
|
---|
| 563 | var binConfig = (BinaryEncoding)config.Encodings[paramName];
|
---|
[10856] | 564 | IBinaryVectorCrossover binXo;
|
---|
[11553] | 565 | if (binConfig.Length > 3) binXo = new Encodings.BinaryVectorEncoding.SinglePointCrossover();
|
---|
[10856] | 566 | else binXo = new Encodings.BinaryVectorEncoding.UniformCrossover();
|
---|
| 567 | binXo.ChildParameter.ActualName = paramName;
|
---|
| 568 | binXo.ParentsParameter.ActualName = paramName;
|
---|
| 569 | return binXo;
|
---|
| 570 | }
|
---|
| 571 |
|
---|
[11484] | 572 | protected virtual IBinaryVectorManipulator GetDefaultBinaryManipulator(string paramName, MultiEncoding config) {
|
---|
[10856] | 573 | var binM = new Encodings.BinaryVectorEncoding.SomePositionsBitflipManipulator();
|
---|
| 574 | binM.BinaryVectorParameter.ActualName = paramName;
|
---|
| 575 | binM.MutationProbabilityParameter.Value = new DoubleValue(0.1);
|
---|
| 576 | return binM;
|
---|
| 577 | }
|
---|
| 578 |
|
---|
[11484] | 579 | protected virtual IIntegerVectorCrossover GetDefaultIntegerCrossover(string paramName, MultiEncoding config) {
|
---|
[10856] | 580 | var intXo = new Encodings.IntegerVectorEncoding.RoundedBlendAlphaBetaCrossover();
|
---|
| 581 | intXo.ChildParameter.ActualName = paramName;
|
---|
| 582 | intXo.ParentsParameter.ActualName = paramName;
|
---|
| 583 | intXo.BoundsParameter.ActualName = paramName + "Bounds";
|
---|
| 584 | intXo.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
|
---|
| 585 | intXo.MaximizationParameter.ActualName = MaximizationParameter.Name;
|
---|
| 586 | return intXo;
|
---|
| 587 | }
|
---|
| 588 |
|
---|
[11484] | 589 | protected virtual IIntegerVectorManipulator GetDefaultIntegerManipulator(string paramName, MultiEncoding configuration) {
|
---|
[10856] | 590 | var intM = new Encodings.IntegerVectorEncoding.UniformSomePositionsManipulator();
|
---|
| 591 | intM.IntegerVectorParameter.ActualName = paramName;
|
---|
| 592 | intM.BoundsParameter.ActualName = paramName + "Bounds";
|
---|
| 593 | intM.ProbabilityParameter.Value = new DoubleValue(0.1);
|
---|
| 594 | return intM;
|
---|
| 595 | }
|
---|
| 596 |
|
---|
[11484] | 597 | protected virtual IRealVectorCrossover GetDefaultRealCrossover(string paramName, MultiEncoding configuration) {
|
---|
[10856] | 598 | var realXo = new Encodings.RealVectorEncoding.BlendAlphaBetaCrossover();
|
---|
| 599 | realXo.ChildParameter.ActualName = paramName;
|
---|
| 600 | realXo.ParentsParameter.ActualName = paramName;
|
---|
| 601 | realXo.BoundsParameter.ActualName = paramName + "Bounds";
|
---|
| 602 | realXo.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
|
---|
| 603 | realXo.MaximizationParameter.ActualName = MaximizationParameter.Name;
|
---|
| 604 | return realXo;
|
---|
| 605 | }
|
---|
| 606 |
|
---|
[11484] | 607 | protected virtual IRealVectorManipulator GetDefaultRealManipulator(string paramName, MultiEncoding configuration) {
|
---|
[10856] | 608 | var realM = new Encodings.RealVectorEncoding.BreederGeneticAlgorithmManipulator();
|
---|
| 609 | realM.RealVectorParameter.ActualName = paramName;
|
---|
| 610 | realM.BoundsParameter.ActualName = paramName + "Bounds";
|
---|
| 611 | return realM;
|
---|
| 612 | }
|
---|
| 613 |
|
---|
[11484] | 614 | protected virtual IPermutationCrossover GetDefaultPermutationCrossover(string paramName, MultiEncoding configuration) {
|
---|
[10856] | 615 | var permXo = new Encodings.PermutationEncoding.PartiallyMatchedCrossover();
|
---|
| 616 | permXo.ChildParameter.ActualName = paramName;
|
---|
| 617 | permXo.ParentsParameter.ActualName = paramName;
|
---|
| 618 | return permXo;
|
---|
| 619 | }
|
---|
| 620 |
|
---|
[11484] | 621 | protected virtual IPermutationManipulator GetDefaultPermutationManipulator(string paramName, MultiEncoding configuration) {
|
---|
[10856] | 622 | var permM = new Encodings.PermutationEncoding.Swap2Manipulator();
|
---|
| 623 | permM.PermutationParameter.ActualName = paramName;
|
---|
| 624 | return permM;
|
---|
| 625 | }
|
---|
| 626 | // ReSharper restore RedundantNameQualifier
|
---|
[11398] | 627 | #endregion
|
---|
[10753] | 628 | }
|
---|
| 629 | }
|
---|