[6956] | 1 | #region License Information
|
---|
| 2 | /* HeuristicLab
|
---|
[7319] | 3 | * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
|
---|
[6956] | 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 |
|
---|
[7311] | 22 | using System;
|
---|
[6956] | 23 | using System.Drawing;
|
---|
| 24 | using System.Linq;
|
---|
[7970] | 25 | using HeuristicLab.Analysis.QualityAnalysis;
|
---|
[6956] | 26 | using HeuristicLab.Common;
|
---|
| 27 | using HeuristicLab.Core;
|
---|
| 28 | using HeuristicLab.Data;
|
---|
| 29 | using HeuristicLab.Encodings.IntegerVectorEncoding;
|
---|
| 30 | using HeuristicLab.Optimization;
|
---|
| 31 | using HeuristicLab.Parameters;
|
---|
| 32 | using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
|
---|
| 33 | using HeuristicLab.PluginInfrastructure;
|
---|
[7443] | 34 | using HeuristicLab.Problems.Instances;
|
---|
[6956] | 35 |
|
---|
| 36 | namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
|
---|
| 37 | [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.")]
|
---|
| 38 | [Creatable("Problems")]
|
---|
| 39 | [StorableClass]
|
---|
[7523] | 40 | public sealed class GeneralizedQuadraticAssignmentProblem : SingleObjectiveHeuristicOptimizationProblem<IGQAPEvaluator, IGQAPSolutionCreator>, IStorableContent,
|
---|
[7548] | 41 | IProblemInstanceConsumer<QAPData>,
|
---|
| 42 | IProblemInstanceConsumer<CTAPData>,
|
---|
| 43 | IProblemInstanceConsumer<TSPData>,
|
---|
| 44 | IProblemInstanceConsumer<ATSPData>,
|
---|
| 45 | IProblemInstanceConsumer<GQAPData> {
|
---|
[7419] | 46 |
|
---|
[6956] | 47 | public override Image ItemImage {
|
---|
| 48 | get { return HeuristicLab.Common.Resources.VSImageLibrary.Type; }
|
---|
| 49 | }
|
---|
| 50 |
|
---|
[7311] | 51 | public string Filename { get; set; }
|
---|
| 52 |
|
---|
[7419] | 53 | #region Parameter Descriptions
|
---|
| 54 | public static readonly string MaximizationDescription = "False if the fitness function should be minimized (default) or otherwise True if it should be maximized.";
|
---|
| 55 | public static readonly string WeightsDescription = "The weights matrix describes the flows between the equipments.";
|
---|
| 56 | public static readonly string DistancesDescription = "The distances matrix describes the distances between the locations at which the equipment can be installed.";
|
---|
| 57 | public static readonly string InstallationCostsDescription = "The installation costs matrix describes the installation costs of installing equipment i at location j";
|
---|
| 58 | public static readonly string DemandsDescription = "The demands vector describes the space requirements of the equipments.";
|
---|
| 59 | public static readonly string CapacitiesDescription = "The capacities vector describes the available space at the locations.";
|
---|
| 60 | public static readonly string TransportationCostsDescription = "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.";
|
---|
[7423] | 61 | public static readonly string BestKnownQualityDescription = "The best known quality (if available).";
|
---|
| 62 | public static readonly string BestKnownSolutionDescription = "The best known solution (if available).";
|
---|
[7438] | 63 | public static readonly string BestKnownSolutionsDescription = "Contains an archive of best-known solutions regarding flow-distance quality and installation quality.";
|
---|
[7419] | 64 | public static readonly string EquipmentNamesDescription = "Optional: A list of names that describes the equipments.";
|
---|
| 65 | public static readonly string LocationNamesDescription = "Optional: A list of names that describes the locations.";
|
---|
[7970] | 66 | public static readonly string ExpectedRandomQualityDescription = "The expected quality value of a random solution.";
|
---|
[7419] | 67 | #endregion
|
---|
| 68 |
|
---|
[6956] | 69 | #region Parameter Properties
|
---|
| 70 | public ValueParameter<DoubleMatrix> WeightsParameter {
|
---|
| 71 | get { return (ValueParameter<DoubleMatrix>)Parameters["Weights"]; }
|
---|
| 72 | }
|
---|
| 73 | public ValueParameter<DoubleMatrix> DistancesParameter {
|
---|
| 74 | get { return (ValueParameter<DoubleMatrix>)Parameters["Distances"]; }
|
---|
| 75 | }
|
---|
| 76 | public ValueParameter<DoubleMatrix> InstallationCostsParameter {
|
---|
| 77 | get { return (ValueParameter<DoubleMatrix>)Parameters["InstallationCosts"]; }
|
---|
| 78 | }
|
---|
| 79 | public ValueParameter<DoubleArray> DemandsParameter {
|
---|
| 80 | get { return (ValueParameter<DoubleArray>)Parameters["Demands"]; }
|
---|
| 81 | }
|
---|
| 82 | public ValueParameter<DoubleArray> CapacitiesParameter {
|
---|
| 83 | get { return (ValueParameter<DoubleArray>)Parameters["Capacities"]; }
|
---|
| 84 | }
|
---|
[7412] | 85 | public FixedValueParameter<DoubleValue> TransportationCostsParameter {
|
---|
| 86 | get { return (FixedValueParameter<DoubleValue>)Parameters["TransportationCosts"]; }
|
---|
| 87 | }
|
---|
[7970] | 88 | public FixedValueParameter<DoubleValue> ExpectedRandomQualityParameter {
|
---|
| 89 | get { return (FixedValueParameter<DoubleValue>)Parameters["ExpectedRandomQuality"]; }
|
---|
[7412] | 90 | }
|
---|
[7470] | 91 | public OptionalValueParameter<GQAPAssignment> BestKnownSolutionParameter {
|
---|
| 92 | get { return (OptionalValueParameter<GQAPAssignment>)Parameters["BestKnownSolution"]; }
|
---|
[6956] | 93 | }
|
---|
[7438] | 94 | public OptionalValueParameter<GQAPAssignmentArchive> BestKnownSolutionsParameter {
|
---|
| 95 | get { return (OptionalValueParameter<GQAPAssignmentArchive>)Parameters["BestKnownSolutions"]; }
|
---|
| 96 | }
|
---|
[7415] | 97 | public OptionalValueParameter<StringArray> EquipmentNamesParameter {
|
---|
| 98 | get { return (OptionalValueParameter<StringArray>)Parameters["EquipmentNames"]; }
|
---|
| 99 | }
|
---|
| 100 | public OptionalValueParameter<StringArray> LocationNamesParameter {
|
---|
| 101 | get { return (OptionalValueParameter<StringArray>)Parameters["LocationNames"]; }
|
---|
| 102 | }
|
---|
[6956] | 103 | #endregion
|
---|
| 104 |
|
---|
| 105 | #region Properties
|
---|
| 106 | public DoubleMatrix Weights {
|
---|
| 107 | get { return WeightsParameter.Value; }
|
---|
| 108 | set { WeightsParameter.Value = value; }
|
---|
| 109 | }
|
---|
| 110 | public DoubleMatrix Distances {
|
---|
| 111 | get { return DistancesParameter.Value; }
|
---|
| 112 | set { DistancesParameter.Value = value; }
|
---|
| 113 | }
|
---|
| 114 | public DoubleMatrix InstallationCosts {
|
---|
| 115 | get { return InstallationCostsParameter.Value; }
|
---|
| 116 | set { InstallationCostsParameter.Value = value; }
|
---|
| 117 | }
|
---|
| 118 | public DoubleArray Demands {
|
---|
| 119 | get { return DemandsParameter.Value; }
|
---|
| 120 | set { DemandsParameter.Value = value; }
|
---|
| 121 | }
|
---|
| 122 | public DoubleArray Capacities {
|
---|
| 123 | get { return CapacitiesParameter.Value; }
|
---|
| 124 | set { CapacitiesParameter.Value = value; }
|
---|
| 125 | }
|
---|
[7970] | 126 | public double TransportationCosts {
|
---|
| 127 | get { return TransportationCostsParameter.Value.Value; }
|
---|
| 128 | set { TransportationCostsParameter.Value.Value = value; }
|
---|
[7412] | 129 | }
|
---|
[7970] | 130 | public double ExpectedRandomQuality {
|
---|
| 131 | get { return ExpectedRandomQualityParameter.Value.Value; }
|
---|
| 132 | set { ExpectedRandomQualityParameter.Value.Value = value; }
|
---|
[7412] | 133 | }
|
---|
[7415] | 134 | public StringArray EquipmentNames {
|
---|
| 135 | get { return EquipmentNamesParameter.Value; }
|
---|
| 136 | set { EquipmentNamesParameter.Value = value; }
|
---|
| 137 | }
|
---|
| 138 | public StringArray LocationNames {
|
---|
| 139 | get { return LocationNamesParameter.Value; }
|
---|
| 140 | set { LocationNamesParameter.Value = value; }
|
---|
| 141 | }
|
---|
[7470] | 142 | public GQAPAssignment BestKnownSolution {
|
---|
[7443] | 143 | get { return BestKnownSolutionParameter.Value; }
|
---|
| 144 | set { BestKnownSolutionParameter.Value = value; }
|
---|
| 145 | }
|
---|
[7448] | 146 | public GQAPAssignmentArchive BestKnownSolutions {
|
---|
| 147 | get { return BestKnownSolutionsParameter.Value; }
|
---|
| 148 | set { BestKnownSolutionsParameter.Value = value; }
|
---|
| 149 | }
|
---|
[6956] | 150 | #endregion
|
---|
| 151 |
|
---|
| 152 | public BestGQAPSolutionAnalyzer BestSolutionAnalyzer {
|
---|
[7418] | 153 | get { return Operators.OfType<BestGQAPSolutionAnalyzer>().FirstOrDefault(); }
|
---|
[6956] | 154 | }
|
---|
[7418] | 155 | public GQAPSolutionArchiveAnalyzer SolutionArchiveAnalyzer {
|
---|
| 156 | get { return Operators.OfType<GQAPSolutionArchiveAnalyzer>().FirstOrDefault(); }
|
---|
| 157 | }
|
---|
[6956] | 158 |
|
---|
| 159 | [StorableConstructor]
|
---|
| 160 | private GeneralizedQuadraticAssignmentProblem(bool deserializing) : base(deserializing) { }
|
---|
| 161 | private GeneralizedQuadraticAssignmentProblem(GeneralizedQuadraticAssignmentProblem original, Cloner cloner)
|
---|
| 162 | : base(original, cloner) {
|
---|
[7432] | 163 | RegisterEventHandlers();
|
---|
[6956] | 164 | }
|
---|
| 165 | public GeneralizedQuadraticAssignmentProblem()
|
---|
[7970] | 166 | : base(new GQAPAdditivePenaltyEvaluator(), new RandomSolutionCreator()) {
|
---|
[7438] | 167 | Parameters.Add(new ValueParameter<DoubleMatrix>("Weights", WeightsDescription, new DoubleMatrix(), false));
|
---|
| 168 | Parameters.Add(new ValueParameter<DoubleMatrix>("Distances", DistancesDescription, new DoubleMatrix(), false));
|
---|
| 169 | Parameters.Add(new ValueParameter<DoubleMatrix>("InstallationCosts", InstallationCostsDescription, new DoubleMatrix(), false));
|
---|
[7419] | 170 | Parameters.Add(new FixedValueParameter<DoubleValue>("TransportationCosts", TransportationCostsDescription, new DoubleValue(1)));
|
---|
[7970] | 171 | Parameters.Add(new FixedValueParameter<DoubleValue>("ExpectedRandomQuality", ExpectedRandomQualityDescription, new DoubleValue(0), true));
|
---|
[7438] | 172 | Parameters.Add(new ValueParameter<DoubleArray>("Demands", DemandsDescription, new DoubleArray(), false));
|
---|
| 173 | Parameters.Add(new ValueParameter<DoubleArray>("Capacities", CapacitiesDescription, new DoubleArray(), false));
|
---|
[7480] | 174 | Parameters.Add(new OptionalValueParameter<GQAPAssignment>("BestKnownSolution", BestKnownSolutionDescription, null, false));
|
---|
[7438] | 175 | Parameters.Add(new OptionalValueParameter<GQAPAssignmentArchive>("BestKnownSolutions", BestKnownSolutionsDescription, null, false));
|
---|
[7419] | 176 | Parameters.Add(new OptionalValueParameter<StringArray>("EquipmentNames", EquipmentNamesDescription, null, false));
|
---|
| 177 | Parameters.Add(new OptionalValueParameter<StringArray>("LocationNames", LocationNamesDescription, null, false));
|
---|
[6956] | 178 |
|
---|
| 179 | WeightsParameter.ReactOnValueToStringChangedAndValueItemImageChanged = false;
|
---|
| 180 | DistancesParameter.ReactOnValueToStringChangedAndValueItemImageChanged = false;
|
---|
| 181 | InstallationCostsParameter.ReactOnValueToStringChangedAndValueItemImageChanged = false;
|
---|
[7471] | 182 | DemandsParameter.ReactOnValueToStringChangedAndValueItemImageChanged = false;
|
---|
| 183 | CapacitiesParameter.ReactOnValueToStringChangedAndValueItemImageChanged = false;
|
---|
[6956] | 184 |
|
---|
| 185 | Weights = new DoubleMatrix(5, 5);
|
---|
| 186 | Weights[0, 0] = Weights[1, 1] = Weights[2, 2] = Weights[3, 3] = Weights[4, 4] = 0;
|
---|
| 187 | 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;
|
---|
| 188 | Weights[1, 2] = Weights[2, 1] = Weights[1, 3] = Weights[3, 1] = Weights[1, 4] = Weights[4, 1] = 5;
|
---|
| 189 | Weights[2, 3] = Weights[3, 2] = Weights[2, 4] = Weights[4, 2] = 7.5;
|
---|
| 190 | Weights[3, 4] = Weights[4, 3] = 2.5;
|
---|
| 191 |
|
---|
| 192 | Distances = new DoubleMatrix(3, 3);
|
---|
| 193 | Distances[0, 0] = Distances[1, 1] = Distances[2, 2] = 0;
|
---|
| 194 | Distances[0, 1] = Distances[1, 0] = Distances[1, 2] = Distances[2, 1] = 1;
|
---|
| 195 | Distances[0, 2] = Distances[2, 0] = 2;
|
---|
| 196 |
|
---|
[7311] | 197 | InstallationCosts = new DoubleMatrix(5, 3);
|
---|
[6956] | 198 |
|
---|
| 199 | Demands = new DoubleArray(5);
|
---|
| 200 | Demands[0] = 2; Demands[1] = 1; Demands[2] = 3; Demands[3] = 1; Demands[4] = 1;
|
---|
| 201 |
|
---|
| 202 | Capacities = new DoubleArray(3);
|
---|
| 203 | Capacities[0] = 4; Capacities[1] = 1; Capacities[2] = 4;
|
---|
| 204 |
|
---|
[7373] | 205 | SolutionCreator.AssignmentParameter.ActualName = "Assignment";
|
---|
[6956] | 206 |
|
---|
| 207 | InitializeOperators();
|
---|
[7432] | 208 | RegisterEventHandlers();
|
---|
[6956] | 209 | }
|
---|
| 210 |
|
---|
| 211 | public override IDeepCloneable Clone(Cloner cloner) {
|
---|
| 212 | return new GeneralizedQuadraticAssignmentProblem(this, cloner);
|
---|
| 213 | }
|
---|
| 214 |
|
---|
[7548] | 215 | #region Problem Instance Loading
|
---|
| 216 | public void Load(QAPData data) {
|
---|
| 217 | Name = data.Name;
|
---|
| 218 | Description = data.Description;
|
---|
[7448] | 219 |
|
---|
[7548] | 220 | var weights = new DoubleMatrix(data.Weights);
|
---|
| 221 | var distances = new DoubleMatrix(data.Distances);
|
---|
| 222 | var installationCosts = new DoubleMatrix(weights.Rows, distances.Columns); // all zero
|
---|
| 223 | var capacities = new DoubleArray(Enumerable.Range(0, distances.Rows).Select(x => 1.0).ToArray());
|
---|
| 224 | var demands = new DoubleArray(Enumerable.Range(0, weights.Rows).Select(x => 1.0).ToArray());
|
---|
[7443] | 225 |
|
---|
[7548] | 226 | Load(demands, capacities, weights, distances, installationCosts, new DoubleValue(1));
|
---|
| 227 | EvaluateAndLoadAssignment(data.BestKnownAssignment);
|
---|
| 228 | }
|
---|
[7445] | 229 |
|
---|
[7548] | 230 | public void Load(CTAPData data) {
|
---|
| 231 | Name = data.Name;
|
---|
| 232 | Description = data.Description;
|
---|
| 233 |
|
---|
| 234 | var capacities = new DoubleArray(data.MemoryCapacities);
|
---|
| 235 | var demands = new DoubleArray(data.MemoryRequirements);
|
---|
| 236 | var weights = new DoubleMatrix(data.CommunicationCosts);
|
---|
| 237 | var installationCosts = new DoubleMatrix(data.ExecutionCosts.Transpose());
|
---|
| 238 | var distances = new DoubleMatrix(capacities.Length, capacities.Length);
|
---|
| 239 | for (int i = 0; i < capacities.Length - 1; i++)
|
---|
| 240 | for (int j = i + 1; j < capacities.Length; j++) {
|
---|
| 241 | distances[i, j] = 1;
|
---|
[7466] | 242 | }
|
---|
[7548] | 243 |
|
---|
| 244 | Load(demands, capacities, weights, distances, installationCosts, new DoubleValue(1));
|
---|
| 245 | EvaluateAndLoadAssignment(data.BestKnownAssignment);
|
---|
[7443] | 246 | }
|
---|
| 247 |
|
---|
[7548] | 248 | public void Load(TSPData data) {
|
---|
| 249 | if (data.Dimension > 1000)
|
---|
| 250 | throw new System.IO.InvalidDataException("Instances with more than 1000 cities are not supported.");
|
---|
[7448] | 251 |
|
---|
[7548] | 252 | Name = data.Name;
|
---|
| 253 | Description = data.Description;
|
---|
[7466] | 254 |
|
---|
[7548] | 255 | var capacities = new DoubleArray(data.Dimension);
|
---|
| 256 | var demands = new DoubleArray(data.Dimension);
|
---|
| 257 | for (int i = 0; i < data.Dimension; i++) {
|
---|
| 258 | capacities[i] = 1;
|
---|
| 259 | demands[i] = 1;
|
---|
| 260 | }
|
---|
| 261 | var installationCosts = new DoubleMatrix(data.Dimension, data.Dimension);
|
---|
| 262 | var weights = new DoubleMatrix(data.Dimension, data.Dimension);
|
---|
| 263 | for (int i = 0; i < data.Dimension; i++)
|
---|
| 264 | weights[i, (i + 1) % data.Dimension] = 1;
|
---|
| 265 | var distances = new DoubleMatrix(data.GetDistanceMatrix());
|
---|
[7466] | 266 |
|
---|
[7548] | 267 | Load(demands, capacities, weights, distances, installationCosts, new DoubleValue(1));
|
---|
| 268 | EvaluateAndLoadAssignment(data.BestKnownTour);
|
---|
| 269 | }
|
---|
| 270 |
|
---|
| 271 | public void Load(ATSPData data) {
|
---|
| 272 | Name = data.Name;
|
---|
| 273 | Description = data.Description;
|
---|
| 274 |
|
---|
| 275 | var capacities = new DoubleArray(data.Dimension);
|
---|
| 276 | var demands = new DoubleArray(data.Dimension);
|
---|
| 277 | for (int i = 0; i < data.Dimension; i++) {
|
---|
| 278 | capacities[i] = 1;
|
---|
| 279 | demands[i] = 1;
|
---|
[7466] | 280 | }
|
---|
[7548] | 281 | var installationCosts = new DoubleMatrix(data.Dimension, data.Dimension);
|
---|
| 282 | var weights = new DoubleMatrix(data.Dimension, data.Dimension);
|
---|
| 283 | for (int i = 0; i < data.Dimension; i++)
|
---|
| 284 | weights[i, (i + 1) % data.Dimension] = 1;
|
---|
| 285 | var distances = new DoubleMatrix(data.Distances);
|
---|
| 286 |
|
---|
| 287 | Load(demands, capacities, weights, distances, installationCosts, new DoubleValue(1));
|
---|
| 288 | EvaluateAndLoadAssignment(data.BestKnownTour);
|
---|
[7466] | 289 | }
|
---|
[7445] | 290 |
|
---|
[7548] | 291 | public void Load(GQAPData data) {
|
---|
| 292 | Name = data.Name;
|
---|
| 293 | Description = data.Description;
|
---|
[7470] | 294 |
|
---|
[7548] | 295 | var capacities = new DoubleArray(data.Capacities);
|
---|
| 296 | var demands = new DoubleArray(data.Demands);
|
---|
| 297 | var installationCosts = new DoubleMatrix(data.InstallationCosts);
|
---|
| 298 | var weights = new DoubleMatrix(data.Weights);
|
---|
| 299 | var distances = new DoubleMatrix(data.Distances);
|
---|
| 300 | var transportationCosts = new DoubleValue(data.TransportationCosts);
|
---|
[7445] | 301 |
|
---|
[7548] | 302 | Load(demands, capacities, weights, distances, installationCosts, transportationCosts);
|
---|
| 303 | EvaluateAndLoadAssignment(data.BestKnownAssignment);
|
---|
[7466] | 304 |
|
---|
[7548] | 305 | if (data.BestKnownAssignment == null && data.BestKnownQuality.HasValue) {
|
---|
| 306 | BestKnownQuality = new DoubleValue(data.BestKnownQuality.Value);
|
---|
[7445] | 307 | }
|
---|
| 308 | }
|
---|
| 309 |
|
---|
[7548] | 310 | public void Load(DoubleArray demands, DoubleArray capacities,
|
---|
| 311 | DoubleMatrix weights, DoubleMatrix distances, DoubleMatrix installationCosts,
|
---|
[7970] | 312 | DoubleValue transportationCosts) {
|
---|
[7548] | 313 | if (weights == null || weights.Rows == 0)
|
---|
| 314 | throw new System.IO.InvalidDataException(
|
---|
| 315 | @"The given instance does not contain weights!");
|
---|
| 316 | if (weights.Rows != weights.Columns)
|
---|
| 317 | throw new System.IO.InvalidDataException(
|
---|
[7970] | 318 | @"The weights matrix of the given instance contains
|
---|
| 319 | an unequal number of rows and columns.");
|
---|
[7548] | 320 | Weights = weights;
|
---|
[7466] | 321 |
|
---|
[7548] | 322 | if (distances == null || distances.Rows == 0)
|
---|
| 323 | throw new System.IO.InvalidDataException(
|
---|
| 324 | @"The given instance does not contain distances!");
|
---|
| 325 | if (distances.Rows != distances.Columns)
|
---|
| 326 | throw new System.IO.InvalidDataException(
|
---|
[7970] | 327 | @"The distances matrix of the given instance contains
|
---|
| 328 | an unequal number of rows and columns.");
|
---|
[7548] | 329 | Distances = distances;
|
---|
[7466] | 330 |
|
---|
[7548] | 331 | if (installationCosts == null || installationCosts.Rows == 0)
|
---|
| 332 | throw new System.IO.InvalidDataException(
|
---|
| 333 | @"The given instance does not contain installation costs!");
|
---|
| 334 | if (installationCosts.Rows != weights.Rows
|
---|
| 335 | || installationCosts.Columns != distances.Columns)
|
---|
| 336 | throw new System.IO.InvalidDataException(
|
---|
[7970] | 337 | @"The installation costs matrix of the given instance
|
---|
| 338 | contains different number of rows than given in the
|
---|
| 339 | weights matrix and a different number of columns than
|
---|
[7548] | 340 | given in the distances matrix.");
|
---|
| 341 | InstallationCosts = installationCosts;
|
---|
[7466] | 342 |
|
---|
[7548] | 343 | if (capacities == null || capacities.Length == 0)
|
---|
| 344 | throw new System.IO.InvalidDataException(
|
---|
| 345 | @"The given instance does not contain capacities!");
|
---|
| 346 | if (capacities.Length != distances.Rows)
|
---|
| 347 | throw new System.IO.InvalidDataException(
|
---|
[7970] | 348 | @"The given instance contains a different number of
|
---|
| 349 | capacities than rows given in the distances matrix.");
|
---|
[7548] | 350 | Capacities = capacities;
|
---|
[7466] | 351 |
|
---|
[7548] | 352 | if (demands == null || demands.Length == 0)
|
---|
| 353 | throw new System.IO.InvalidDataException(
|
---|
| 354 | @"The given instance does not contain demands!");
|
---|
| 355 | if (demands.Length != weights.Rows)
|
---|
| 356 | throw new System.IO.InvalidDataException(
|
---|
[7970] | 357 | @"The given instance contains a different number of
|
---|
| 358 | demands than rows given in the weights matrix.");
|
---|
[7548] | 359 | Demands = demands;
|
---|
[7523] | 360 |
|
---|
[7548] | 361 | if (transportationCosts == null)
|
---|
| 362 | throw new System.IO.InvalidDataException(
|
---|
| 363 | @"The given instance does not contain transportation costs.");
|
---|
[7970] | 364 | TransportationCosts = transportationCosts.Value;
|
---|
[7523] | 365 |
|
---|
[7548] | 366 | BestKnownQuality = null;
|
---|
| 367 | BestKnownSolution = null;
|
---|
| 368 | BestKnownSolutions = null;
|
---|
[7970] | 369 | CalculateExpectedRandomQuality();
|
---|
[7523] | 370 | }
|
---|
| 371 |
|
---|
[7970] | 372 | private void CalculateExpectedRandomQuality() {
|
---|
| 373 | if (IsConfigurationValid()) {
|
---|
| 374 | double[] avgDistances = new double[Capacities.Length];
|
---|
| 375 | for (int i = 0; i < Capacities.Length; i++) {
|
---|
| 376 | for (int j = 0; j < Capacities.Length; j++)
|
---|
| 377 | avgDistances[i] += Distances[i, j];
|
---|
| 378 | avgDistances[i] /= Capacities.Length;
|
---|
| 379 | }
|
---|
| 380 | double[] avgWeight = new double[Demands.Length];
|
---|
| 381 | for (int i = 0; i < Demands.Length; i++) {
|
---|
| 382 | for (int j = 0; j < Demands.Length; j++)
|
---|
| 383 | avgWeight[i] += Weights[i, j];
|
---|
| 384 | avgWeight[i] /= Demands.Length;
|
---|
| 385 | }
|
---|
| 386 | double avgCosts = InstallationCosts.Average();
|
---|
| 387 | double quality = 0;
|
---|
| 388 | for (int i = 0; i < Demands.Length; i++) {
|
---|
| 389 | double equipmentInfluence = 0;
|
---|
| 390 | for (int j = 0; j < Capacities.Length; j++)
|
---|
| 391 | equipmentInfluence += avgWeight[i] * avgDistances[j];
|
---|
| 392 | quality += equipmentInfluence * Demands.Length / (double)Capacities.Length;
|
---|
| 393 | }
|
---|
| 394 | quality *= TransportationCosts;
|
---|
| 395 | quality += avgCosts * Demands.Length;
|
---|
| 396 |
|
---|
| 397 | ExpectedRandomQuality = quality;
|
---|
| 398 | }
|
---|
| 399 | }
|
---|
[7445] | 400 | private void EvaluateAndLoadAssignment(int[] vector) {
|
---|
[7548] | 401 | if (vector == null || vector.Length == 0) return;
|
---|
[7471] | 402 | EvaluateAndLoadAssignment(new IntegerVector(vector));
|
---|
| 403 | }
|
---|
[7548] | 404 | public void EvaluateAndLoadAssignment(IntegerVector assignment) {
|
---|
[7523] | 405 | if (!IsConfigurationValid()) {
|
---|
| 406 | BestKnownQuality = null;
|
---|
| 407 | BestKnownSolution = null;
|
---|
| 408 | BestKnownSolutions = null;
|
---|
| 409 | }
|
---|
[7445] | 410 | double flowDistanceQuality, installationQuality, overbookedCapacity;
|
---|
[7970] | 411 | Evaluator.Evaluate(assignment, Weights, Distances, InstallationCosts, Demands, Capacities,
|
---|
[7445] | 412 | out flowDistanceQuality, out installationQuality, out overbookedCapacity);
|
---|
[7970] | 413 | double quality = Evaluator.GetFitness(flowDistanceQuality, installationQuality, overbookedCapacity, TransportationCosts, ExpectedRandomQuality);
|
---|
[7471] | 414 | BestKnownSolution = new GQAPAssignment((IntegerVector)assignment.Clone(), new DoubleValue(quality),
|
---|
[7470] | 415 | new DoubleValue(flowDistanceQuality), new DoubleValue(installationQuality),
|
---|
| 416 | new DoubleValue(overbookedCapacity), EquipmentNames, LocationNames, Distances, Weights, InstallationCosts,
|
---|
[7970] | 417 | Demands, Capacities, new DoubleValue(TransportationCosts), new DoubleValue(ExpectedRandomQuality), Evaluator);
|
---|
[7445] | 418 | BestKnownQuality = new DoubleValue(quality);
|
---|
[7970] | 419 | BestKnownSolutions = new GQAPAssignmentArchive(EquipmentNames, LocationNames, Distances, Weights, InstallationCosts, Demands, Capacities, new DoubleValue(TransportationCosts), new DoubleValue(ExpectedRandomQuality), Evaluator);
|
---|
[7471] | 420 | BestKnownSolutions.Solutions.Add(new GQAPSolution((IntegerVector)assignment.Clone(), new DoubleValue(quality), new DoubleValue(flowDistanceQuality), new DoubleValue(installationQuality), new DoubleValue(overbookedCapacity)));
|
---|
[7445] | 421 | }
|
---|
[7548] | 422 | #endregion
|
---|
[7445] | 423 |
|
---|
[6956] | 424 | #region Events
|
---|
[7311] | 425 | protected override void OnOperatorsChanged() {
|
---|
| 426 | base.OnOperatorsChanged();
|
---|
| 427 | Parameterize();
|
---|
| 428 | }
|
---|
| 429 | protected override void OnEvaluatorChanged() {
|
---|
| 430 | base.OnEvaluatorChanged();
|
---|
| 431 | Parameterize();
|
---|
[7970] | 432 | if (BestKnownSolution != null) EvaluateAndLoadAssignment(BestKnownSolution.Assignment);
|
---|
[7311] | 433 | Evaluator.QualityParameter.ActualNameChanged += new System.EventHandler(Evaluator_QualityParameter_ActualNameChanged);
|
---|
| 434 | }
|
---|
| 435 | protected override void OnSolutionCreatorChanged() {
|
---|
| 436 | base.OnSolutionCreatorChanged();
|
---|
| 437 | Parameterize();
|
---|
[7407] | 438 | SolutionCreator.AssignmentParameter.ActualNameChanged += new EventHandler(SolutionCreator_IntegerVectorParameter_ActualNameChanged);
|
---|
[7311] | 439 | }
|
---|
| 440 |
|
---|
| 441 | private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
|
---|
| 442 | Parameterize();
|
---|
| 443 | }
|
---|
| 444 | private void SolutionCreator_IntegerVectorParameter_ActualNameChanged(object sender, EventArgs e) {
|
---|
| 445 | Parameterize();
|
---|
| 446 | }
|
---|
[6956] | 447 | #endregion
|
---|
| 448 |
|
---|
| 449 | #region Helpers
|
---|
| 450 | [StorableHook(HookType.AfterDeserialization)]
|
---|
[7412] | 451 | private void AfterDeserialization() {
|
---|
[7432] | 452 | RegisterEventHandlers();
|
---|
[6956] | 453 | }
|
---|
| 454 |
|
---|
[7432] | 455 | private void RegisterEventHandlers() {
|
---|
[7311] | 456 | Evaluator.QualityParameter.ActualNameChanged += new System.EventHandler(Evaluator_QualityParameter_ActualNameChanged);
|
---|
[7373] | 457 | SolutionCreator.AssignmentParameter.ActualNameChanged += new EventHandler(SolutionCreator_IntegerVectorParameter_ActualNameChanged);
|
---|
[6956] | 458 | }
|
---|
| 459 |
|
---|
| 460 | private void InitializeOperators() {
|
---|
[7437] | 461 | Operators.Clear();
|
---|
[7415] | 462 | Operators.AddRange(ApplicationManager.Manager.GetInstances<IGQAPOperator>());
|
---|
[6956] | 463 | Operators.AddRange(ApplicationManager.Manager.GetInstances<IIntegerVectorOperator>());
|
---|
| 464 | Operators.RemoveAll(x => x is ISingleObjectiveMoveEvaluator);
|
---|
[7413] | 465 | Operators.AddRange(ApplicationManager.Manager.GetInstances<IGQAPMoveEvaluator>());
|
---|
[7970] | 466 | Operators.Add(new ScaledQualityDifferenceAnalyzer());
|
---|
[7311] | 467 | Parameterize();
|
---|
[6956] | 468 | }
|
---|
[7311] | 469 |
|
---|
| 470 | private void Parameterize() {
|
---|
| 471 |
|
---|
[7419] | 472 | var operators = Operators.Union(new IOperator[] { SolutionCreator, Evaluator }).ToArray();
|
---|
[7311] | 473 |
|
---|
[7419] | 474 | foreach (var op in operators.OfType<IAssignmentAwareGQAPOperator>()) {
|
---|
| 475 | op.AssignmentParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
|
---|
[7970] | 476 | op.AssignmentParameter.Hidden = true;
|
---|
[7419] | 477 | }
|
---|
| 478 | foreach (var op in operators.OfType<IBestKnownQualityAwareGQAPOperator>()) {
|
---|
| 479 | op.BestKnownQualityParameter.ActualName = BestKnownQualityParameter.Name;
|
---|
[7970] | 480 | op.BestKnownQualityParameter.Hidden = true;
|
---|
[7419] | 481 | }
|
---|
| 482 | foreach (var op in operators.OfType<IBestKnownSolutionAwareGQAPOperator>()) {
|
---|
| 483 | op.BestKnownSolutionParameter.ActualName = BestKnownSolutionParameter.Name;
|
---|
[7970] | 484 | op.BestKnownSolutionParameter.Hidden = true;
|
---|
[7419] | 485 | }
|
---|
[7438] | 486 | foreach (var op in operators.OfType<IBestKnownSolutionsAwareGQAPOperator>()) {
|
---|
| 487 | op.BestKnownSolutionsParameter.ActualName = BestKnownSolutionsParameter.Name;
|
---|
[7970] | 488 | op.BestKnownSolutionsParameter.Hidden = true;
|
---|
[7438] | 489 | }
|
---|
[7419] | 490 | foreach (var op in operators.OfType<ICapacitiesAwareGQAPOperator>()) {
|
---|
| 491 | op.CapacitiesParameter.ActualName = CapacitiesParameter.Name;
|
---|
[7970] | 492 | op.CapacitiesParameter.Hidden = true;
|
---|
[7419] | 493 | }
|
---|
| 494 | foreach (var op in operators.OfType<IDemandsAwareGQAPOperator>()) {
|
---|
[7407] | 495 | op.DemandsParameter.ActualName = DemandsParameter.Name;
|
---|
[7970] | 496 | op.DemandsParameter.Hidden = true;
|
---|
[7311] | 497 | }
|
---|
[7419] | 498 | foreach (var op in operators.OfType<IDistancesAwareGQAPOperator>()) {
|
---|
| 499 | op.DistancesParameter.ActualName = DistancesParameter.Name;
|
---|
[7970] | 500 | op.DistancesParameter.Hidden = true;
|
---|
[7419] | 501 | }
|
---|
| 502 | foreach (var op in operators.OfType<IEquipmentNamesAwareGQAPOperator>()) {
|
---|
| 503 | op.EquipmentNamesParameter.ActualName = EquipmentNamesParameter.Name;
|
---|
[7970] | 504 | op.EquipmentNamesParameter.Hidden = true;
|
---|
[7419] | 505 | }
|
---|
| 506 | foreach (var op in operators.OfType<IGQAPCrossover>()) {
|
---|
[7373] | 507 | op.ParentsParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
|
---|
[7970] | 508 | op.ParentsParameter.Hidden = true;
|
---|
[7373] | 509 | op.ChildParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
|
---|
[7970] | 510 | op.ChildParameter.Hidden = true;
|
---|
[7319] | 511 | }
|
---|
[7419] | 512 | foreach (var op in operators.OfType<IInstallationCostsAwareGQAPOperator>()) {
|
---|
[7407] | 513 | op.InstallationCostsParameter.ActualName = InstallationCostsParameter.Name;
|
---|
[7970] | 514 | op.InstallationCostsParameter.Hidden = true;
|
---|
[7407] | 515 | }
|
---|
[7419] | 516 | foreach (var op in operators.OfType<ILocationNamesAwareGQAPOperator>()) {
|
---|
| 517 | op.LocationNamesParameter.ActualName = LocationNamesParameter.Name;
|
---|
[7970] | 518 | op.LocationNamesParameter.Hidden = true;
|
---|
[7419] | 519 | }
|
---|
| 520 | var moveEvaluator = operators.OfType<IGQAPMoveEvaluator>().FirstOrDefault();
|
---|
| 521 | foreach (var op in operators.OfType<IGQAPMoveEvaluator>()) { // synchronize all move evaluators
|
---|
| 522 | if (moveEvaluator != null) {
|
---|
| 523 | op.MoveQualityParameter.ActualName = moveEvaluator.MoveQualityParameter.ActualName;
|
---|
[7970] | 524 | op.MoveQualityParameter.Hidden = true;
|
---|
[7419] | 525 | op.MoveFlowDistanceQualityParameter.ActualName = moveEvaluator.MoveFlowDistanceQualityParameter.ActualName;
|
---|
[7970] | 526 | op.MoveFlowDistanceQualityParameter.Hidden = true;
|
---|
[7419] | 527 | op.MoveInstallationQualityParameter.ActualName = moveEvaluator.MoveInstallationQualityParameter.ActualName;
|
---|
[7970] | 528 | op.MoveInstallationQualityParameter.Hidden = true;
|
---|
[7419] | 529 | op.MoveOverbookedCapacityParameter.ActualName = moveEvaluator.MoveOverbookedCapacityParameter.ActualName;
|
---|
[7970] | 530 | op.MoveOverbookedCapacityParameter.Hidden = true;
|
---|
[7419] | 531 | }
|
---|
| 532 | }
|
---|
| 533 | foreach (var op in operators.OfType<IMoveQualityAwareGQAPOperator>()) {
|
---|
| 534 | if (moveEvaluator != null) {
|
---|
| 535 | op.MoveQualityParameter.ActualName = moveEvaluator.MoveQualityParameter.ActualName;
|
---|
[7970] | 536 | op.MoveQualityParameter.Hidden = true;
|
---|
[7419] | 537 | op.MoveFlowDistanceQualityParameter.ActualName = moveEvaluator.MoveFlowDistanceQualityParameter.ActualName;
|
---|
[7970] | 538 | op.MoveFlowDistanceQualityParameter.Hidden = true;
|
---|
[7419] | 539 | op.MoveInstallationQualityParameter.ActualName = moveEvaluator.MoveInstallationQualityParameter.ActualName;
|
---|
[7970] | 540 | op.MoveInstallationQualityParameter.Hidden = true;
|
---|
[7419] | 541 | op.MoveOverbookedCapacityParameter.ActualName = moveEvaluator.MoveOverbookedCapacityParameter.ActualName;
|
---|
[7970] | 542 | op.MoveOverbookedCapacityParameter.Hidden = true;
|
---|
[7419] | 543 | }
|
---|
| 544 | op.MaximizationParameter.ActualName = MaximizationParameter.Name;
|
---|
[7970] | 545 | op.MaximizationParameter.Hidden = true;
|
---|
[7419] | 546 | }
|
---|
[7970] | 547 | foreach (var op in operators.OfType<IExpectedRandomQualityAwareGQAPOperator>()) {
|
---|
| 548 | op.ExpectedRandomQualityParameter.ActualName = ExpectedRandomQualityParameter.Name;
|
---|
| 549 | op.ExpectedRandomQualityParameter.Hidden = true;
|
---|
[7419] | 550 | }
|
---|
| 551 | foreach (var op in operators.OfType<IQualitiesAwareGQAPOperator>()) {
|
---|
[7412] | 552 | op.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
|
---|
[7970] | 553 | op.QualityParameter.Hidden = true;
|
---|
[7412] | 554 | op.FlowDistanceQualityParameter.ActualName = Evaluator.FlowDistanceQualityParameter.ActualName;
|
---|
[7970] | 555 | op.FlowDistanceQualityParameter.Hidden = true;
|
---|
[7412] | 556 | op.InstallationQualityParameter.ActualName = Evaluator.InstallationQualityParameter.ActualName;
|
---|
[7970] | 557 | op.InstallationQualityParameter.Hidden = true;
|
---|
[7412] | 558 | op.OverbookedCapacityParameter.ActualName = Evaluator.OverbookedCapacityParameter.ActualName;
|
---|
[7970] | 559 | op.OverbookedCapacityParameter.Hidden = true;
|
---|
[7419] | 560 | op.MaximizationParameter.ActualName = MaximizationParameter.Name;
|
---|
[7970] | 561 | op.MaximizationParameter.Hidden = true;
|
---|
[7407] | 562 | }
|
---|
[7419] | 563 | foreach (var op in operators.OfType<IQualityAwareGQAPOperator>()) {
|
---|
[7412] | 564 | op.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
|
---|
[7970] | 565 | op.QualityParameter.Hidden = true;
|
---|
[7419] | 566 | op.FlowDistanceQualityParameter.ActualName = Evaluator.FlowDistanceQualityParameter.ActualName;
|
---|
[7970] | 567 | op.FlowDistanceQualityParameter.Hidden = true;
|
---|
[7419] | 568 | op.InstallationQualityParameter.ActualName = Evaluator.InstallationQualityParameter.ActualName;
|
---|
[7970] | 569 | op.InstallationQualityParameter.Hidden = true;
|
---|
[7419] | 570 | op.OverbookedCapacityParameter.ActualName = Evaluator.OverbookedCapacityParameter.ActualName;
|
---|
[7970] | 571 | op.OverbookedCapacityParameter.Hidden = true;
|
---|
[7412] | 572 | op.MaximizationParameter.ActualName = MaximizationParameter.Name;
|
---|
[7970] | 573 | op.MaximizationParameter.Hidden = true;
|
---|
[7412] | 574 | }
|
---|
[7419] | 575 | foreach (var op in operators.OfType<ITransportationCostsAwareGQAPOperator>()) {
|
---|
| 576 | op.TransportationCostsParameter.ActualName = TransportationCostsParameter.Name;
|
---|
[7970] | 577 | op.TransportationCostsParameter.Hidden = true;
|
---|
[7407] | 578 | }
|
---|
[7419] | 579 | foreach (var op in operators.OfType<IWeightsAwareGQAPOperator>()) {
|
---|
| 580 | op.WeightsParameter.ActualName = WeightsParameter.Name;
|
---|
[7970] | 581 | op.WeightsParameter.Hidden = true;
|
---|
[7319] | 582 | }
|
---|
[7970] | 583 | foreach (var op in operators.OfType<IEvaluatorAwareGQAPOperator>()) {
|
---|
| 584 | op.EvaluatorParameter.ActualName = EvaluatorParameter.Name;
|
---|
| 585 | op.EvaluatorParameter.Hidden = true;
|
---|
| 586 | }
|
---|
[7407] | 587 |
|
---|
[7419] | 588 | foreach (var op in operators.OfType<IIntegerVectorCrossover>()) {
|
---|
[7407] | 589 | op.ParentsParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
|
---|
[7970] | 590 | op.ParentsParameter.Hidden = true;
|
---|
[7407] | 591 | op.ChildParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
|
---|
[7970] | 592 | op.ChildParameter.Hidden = true;
|
---|
[7319] | 593 | }
|
---|
[7419] | 594 | foreach (var op in operators.OfType<IIntegerVectorManipulator>()) {
|
---|
[7407] | 595 | op.IntegerVectorParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
|
---|
[7970] | 596 | op.IntegerVectorParameter.Hidden = true;
|
---|
[7407] | 597 | }
|
---|
[7970] | 598 |
|
---|
| 599 | foreach (var op in operators.OfType<ScaledQualityDifferenceAnalyzer>()) {
|
---|
| 600 | op.MinimumQualityParameter.ActualName = BestKnownQualityParameter.Name;
|
---|
| 601 | op.MinimumQualityParameter.Hidden = true;
|
---|
| 602 | op.MaximumQualityParameter.ActualName = ExpectedRandomQualityParameter.Name;
|
---|
| 603 | op.MaximumQualityParameter.Hidden = true;
|
---|
| 604 | op.QualityParameter.ActualName = "BestQuality";
|
---|
| 605 | op.QualityParameter.Hidden = true;
|
---|
| 606 | }
|
---|
[6956] | 607 | }
|
---|
| 608 | #endregion
|
---|
[7471] | 609 |
|
---|
[7548] | 610 | public bool IsConfigurationValid() {
|
---|
[7471] | 611 | return Weights != null && Distances != null && Demands != null && Capacities != null && InstallationCosts != null
|
---|
| 612 | && Weights.Rows == Weights.Columns && Weights.Rows == InstallationCosts.Rows
|
---|
| 613 | && Distances.Rows == Distances.Columns && Distances.Rows == InstallationCosts.Columns
|
---|
| 614 | && Demands.Length == Weights.Rows && Capacities.Length == Distances.Rows;
|
---|
| 615 | }
|
---|
[6956] | 616 | }
|
---|
| 617 | }
|
---|