#region License Information /* HeuristicLab * Copyright (C) 2002-2011 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.Drawing; using System.Linq; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Encodings.IntegerVectorEncoding; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.PluginInfrastructure; namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment { [Item("Generalized Quadratic Assignment Problem", "The Generalized Quadratic Assignment Problem (GQAP) is a generalization of the QAP in that it allows to assign multiple facilities (here called equipment) to a single location. The problem is described in Lee, C.G., and Ma, Z. 2003. The Generalized Quadratic Assignment Problem. Technical Report M5S 3G8, University of Toronto, Canada.")] [Creatable("Problems")] [StorableClass] public sealed class GeneralizedQuadraticAssignmentProblem : SingleObjectiveHeuristicOptimizationProblem, IStorableContent { public override Image ItemImage { get { return HeuristicLab.Common.Resources.VSImageLibrary.Type; } } public string Filename { get; set; } #region Parameter Properties public ValueParameter WeightsParameter { get { return (ValueParameter)Parameters["Weights"]; } } public ValueParameter DistancesParameter { get { return (ValueParameter)Parameters["Distances"]; } } public ValueParameter InstallationCostsParameter { get { return (ValueParameter)Parameters["InstallationCosts"]; } } public FixedValueParameter TransportationCostsParameter { get { return (FixedValueParameter)Parameters["TransportationCosts"]; } } public ValueParameter DemandsParameter { get { return (ValueParameter)Parameters["Demands"]; } } public ValueParameter CapacitiesParameter { get { return (ValueParameter)Parameters["Capacities"]; } } public OptionalValueParameter BestKnownSolutionParameter { get { return (OptionalValueParameter)Parameters["BestKnownSolution"]; } } #endregion #region Properties public DoubleMatrix Weights { get { return WeightsParameter.Value; } set { WeightsParameter.Value = value; } } public DoubleMatrix Distances { get { return DistancesParameter.Value; } set { DistancesParameter.Value = value; } } public DoubleMatrix InstallationCosts { get { return InstallationCostsParameter.Value; } set { InstallationCostsParameter.Value = value; } } public double TransportationCosts { get { return TransportationCostsParameter.Value.Value; } set { TransportationCostsParameter.Value.Value = value; } } public DoubleArray Demands { get { return DemandsParameter.Value; } set { DemandsParameter.Value = value; } } public DoubleArray Capacities { get { return CapacitiesParameter.Value; } set { CapacitiesParameter.Value = value; } } #endregion [Storable] private BestGQAPSolutionAnalyzer bestSolutionAnalyzer; public BestGQAPSolutionAnalyzer BestSolutionAnalyzer { get { return bestSolutionAnalyzer; } set { bestSolutionAnalyzer = value; } } [StorableConstructor] private GeneralizedQuadraticAssignmentProblem(bool deserializing) : base(deserializing) { } private GeneralizedQuadraticAssignmentProblem(GeneralizedQuadraticAssignmentProblem original, Cloner cloner) : base(original, cloner) { bestSolutionAnalyzer = cloner.Clone(original.bestSolutionAnalyzer); AttachEventHandlers(); } public GeneralizedQuadraticAssignmentProblem() : base(new GQAPEvaluator(), new UniformRandomIntegerVectorCreator()) { Parameters.Add(new ValueParameter("Weights", "The weights matrix describes the flows between the equipments.", new DoubleMatrix())); Parameters.Add(new ValueParameter("Distances", "The distances matrix describes the distances between the locations at which the equipment can be installed.", new DoubleMatrix())); Parameters.Add(new ValueParameter("InstallationCosts", "The installation costs matrix describes the installation costs of installing equipment i at location j", new DoubleMatrix())); Parameters.Add(new FixedValueParameter("TransportationCosts", "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.", new DoubleValue(1))); Parameters.Add(new ValueParameter("Demands", "The demands vector describes the space requirements of the equipments.", new DoubleArray())); Parameters.Add(new ValueParameter("Capacities", "The capacities vector describes the available space at the locations.", new DoubleArray())); Parameters.Add(new OptionalValueParameter("BestKnownSolution", "The best known solution (if available)", null)); Parameters.Add(new OptionalValueParameter("EquipmentNames", "Optional: A list of names that describes the equipments.", null, false)); Parameters.Add(new OptionalValueParameter("LocationNames", "Optional: A list of names that describes the locations.", null, false)); WeightsParameter.ReactOnValueToStringChangedAndValueItemImageChanged = false; DistancesParameter.ReactOnValueToStringChangedAndValueItemImageChanged = false; InstallationCostsParameter.ReactOnValueToStringChangedAndValueItemImageChanged = false; Weights = new DoubleMatrix(5, 5); Weights[0, 0] = Weights[1, 1] = Weights[2, 2] = Weights[3, 3] = Weights[4, 4] = 0; Weights[0, 1] = Weights[1, 0] = Weights[0, 2] = Weights[2, 0] = Weights[0, 3] = Weights[3, 0] = Weights[0, 4] = Weights[4, 0] = 10; Weights[1, 2] = Weights[2, 1] = Weights[1, 3] = Weights[3, 1] = Weights[1, 4] = Weights[4, 1] = 5; Weights[2, 3] = Weights[3, 2] = Weights[2, 4] = Weights[4, 2] = 7.5; Weights[3, 4] = Weights[4, 3] = 2.5; Distances = new DoubleMatrix(3, 3); Distances[0, 0] = Distances[1, 1] = Distances[2, 2] = 0; Distances[0, 1] = Distances[1, 0] = Distances[1, 2] = Distances[2, 1] = 1; Distances[0, 2] = Distances[2, 0] = 2; InstallationCosts = new DoubleMatrix(5, 3); TransportationCosts = 1; Demands = new DoubleArray(5); Demands[0] = 2; Demands[1] = 1; Demands[2] = 3; Demands[3] = 1; Demands[4] = 1; Capacities = new DoubleArray(3); Capacities[0] = 4; Capacities[1] = 1; Capacities[2] = 4; Parameterize(); InitializeOperators(); AttachEventHandlers(); } public override IDeepCloneable Clone(Cloner cloner) { return new GeneralizedQuadraticAssignmentProblem(this, cloner); } #region Events protected override void OnOperatorsChanged() { base.OnOperatorsChanged(); Parameterize(); } protected override void OnEvaluatorChanged() { base.OnEvaluatorChanged(); Parameterize(); Evaluator.QualityParameter.ActualNameChanged += new System.EventHandler(Evaluator_QualityParameter_ActualNameChanged); } protected override void OnSolutionCreatorChanged() { base.OnSolutionCreatorChanged(); Parameterize(); SolutionCreator.IntegerVectorParameter.ActualNameChanged += new EventHandler(SolutionCreator_IntegerVectorParameter_ActualNameChanged); } private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) { Parameterize(); } private void SolutionCreator_IntegerVectorParameter_ActualNameChanged(object sender, EventArgs e) { Parameterize(); } #endregion #region Helpers [StorableHook(HookType.AfterDeserialization)] private void AfterDeserializationHook() { // BackwardsCompatibility3.3 #region Backwards compatible code, remove with 3.4 if (!Parameters.ContainsKey("EquipmentNames")) Parameters.Add(new OptionalValueParameter("EquipmentNames", "Optional: A list of names that describes the equipments.", null, false)); if (!Parameters.ContainsKey("LocationNames")) Parameters.Add(new OptionalValueParameter("LocationNames", "Optional: A list of names that describes the locations.", null, false)); #endregion AttachEventHandlers(); } private void AttachEventHandlers() { Evaluator.QualityParameter.ActualNameChanged += new System.EventHandler(Evaluator_QualityParameter_ActualNameChanged); SolutionCreator.IntegerVectorParameter.ActualNameChanged += new EventHandler(SolutionCreator_IntegerVectorParameter_ActualNameChanged); } private void InitializeOperators() { Operators.AddRange(ApplicationManager.Manager.GetInstances()); Operators.RemoveAll(x => x is ISingleObjectiveMoveEvaluator); Operators.Add(new BestGQAPSolutionAnalyzer()); Parameterize(); } private void Parameterize() { Evaluator.WeightsParameter.ActualName = WeightsParameter.Name; Evaluator.DistancesParameter.ActualName = DistancesParameter.Name; Evaluator.InstallationCostsParameter.ActualName = InstallationCostsParameter.Name; Evaluator.TransportationCostsParameter.ActualName = TransportationCostsParameter.Name; Evaluator.DemandsParameter.ActualName = DemandsParameter.Name; Evaluator.CapacitiesParameter.ActualName = CapacitiesParameter.Name; Evaluator.AssignmentParameter.ActualName = "Assignment"; SolutionCreator.LengthParameter.Value = new IntValue(Demands.Length); SolutionCreator.MinimumParameter.Value = new IntValue(0); SolutionCreator.MaximumParameter.Value = new IntValue(Capacities.Length); SolutionCreator.IntegerVectorParameter.ActualName = "Assignment"; foreach (IIntegerVectorCrossover op in Operators.OfType()) { op.ParentsParameter.ActualName = SolutionCreator.IntegerVectorParameter.ActualName; op.ChildParameter.ActualName = SolutionCreator.IntegerVectorParameter.ActualName; } foreach (IIntegerVectorManipulator op in Operators.OfType()) { op.IntegerVectorParameter.ActualName = SolutionCreator.IntegerVectorParameter.ActualName; } if (BestSolutionAnalyzer != null) { BestSolutionAnalyzer.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName; BestSolutionAnalyzer.DistancesParameter.ActualName = DistancesParameter.Name; BestSolutionAnalyzer.WeightsParameter.ActualName = WeightsParameter.Name; BestSolutionAnalyzer.AssignmentParameter.ActualName = SolutionCreator.IntegerVectorParameter.ActualName; BestSolutionAnalyzer.ResultsParameter.ActualName = "Results"; BestSolutionAnalyzer.BestKnownQualityParameter.ActualName = BestKnownQualityParameter.Name; BestSolutionAnalyzer.MaximizationParameter.ActualName = MaximizationParameter.Name; } } #endregion } }