1  #region License Information


2  /* HeuristicLab


3  * Copyright (C) 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 HEAL.Attic;


23  using HeuristicLab.Common;


24  using HeuristicLab.Core;


25  using HeuristicLab.Data;


26  using HeuristicLab.Operators;


27  using HeuristicLab.Optimization;


28  using HeuristicLab.Parameters;


29  using HeuristicLab.Problems.VehicleRouting.Interfaces;


30  using HeuristicLab.Problems.VehicleRouting.ProblemInstances;


31  using HeuristicLab.Problems.VehicleRouting.Variants;


32 


33  namespace HeuristicLab.Problems.VehicleRouting {


34  /// <summary>


35  /// An operator for adaptive constraint relaxation.


36  /// </summary>


37  [Item("PickupViolationsRelaxationVRPAnalyzer", "An operator for adaptively relaxing the pickup constraints.")]


38  [StorableType("86D541AB5E65432BA8C4F012A6B46275")]


39  public class PickupViolationsRelaxationVRPAnalyzer : SingleSuccessorOperator, IAnalyzer, IPickupAndDeliveryOperator, ISingleObjectiveOperator {


40  public ILookupParameter<IVRPProblemInstance> ProblemInstanceParameter {


41  get { return (ILookupParameter<IVRPProblemInstance>)Parameters["ProblemInstance"]; }


42  }


43  public ScopeTreeLookupParameter<IVRPEncodedSolution> VRPToursParameter {


44  get { return (ScopeTreeLookupParameter<IVRPEncodedSolution>)Parameters["VRPTours"]; }


45  }


46  public ScopeTreeLookupParameter<CVRPPDTWEvaluation> EvaluationParameter {


47  get { return (ScopeTreeLookupParameter<CVRPPDTWEvaluation>)Parameters["EvaluationResult"]; }


48  }


49 


50  public IValueParameter<DoubleValue> SigmaParameter {


51  get { return (IValueParameter<DoubleValue>)Parameters["Sigma"]; }


52  }


53  public IValueParameter<DoubleValue> PhiParameter {


54  get { return (IValueParameter<DoubleValue>)Parameters["Phi"]; }


55  }


56  public IValueParameter<DoubleValue> MinPenaltyFactorParameter {


57  get { return (IValueParameter<DoubleValue>)Parameters["MinPenaltyFactor"]; }


58  }


59  public IValueParameter<DoubleValue> MaxPenaltyFactorParameter {


60  get { return (IValueParameter<DoubleValue>)Parameters["MaxPenaltyFactor"]; }


61  }


62 


63  public ValueLookupParameter<ResultCollection> ResultsParameter {


64  get { return (ValueLookupParameter<ResultCollection>)Parameters["Results"]; }


65  }


66 


67  public bool EnabledByDefault {


68  get { return false; }


69  }


70 


71  [StorableConstructor]


72  protected PickupViolationsRelaxationVRPAnalyzer(StorableConstructorFlag _) : base(_) { }


73 


74  public PickupViolationsRelaxationVRPAnalyzer()


75  : base() {


76  Parameters.Add(new LookupParameter<IVRPProblemInstance>("ProblemInstance", "The problem instance."));


77  Parameters.Add(new ScopeTreeLookupParameter<IVRPEncodedSolution>("VRPTours", "The VRP tours which should be evaluated."));


78  Parameters.Add(new ScopeTreeLookupParameter<CVRPPDTWEvaluation>("EvaluationResult", "The evaluations of the VRP solutions which should be analyzed."));


79 


80  Parameters.Add(new ValueParameter<DoubleValue>("Sigma", "The sigma applied to the penalty factor.", new DoubleValue(0.5)));


81  Parameters.Add(new ValueParameter<DoubleValue>("Phi", "The phi applied to the penalty factor.", new DoubleValue(0.5)));


82  Parameters.Add(new ValueParameter<DoubleValue>("MinPenaltyFactor", "The minimum penalty factor.", new DoubleValue(0.01)));


83  Parameters.Add(new ValueParameter<DoubleValue>("MaxPenaltyFactor", "The maximum penalty factor.", new DoubleValue(100000)));


84 


85  Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The result collection where the best VRP solution should be stored."));


86  }


87 


88  public override IDeepCloneable Clone(Cloner cloner) {


89  return new PickupViolationsRelaxationVRPAnalyzer(this, cloner);


90  }


91 


92  protected PickupViolationsRelaxationVRPAnalyzer(PickupViolationsRelaxationVRPAnalyzer original, Cloner cloner)


93  : base(original, cloner) {


94  }


95 


96  [StorableHook(HookType.AfterDeserialization)]


97  private void AfterDeserialization() {


98  // BackwardsCompatibility3.3


99  #region Backwards compatible code, remove with 3.4


100  if (!Parameters.ContainsKey("MaxPenaltyFactor")) {


101  Parameters.Add(new ValueParameter<DoubleValue>("MaxPenaltyFactor", "The maximum penalty factor.", new DoubleValue(100000)));


102  }


103  #endregion


104  }


105 


106  public override IOperation Apply() {


107  IPickupAndDeliveryProblemInstance pdp = ProblemInstanceParameter.ActualValue as IPickupAndDeliveryProblemInstance;


108  ResultCollection results = ResultsParameter.ActualValue;


109 


110  ItemArray<CVRPPDTWEvaluation> evaluations = EvaluationParameter.ActualValue;


111 


112  double sigma = SigmaParameter.Value.Value;


113  double phi = PhiParameter.Value.Value;


114  double minPenalty = MinPenaltyFactorParameter.Value.Value;


115  double maxPenalty = MaxPenaltyFactorParameter.Value.Value;


116 


117  for (int j = 0; j < evaluations.Length; j++) {


118  evaluations[j].Quality = evaluations[j].PickupViolations * pdp.PickupViolationPenalty.Value;


119  }


120 


121  int validCount = 0;


122  for (int j = 0; j < evaluations.Length; j++) {


123  if (evaluations[j].PickupViolations == 0)


124  validCount++;


125  }


126 


127  double factor = 1.0  ((double)validCount / (double)evaluations.Length);


128 


129  double min = pdp.PickupViolationPenalty.Value / (1 + sigma);


130  double max = pdp.PickupViolationPenalty.Value * (1 + phi);


131 


132  pdp.CurrentPickupViolationPenalty = new DoubleValue(min + (max  min) * factor);


133  if (pdp.CurrentPickupViolationPenalty.Value < minPenalty)


134  pdp.CurrentPickupViolationPenalty.Value = minPenalty;


135  if (pdp.CurrentPickupViolationPenalty.Value > maxPenalty)


136  pdp.CurrentPickupViolationPenalty.Value = maxPenalty;


137 


138  for (int j = 0; j < evaluations.Length; j++) {


139  evaluations[j].Quality += evaluations[j].PickupViolations * pdp.CurrentPickupViolationPenalty.Value;


140  }


141 


142  if (!results.TryGetValue("Current Pickup Violation Penalty", out IResult res)  !(res.Value is DoubleValue)) {


143  results.AddOrUpdateResult("Current Pickup Violation Penalty", new DoubleValue(pdp.CurrentPickupViolationPenalty.Value));


144  } else {


145  (res.Value as DoubleValue).Value = pdp.CurrentPickupViolationPenalty.Value;


146  }


147 


148  return base.Apply();


149  }


150  }


151  }

