#region License Information
/* HeuristicLab
* Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using HeuristicLab.Common;
using HeuristicLab.Core;
using HeuristicLab.Data;
using HeuristicLab.Encodings.IntegerVectorEncoding;
using HeuristicLab.Operators;
using HeuristicLab.Optimization;
using HeuristicLab.Parameters;
using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment.Operators {
[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.")]
[StorableClass]
public class ApproximateLocalSearch : SingleSuccessorOperator, IDemandsAwareGQAPOperator, ICapacitiesAwareGQAPOperator,
IWeightsAwareGQAPOperator, IDistancesAwareGQAPOperator, IInstallationCostsAwareGQAPOperator,
ITransportationCostsAwareGQAPOperator, IExpectedRandomQualityAwareGQAPOperator,
IAssignmentAwareGQAPOperator, IQualityAwareGQAPOperator, IGQAPLocalImprovementOperator,
IEvaluatorAwareGQAPOperator, IStochasticOperator {
public IProblem Problem { get; set; }
public Type ProblemType {
get { return typeof(GeneralizedQuadraticAssignmentProblem); }
}
public ILookupParameter DemandsParameter {
get { return (ILookupParameter)Parameters["Demands"]; }
}
public ILookupParameter CapacitiesParameter {
get { return (ILookupParameter)Parameters["Capacities"]; }
}
public ILookupParameter WeightsParameter {
get { return (ILookupParameter)Parameters["Weights"]; }
}
public ILookupParameter DistancesParameter {
get { return (ILookupParameter)Parameters["Distances"]; }
}
public ILookupParameter InstallationCostsParameter {
get { return (ILookupParameter)Parameters["InstallationCosts"]; }
}
public IValueLookupParameter TransportationCostsParameter {
get { return (IValueLookupParameter)Parameters["TransportationCosts"]; }
}
public IValueLookupParameter ExpectedRandomQualityParameter {
get { return (IValueLookupParameter)Parameters["ExpectedRandomQuality"]; }
}
public ILookupParameter AssignmentParameter {
get { return (ILookupParameter)Parameters["Assignment"]; }
}
public ILookupParameter MaximizationParameter {
get { return (ILookupParameter)Parameters["Maximization"]; }
}
public ILookupParameter QualityParameter {
get { return (ILookupParameter)Parameters["Quality"]; }
}
public ILookupParameter FlowDistanceQualityParameter {
get { return (ILookupParameter)Parameters["FlowDistanceQuality"]; }
}
public ILookupParameter InstallationQualityParameter {
get { return (ILookupParameter)Parameters["InstallationQuality"]; }
}
public ILookupParameter OverbookedCapacityParameter {
get { return (ILookupParameter)Parameters["OverbookedCapacity"]; }
}
public IValueLookupParameter MaximumIterationsParameter {
get { return (IValueLookupParameter)Parameters["MaximumIterations"]; }
}
public ILookupParameter EvaluatedSolutionsParameter {
get { return (ILookupParameter)Parameters["EvaluatedSolutions"]; }
}
public ILookupParameter RandomParameter {
get { return (ILookupParameter)Parameters["Random"]; }
}
public IValueLookupParameter MaximumCandidateListSizeParameter {
get { return (IValueLookupParameter)Parameters["MaximumCandidateListSize"]; }
}
public IValueLookupParameter OneMoveProbabilityParameter {
get { return (IValueLookupParameter)Parameters["OneMoveProbability"]; }
}
public ILookupParameter ResultsParameter {
get { return (ILookupParameter)Parameters["Results"]; }
}
public IValueLookupParameter EvaluatorParameter {
get { return (IValueLookupParameter)Parameters["Evaluator"]; }
}
[StorableConstructor]
protected ApproximateLocalSearch(bool deserializing) : base(deserializing) { }
protected ApproximateLocalSearch(ApproximateLocalSearch original, Cloner cloner) : base(original, cloner) { }
public ApproximateLocalSearch()
: base() {
Parameters.Add(new LookupParameter("Demands", GeneralizedQuadraticAssignmentProblem.DemandsDescription));
Parameters.Add(new LookupParameter("Capacities", GeneralizedQuadraticAssignmentProblem.CapacitiesDescription));
Parameters.Add(new LookupParameter("Weights", GeneralizedQuadraticAssignmentProblem.WeightsDescription));
Parameters.Add(new LookupParameter("Distances", GeneralizedQuadraticAssignmentProblem.DistancesDescription));
Parameters.Add(new LookupParameter("InstallationCosts", GeneralizedQuadraticAssignmentProblem.InstallationCostsDescription));
Parameters.Add(new ValueLookupParameter("TransportationCosts", GeneralizedQuadraticAssignmentProblem.TransportationCostsDescription));
Parameters.Add(new ValueLookupParameter("ExpectedRandomQuality", GeneralizedQuadraticAssignmentProblem.ExpectedRandomQualityDescription));
Parameters.Add(new LookupParameter("Assignment", GQAPSolutionCreator.AssignmentDescription));
Parameters.Add(new LookupParameter("Maximization", GeneralizedQuadraticAssignmentProblem.MaximizationDescription));
Parameters.Add(new LookupParameter("Quality", GQAPEvaluator.QualityDescription));
Parameters.Add(new LookupParameter("FlowDistanceQuality", GQAPEvaluator.FlowDistanceQualityDescription));
Parameters.Add(new LookupParameter("InstallationQuality", GQAPEvaluator.InstallationQualityDescription));
Parameters.Add(new LookupParameter("OverbookedCapacity", GQAPEvaluator.OverbookedCapacityDescription));
Parameters.Add(new ValueLookupParameter("MaximumIterations", "The maximum number of iterations that should be performed."));
Parameters.Add(new LookupParameter("EvaluatedSolutions", "The number of evaluated solution equivalents."));
Parameters.Add(new LookupParameter("Random", "The random number generator to use."));
Parameters.Add(new ValueLookupParameter("MaximumCandidateListSize", "The maximum number of candidates that should be found in each step.", new IntValue(10)));
Parameters.Add(new ValueLookupParameter("OneMoveProbability", "The probability for performing a 1-move, which is the opposite of performing a 2-move.", new PercentValue(.5)));
Parameters.Add(new LookupParameter("Results", "The result collection that stores the results."));
Parameters.Add(new ValueLookupParameter("Evaluator", "The evaluator that is used to evaluate GQAP solutions."));
}
public override IDeepCloneable Clone(Cloner cloner) {
return new ApproximateLocalSearch(this, cloner);
}
///
/// The implementation differs slightly from Mateus et al. in that the maximumIterations parameter defines a cap
/// on the number of steps that the local search can perform. While the maxSampleSize parameter corresponds to
/// the maxItr parameter defined by Mateus et al.
///
/// The random number generator to use.
/// The equipment-location assignment vector.
/// The solution quality.
/// The quality regarding the flow-distance criteria.
/// The quality regarding the installation costs.
/// The sum of the overbooked capacities relative to the capacity of each location.
/// The maximum number of candidates that should be found in each step.
/// The maximum number of iterations that should be performed each time the candidate list is generated.
/// The weights matrix describes the flows between the equipments.
/// The distances matrix describes the distances between the locations at which the equipment can be installed.
/// The installation costs matrix describes the installation costs of installing equipment i at location j
/// The demands vector describes the space requirements of the equipments.
/// The capacities vector describes the available space at the locations.
/// The transportation cost represents the flow-unit per distance-unit cost factor. This value can also be set to 1 if these costs are factored into the weights matrix already.
///
/// The probability for performing a 1-move, which is the opposite of performing a 2-move.
public static void Apply(IRandom random, IntegerVector assignment,
DoubleValue quality, DoubleValue flowDistanceQuality, DoubleValue installationQuality, DoubleValue overbookedCapacity,
IntValue maxCLS, IntValue maximumIterations,
DoubleMatrix weights, DoubleMatrix distances, DoubleMatrix installationCosts, DoubleArray demands, DoubleArray capacities,
DoubleValue transportationCosts, DoubleValue expectedRandomQuality, PercentValue oneMoveProbability,
IGQAPEvaluator evaluator) {
while (true) {
int count = 0;
var CLS = new List>();
double sum = 0.0;
do {
NMove move;
if (random.NextDouble() < oneMoveProbability.Value)
move = StochasticNMoveSingleMoveGenerator.GenerateExactlyN(random, assignment, 1, capacities);
else move = StochasticNMoveSingleMoveGenerator.GenerateExactlyN(random, assignment, 2, capacities);
double moveFlowDistanceQuality, moveInstallationQuality, moveOverbookedCapacity;
GQAPNMoveEvaluator.Evaluate(move, assignment, weights, distances, installationCosts,
demands, capacities, evaluator, out moveFlowDistanceQuality, out moveInstallationQuality, out moveOverbookedCapacity);
double moveQuality = evaluator.GetFitness(moveFlowDistanceQuality, moveInstallationQuality, moveOverbookedCapacity,
transportationCosts.Value, expectedRandomQuality.Value);
if (moveOverbookedCapacity <= 0.0 && moveQuality < 0.0) {
CLS.Add(Tuple.Create(move, moveQuality, moveFlowDistanceQuality, moveInstallationQuality, moveOverbookedCapacity));
sum += 1.0 / moveQuality;
}
count++;
} while (CLS.Count < maxCLS.Value && count < maximumIterations.Value);
if (CLS.Count == 0)
return; // END
else {
var ball = random.NextDouble() * sum;
var selected = CLS.Last();
foreach (var candidate in CLS) {
ball -= 1.0 / candidate.Item2;
if (ball <= 0.0) {
selected = candidate;
break;
}
}
NMoveMaker.Apply(assignment, selected.Item1);
quality.Value += selected.Item2;
flowDistanceQuality.Value += selected.Item3;
installationQuality.Value += selected.Item4;
overbookedCapacity.Value += selected.Item5;
}
}
}
public override IOperation Apply() {
Apply(RandomParameter.ActualValue,
AssignmentParameter.ActualValue,
QualityParameter.ActualValue,
FlowDistanceQualityParameter.ActualValue,
InstallationQualityParameter.ActualValue,
OverbookedCapacityParameter.ActualValue,
MaximumCandidateListSizeParameter.ActualValue,
MaximumIterationsParameter.ActualValue,
WeightsParameter.ActualValue, DistancesParameter.ActualValue,
InstallationCostsParameter.ActualValue,
DemandsParameter.ActualValue, CapacitiesParameter.ActualValue,
TransportationCostsParameter.ActualValue,
ExpectedRandomQualityParameter.ActualValue,
OneMoveProbabilityParameter.ActualValue,
EvaluatorParameter.ActualValue);
return base.Apply();
}
}
}