Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2936_GQAPIntegration/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/LocalImprovers/ApproximateLocalSearch.cs @ 16712

Last change on this file since 16712 was 16712, checked in by gkronber, 5 years ago

#2936: adapted branch to new persistence (works with HL trunk r16711)

File size: 10.4 KB
RevLine 
[7407]1#region License Information
2/* HeuristicLab
[16077]3 * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[7407]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
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Encodings.IntegerVectorEncoding;
29using HeuristicLab.Operators;
30using HeuristicLab.Optimization;
31using HeuristicLab.Parameters;
32using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
[15555]33using HeuristicLab.Random;
[16712]34using HEAL.Attic;
[7407]35
[15512]36namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
[15555]37  /// <summary>
38  /// This is an implementation of the algorithm described in Mateus, G.R., Resende, M.G.C. & Silva, R.M.A. J Heuristics (2011) 17: 527. https://doi.org/10.1007/s10732-010-9144-0
39  /// </summary>
[7419]40  [Item("ApproximateLocalSearch", "The approximate local search is described in Mateus, G., Resende, M., and Silva, R. 2011. GRASP with path-relinking for the generalized quadratic assignment problem. Journal of Heuristics 17, Springer Netherlands, pp. 527-565.")]
[16712]41  [StorableType("58C75FBC-C586-4048-A60B-DCF967CB2E33")]
[15504]42  public class ApproximateLocalSearch : SingleSuccessorOperator, IProblemInstanceAwareGQAPOperator,
[15506]43    IQualityAwareGQAPOperator, IGQAPLocalImprovementOperator, IAssignmentAwareGQAPOperator, IStochasticOperator {
[7407]44    public IProblem Problem { get; set; }
45    public Type ProblemType {
[15504]46      get { return typeof(GQAP); }
[7407]47    }
48
[15504]49    public ILookupParameter<GQAPInstance> ProblemInstanceParameter {
50      get { return (ILookupParameter<GQAPInstance>)Parameters["ProblemInstance"]; }
[7407]51    }
[7419]52    public ILookupParameter<IntegerVector> AssignmentParameter {
53      get { return (ILookupParameter<IntegerVector>)Parameters["Assignment"]; }
54    }
[7407]55    public ILookupParameter<DoubleValue> QualityParameter {
56      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
57    }
[15504]58    public ILookupParameter<Evaluation> EvaluationParameter {
59      get { return (ILookupParameter<Evaluation>)Parameters["Evaluation"]; }
[7407]60    }
[7419]61    public IValueLookupParameter<IntValue> MaximumIterationsParameter {
62      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumIterations"]; }
[7407]63    }
[7419]64    public ILookupParameter<IntValue> EvaluatedSolutionsParameter {
65      get { return (ILookupParameter<IntValue>)Parameters["EvaluatedSolutions"]; }
66    }
67    public ILookupParameter<IRandom> RandomParameter {
68      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
69    }
[7407]70    public IValueLookupParameter<IntValue> MaximumCandidateListSizeParameter {
71      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumCandidateListSize"]; }
72    }
[7412]73    public IValueLookupParameter<PercentValue> OneMoveProbabilityParameter {
74      get { return (IValueLookupParameter<PercentValue>)Parameters["OneMoveProbability"]; }
75    }
[7419]76    public ILookupParameter<ResultCollection> ResultsParameter {
77      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
78    }
[15558]79    public IValueLookupParameter<BoolValue> GreedyParameter {
80      get { return (IValueLookupParameter<BoolValue>)Parameters["Greedy"]; }
81    }
[7407]82
83    [StorableConstructor]
[16712]84    protected ApproximateLocalSearch(StorableConstructorFlag _) : base(_) { }
[7407]85    protected ApproximateLocalSearch(ApproximateLocalSearch original, Cloner cloner) : base(original, cloner) { }
86    public ApproximateLocalSearch()
87      : base() {
[15504]88      Parameters.Add(new LookupParameter<GQAPInstance>("ProblemInstance", GQAP.ProblemInstanceDescription));
[7419]89      Parameters.Add(new LookupParameter<IntegerVector>("Assignment", GQAPSolutionCreator.AssignmentDescription));
[15504]90      Parameters.Add(new LookupParameter<DoubleValue>("Quality", ""));
91      Parameters.Add(new LookupParameter<Evaluation>("Evaluation", GQAP.EvaluationDescription));
[7407]92      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumIterations", "The maximum number of iterations that should be performed."));
93      Parameters.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The number of evaluated solution equivalents."));
[7419]94      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
[7407]95      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumCandidateListSize", "The maximum number of candidates that should be found in each step.", new IntValue(10)));
[7412]96      Parameters.Add(new ValueLookupParameter<PercentValue>("OneMoveProbability", "The probability for performing a 1-move, which is the opposite of performing a 2-move.", new PercentValue(.5)));
[7419]97      Parameters.Add(new LookupParameter<ResultCollection>("Results", "The result collection that stores the results."));
[15558]98      Parameters.Add(new ValueLookupParameter<BoolValue>("Greedy", "Whether to use a greedy selection strategy or a probabilistic one.", new BoolValue(true)));
[7407]99    }
100
101    public override IDeepCloneable Clone(Cloner cloner) {
102      return new ApproximateLocalSearch(this, cloner);
103    }
104
[15553]105    public static void Apply(IRandom random, GQAPSolution sol, int maxCLS,
106      double oneMoveProbability, int maximumIterations,
[15558]107      GQAPInstance problemInstance, out int evaluatedSolutions, bool greedy = true) {
[15553]108      var fit = problemInstance.ToSingleObjective(sol.Evaluation);
109      var eval = sol.Evaluation;
110      Apply(random, sol.Assignment, ref fit, ref eval, maxCLS, oneMoveProbability, maximumIterations, problemInstance,
[15558]111        out evaluatedSolutions, greedy);
[15553]112      sol.Evaluation = eval;
113    }
114
[15558]115    /// <summary>
116    /// </summary>
117    /// <param name="random">The random number generator to use.</param>
118    /// <param name="assignment">The equipment-location assignment vector.</param>
119    /// <param name="quality">The solution quality.</param>
120    /// <param name="evaluation">The evaluation result of the solution.</param>
121    /// <param name="maxCLS">The maximum number of candidates that should be found in each step.</param>
122    /// <param name="oneMoveProbability">The probability for performing a 1-move, which is the opposite of performing a 2-move.</param>
123    /// <param name="maximumIterations">The maximum number of iterations that should be performed each time the candidate list is generated.</param>
124    /// <param name="problemInstance">The problem instance that contains the data.</param>
125    /// <param name="evaluatedSolutions">The number of evaluated solutions.</param>
126    /// <param name="greedy">Greedy selection performed better in 5 of 8 instances according to the paper</param>
127    public static void Apply(IRandom random, IntegerVector assignment,
[15553]128      ref double quality, ref Evaluation evaluation, int maxCLS,
129      double oneMoveProbability, int maximumIterations,
[15558]130      GQAPInstance problemInstance, out int evaluatedSolutions, bool greedy = true) {
[15553]131      evaluatedSolutions = 0;
[15504]132      var capacities = problemInstance.Capacities;
133      var demands = problemInstance.Demands;
[15507]134      var evaluations = 0.0;
135      var deltaEvaluationFactor = 1.0 / assignment.Length;
[15555]136      while (true) { // line 1 of Algorithm 3
137        var count = 0; // line 2 of Algorithm 3
138        var CLS = new List<Tuple<NMove, double, Evaluation>>(); // line 3 of Algorithm 3
[7407]139        do {
[15555]140          var move = Move(random, assignment, oneMoveProbability, capacities); // line 4 of Algorithm 3
141
[15504]142          var moveEval = GQAPNMoveEvaluator.Evaluate(move, assignment, evaluation, problemInstance);
[15511]143          evaluations += move.Indices.Count * deltaEvaluationFactor;
[15504]144          double moveQuality = problemInstance.ToSingleObjective(moveEval);
[7412]145
[15555]146          if (moveEval.ExcessDemand <= 0.0 && moveQuality < quality) { // line 5 of Algorithm 3
147            CLS.Add(Tuple.Create(move, moveQuality, moveEval)); // line 6 of Algorithm 3
[7407]148          }
[15555]149          count++; // line 8 of Algorithm 3
150        } while (CLS.Count < maxCLS && count < maximumIterations); // line 9 of Algorithm 3
[7412]151
[15555]152        if (CLS.Count == 0) { // line 10 of Algorithm 3
[15553]153          evaluatedSolutions += (int)Math.Ceiling(evaluations);
[7412]154          return; // END
[15507]155        } else {
[15555]156          // line 11 of Algorithm 3
157          Tuple<NMove, double, Evaluation> selected;
158          if (greedy) {
159            selected = CLS.MinItems(x => x.Item2).Shuffle(random).First();
160          } else {
161            selected = CLS.SampleProportional(random, 1, CLS.Select(x => 1.0 / x.Item2), false, false).Single();
[7407]162          }
163          NMoveMaker.Apply(assignment, selected.Item1);
[15553]164          quality = selected.Item2;
[15504]165          evaluation = selected.Item3;
[7407]166        }
167      }
168    }
169
[15555]170    private static NMove Move(IRandom random, IntegerVector assignment, double oneMoveProbability, DoubleArray capacities) {
171      if (random.NextDouble() < oneMoveProbability)
172        return StochasticNMoveSingleMoveGenerator.GenerateOneMove(random, assignment, capacities);
173      return StochasticNMoveSingleMoveGenerator.GenerateTwoMove(random, assignment, capacities);
174    }
175
[7407]176    public override IOperation Apply() {
[15504]177      var evaluation = EvaluationParameter.ActualValue;
[15553]178      var quality = QualityParameter.ActualValue;
179      var fit = quality.Value;
180      var evaluatedSolutions = 0;
181
[7407]182      Apply(RandomParameter.ActualValue,
183        AssignmentParameter.ActualValue,
[15553]184        ref fit,
[15504]185        ref evaluation,
[15553]186        MaximumCandidateListSizeParameter.ActualValue.Value,
187        OneMoveProbabilityParameter.ActualValue.Value,
188        MaximumIterationsParameter.ActualValue.Value,
[15504]189        ProblemInstanceParameter.ActualValue,
[15558]190        out evaluatedSolutions,
191        GreedyParameter.ActualValue.Value);
[15553]192
[15504]193      EvaluationParameter.ActualValue = evaluation;
[15553]194      quality.Value = fit;
195      EvaluatedSolutionsParameter.ActualValue.Value += evaluatedSolutions;
[7407]196      return base.Apply();
197    }
198  }
199}
Note: See TracBrowser for help on using the repository browser.