Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
12/20/17 23:35:23 (7 years ago)
Author:
abeham
Message:

#1614: finished checking the implementation against the paper

Location:
branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/GQAPPathRelinking.cs

    r15553 r15555  
    3232
    3333namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
     34  /// <summary>
     35  /// 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
     36  /// </summary>
    3437  [Item("GQAPPathRelinking", "Operator that performs path relinking between two solutions. It 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.")]
    3538  [StorableClass]
     
    7174      var cmp = new IntegerVectorEqualityComparer();
    7275
     76      var greedy = true; // greedy performed better according to the paper
    7377      var sFit = problemInstance.ToSingleObjective(sourceEval);
    7478      var tFit = problemInstance.ToSingleObjective(targetEval);
     
    114118        }
    115119        if (B.Count > 0) { // line 21 of Algorithm 4
    116           var pi = B.SampleProportional(random, 1, B_fit.Select(x => 1.0 / x), false).First(); // line 22 of Algorithm 4
     120          GQAPSolution pi;
     121          // line 22 of Algorithm 4
     122          if (greedy) {
     123            pi = B.Select((val, idx) => new { Index = idx, Value = val }).MinItems(x => B_fit[x.Index]).Shuffle(random).First().Value;
     124          } else {
     125            pi = B.SampleProportional(random, 1, B_fit.Select(x => 1.0 / x), false).First();
     126          }
    117127          var diff = IntegerVectorEqualityComparer.GetDifferingIndices(pi.Assignment, target); // line 23 of Algorithm 4
    118128          var I = phi.Except(diff); // line 24 of Algorithm 4
     
    126136            pi_star = pi; // line 30 of Algorithm 4
    127137          }
    128         } else return pi_star ?? new GQAPSolution((IntegerVector)source.Clone(), (Evaluation)sourceEval.Clone());
     138        } else return pi_star;
    129139        phi = new HashSet<int>(IntegerVectorEqualityComparer.GetDifferingIndices(pi_prime, target));
    130140      }
    131141
    132       return pi_star ?? new GQAPSolution((IntegerVector)source.Clone(), (Evaluation)sourceEval.Clone());
     142      return pi_star;
    133143    }
    134144
  • branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/LocalImprovers/ApproximateLocalSearch.cs

    r15553 r15555  
    3131using HeuristicLab.Parameters;
    3232using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     33using HeuristicLab.Random;
    3334
    3435namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
     36  /// <summary>
     37  /// 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
     38  /// </summary>
    3539  [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.")]
    3640  [StorableClass]
     
    105109
    106110      /// <summary>
    107       /// The implementation differs slightly from Mateus et al. in that the maximumIterations parameter defines a cap
    108       /// on the number of steps that the local search can perform. While the maxSampleSize parameter corresponds to
    109       /// the maxItr parameter defined by Mateus et al.
    110111      /// </summary>
    111112      /// <param name="random">The random number generator to use.</param>
     
    127128      var evaluations = 0.0;
    128129      var deltaEvaluationFactor = 1.0 / assignment.Length;
    129       while (true) {
    130         int count = 0;
    131         var CLS = new List<Tuple<NMove, double, Evaluation>>();
    132         double sum = 0.0;
     130      var greedy = true; // greedy selection performed better in 5 of 8 instances according to the paper
     131      while (true) { // line 1 of Algorithm 3
     132        var count = 0; // line 2 of Algorithm 3
     133        var CLS = new List<Tuple<NMove, double, Evaluation>>(); // line 3 of Algorithm 3
    133134        do {
    134           NMove move;
    135           if (random.NextDouble() < oneMoveProbability)
    136             move = StochasticNMoveSingleMoveGenerator.GenerateOneMove(random, assignment, capacities);
    137           else move = StochasticNMoveSingleMoveGenerator.GenerateTwoMove(random, assignment, capacities);
    138          
     135          var move = Move(random, assignment, oneMoveProbability, capacities); // line 4 of Algorithm 3
     136
    139137          var moveEval = GQAPNMoveEvaluator.Evaluate(move, assignment, evaluation, problemInstance);
    140138          evaluations += move.Indices.Count * deltaEvaluationFactor;
    141139          double moveQuality = problemInstance.ToSingleObjective(moveEval);
    142140
    143           if (moveEval.ExcessDemand <= 0.0 && moveQuality < quality) {
    144             CLS.Add(Tuple.Create(move, moveQuality, moveEval));
    145             sum += 1.0 / moveQuality;
     141          if (moveEval.ExcessDemand <= 0.0 && moveQuality < quality) { // line 5 of Algorithm 3
     142            CLS.Add(Tuple.Create(move, moveQuality, moveEval)); // line 6 of Algorithm 3
    146143          }
    147           count++;
    148         } while (CLS.Count < maxCLS && count < maximumIterations);
     144          count++; // line 8 of Algorithm 3
     145        } while (CLS.Count < maxCLS && count < maximumIterations); // line 9 of Algorithm 3
    149146
    150         if (CLS.Count == 0) {
     147        if (CLS.Count == 0) { // line 10 of Algorithm 3
    151148          evaluatedSolutions += (int)Math.Ceiling(evaluations);
    152149          return; // END
    153150        } else {
    154           var ball = random.NextDouble() * sum;
    155           var selected = CLS.Last();
    156           foreach (var candidate in CLS) {
    157             ball -= 1.0 / candidate.Item2;
    158             if (ball <= 0.0) {
    159               selected = candidate;
    160               break;
    161             }
     151          // line 11 of Algorithm 3
     152          Tuple<NMove, double, Evaluation> selected;
     153          if (greedy) {
     154            selected = CLS.MinItems(x => x.Item2).Shuffle(random).First();
     155          } else {
     156            selected = CLS.SampleProportional(random, 1, CLS.Select(x => 1.0 / x.Item2), false, false).Single();
    162157          }
    163158          NMoveMaker.Apply(assignment, selected.Item1);
     
    166161        }
    167162      }
     163    }
     164
     165    private static NMove Move(IRandom random, IntegerVector assignment, double oneMoveProbability, DoubleArray capacities) {
     166      if (random.NextDouble() < oneMoveProbability)
     167        return StochasticNMoveSingleMoveGenerator.GenerateOneMove(random, assignment, capacities);
     168      return StochasticNMoveSingleMoveGenerator.GenerateTwoMove(random, assignment, capacities);
    168169    }
    169170
Note: See TracChangeset for help on using the changeset viewer.