- Timestamp:
- 09/16/19 11:57:18 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2521_ProblemRefactoring/HeuristicLab.Problems.QuadraticAssignment/3.3/QuadraticAssignmentProblem.cs
r17232 r17252 25 25 using System.Linq; 26 26 using HEAL.Attic; 27 using HeuristicLab.Analysis;28 27 using HeuristicLab.Common; 29 28 using HeuristicLab.Core; … … 31 30 using HeuristicLab.Encodings.PermutationEncoding; 32 31 using HeuristicLab.Optimization; 33 using HeuristicLab.Optimization.Operators;34 32 using HeuristicLab.Parameters; 35 33 using HeuristicLab.PluginInfrastructure; … … 42 40 public sealed class QuadraticAssignmentProblem : PermutationProblem, 43 41 IProblemInstanceConsumer<QAPData>, 44 IProblemInstanceConsumer<TSPData> { 42 IProblemInstanceConsumer<TSPData>, IProblemInstanceExporter<QAPData> { 43 public static int ProblemSizeLimit = 1000; 45 44 46 45 public static new Image StaticItemImage { … … 51 50 52 51 #region Parameter Properties 53 [Storable] 54 private IValueParameter<ItemSet<Permutation>> bestKnownSolutionsParameter; 55 public IValueParameter<ItemSet<Permutation>> BestKnownSolutionsParameter { 56 get { return bestKnownSolutionsParameter; } 57 } 58 [Storable] 59 private IValueParameter<Permutation> bestKnownSolutionParameter; 60 public IValueParameter<Permutation> BestKnownSolutionParameter { 61 get { return bestKnownSolutionParameter; } 62 } 63 [Storable] 64 private IValueParameter<DoubleMatrix> weightsParameter; 65 public IValueParameter<DoubleMatrix> WeightsParameter { 66 get { return weightsParameter; } 67 } 68 [Storable] 69 private IValueParameter<DoubleMatrix> distancesParameter; 70 public IValueParameter<DoubleMatrix> DistancesParameter { 71 get { return distancesParameter; } 72 } 73 [Storable] 74 private IValueParameter<DoubleValue> lowerBoundParameter; 75 public IValueParameter<DoubleValue> LowerBoundParameter { 76 get { return lowerBoundParameter; } 77 } 78 [Storable] 79 private IValueParameter<DoubleValue> averageQualityParameter; 80 public IValueParameter<DoubleValue> AverageQualityParameter { 81 get { return averageQualityParameter; } 82 } 52 [Storable] public IValueParameter<ItemSet<Permutation>> BestKnownSolutionsParameter { get; private set; } 53 [Storable] public IValueParameter<Permutation> BestKnownSolutionParameter { get; private set; } 54 [Storable] public IValueParameter<DoubleMatrix> WeightsParameter { get; private set; } 55 [Storable] public IValueParameter<DoubleMatrix> DistancesParameter { get; private set; } 56 [Storable] public IValueParameter<DoubleValue> LowerBoundParameter { get; private set; } 57 [Storable] public IValueParameter<DoubleValue> AverageQualityParameter { get; private set; } 83 58 #endregion 84 59 85 60 #region Properties 86 61 public ItemSet<Permutation> BestKnownSolutions { 87 get { return bestKnownSolutionsParameter.Value; }88 set { bestKnownSolutionsParameter.Value = value; }62 get { return BestKnownSolutionsParameter.Value; } 63 set { BestKnownSolutionsParameter.Value = value; } 89 64 } 90 65 public Permutation BestKnownSolution { 91 get { return bestKnownSolutionParameter.Value; }92 set { bestKnownSolutionParameter.Value = value; }66 get { return BestKnownSolutionParameter.Value; } 67 set { BestKnownSolutionParameter.Value = value; } 93 68 } 94 69 public DoubleMatrix Weights { 95 get { return weightsParameter.Value; }96 set { weightsParameter.Value = value; }70 get { return WeightsParameter.Value; } 71 set { WeightsParameter.Value = value; } 97 72 } 98 73 public DoubleMatrix Distances { 99 get { return distancesParameter.Value; }100 set { distancesParameter.Value = value; }74 get { return DistancesParameter.Value; } 75 set { DistancesParameter.Value = value; } 101 76 } 102 77 public DoubleValue LowerBound { 103 get { return lowerBoundParameter.Value; }104 set { lowerBoundParameter.Value = value; }78 get { return LowerBoundParameter.Value; } 79 set { LowerBoundParameter.Value = value; } 105 80 } 106 81 public DoubleValue AverageQuality { 107 get { return averageQualityParameter.Value; }108 set { averageQualityParameter.Value = value; }82 get { return AverageQualityParameter.Value; } 83 set { AverageQualityParameter.Value = value; } 109 84 } 110 85 … … 115 90 private QAPAlleleFrequencyAnalyzer QAPAlleleFrequencyAnalyzer { 116 91 get { return Operators.OfType<QAPAlleleFrequencyAnalyzer>().FirstOrDefault(); } 117 }118 119 private QAPPopulationDiversityAnalyzer QAPPopulationDiversityAnalyzer {120 get { return Operators.OfType<QAPPopulationDiversityAnalyzer>().FirstOrDefault(); }121 92 } 122 93 #endregion … … 126 97 private QuadraticAssignmentProblem(QuadraticAssignmentProblem original, Cloner cloner) 127 98 : base(original, cloner) { 128 bestKnownSolutionsParameter = cloner.Clone(original.bestKnownSolutionsParameter);129 bestKnownSolutionParameter = cloner.Clone(original.bestKnownSolutionParameter);130 weightsParameter = cloner.Clone(original.weightsParameter);131 distancesParameter = cloner.Clone(original.distancesParameter);132 lowerBoundParameter = cloner.Clone(original.lowerBoundParameter);133 averageQualityParameter = cloner.Clone(original.averageQualityParameter);99 BestKnownSolutionsParameter = cloner.Clone(original.BestKnownSolutionsParameter); 100 BestKnownSolutionParameter = cloner.Clone(original.BestKnownSolutionParameter); 101 WeightsParameter = cloner.Clone(original.WeightsParameter); 102 DistancesParameter = cloner.Clone(original.DistancesParameter); 103 LowerBoundParameter = cloner.Clone(original.LowerBoundParameter); 104 AverageQualityParameter = cloner.Clone(original.AverageQualityParameter); 134 105 RegisterEventHandlers(); 135 106 } 136 107 public QuadraticAssignmentProblem() 137 108 : base(new PermutationEncoding("Assignment") { Length = 5 }) { 138 Parameters.Add( bestKnownSolutionsParameter = new OptionalValueParameter<ItemSet<Permutation>>("BestKnownSolutions", "The list of best known solutions which is updated whenever a new better solution is found or may be the optimal solution if it is known beforehand.", null));139 Parameters.Add( bestKnownSolutionParameter = new OptionalValueParameter<Permutation>("BestKnownSolution", "The best known solution which is updated whenever a new better solution is found or may be the optimal solution if it is known beforehand.", null));140 Parameters.Add( weightsParameter = new ValueParameter<DoubleMatrix>("Weights", "The strength of the connection between the facilities.", new DoubleMatrix(5, 5)));141 Parameters.Add( distancesParameter = new ValueParameter<DoubleMatrix>("Distances", "The distance matrix which can either be specified directly without the coordinates, or can be calculated automatically from the coordinates.", new DoubleMatrix(5, 5)));142 Parameters.Add( lowerBoundParameter = new OptionalValueParameter<DoubleValue>("LowerBound", "The Gilmore-Lawler lower bound to the solution quality."));143 Parameters.Add( averageQualityParameter = new OptionalValueParameter<DoubleValue>("AverageQuality", "The expected quality of a random solution."));109 Parameters.Add(BestKnownSolutionsParameter = new OptionalValueParameter<ItemSet<Permutation>>("BestKnownSolutions", "The list of best known solutions which is updated whenever a new better solution is found or may be the optimal solution if it is known beforehand.", null)); 110 Parameters.Add(BestKnownSolutionParameter = new OptionalValueParameter<Permutation>("BestKnownSolution", "The best known solution which is updated whenever a new better solution is found or may be the optimal solution if it is known beforehand.", null)); 111 Parameters.Add(WeightsParameter = new ValueParameter<DoubleMatrix>("Weights", "The strength of the connection between the facilities.")); 112 Parameters.Add(DistancesParameter = new ValueParameter<DoubleMatrix>("Distances", "The distance matrix which can either be specified directly without the coordinates, or can be calculated automatically from the coordinates.")); 113 Parameters.Add(LowerBoundParameter = new OptionalValueParameter<DoubleValue>("LowerBound", "The Gilmore-Lawler lower bound to the solution quality.")); 114 Parameters.Add(AverageQualityParameter = new OptionalValueParameter<DoubleValue>("AverageQuality", "The expected quality of a random solution.")); 144 115 145 116 WeightsParameter.GetsCollected = false; … … 150 121 { 0, 0, 1, 0, 1 }, 151 122 { 1, 0, 0, 1, 0 } 152 } );123 }, @readonly: true); 153 124 154 125 DistancesParameter.GetsCollected = false; … … 159 130 { 582, 582, 360, 0, 360 }, 160 131 { 360, 582, 582, 360, 0 } 161 } );132 }, @readonly: true); 162 133 163 134 InitializeOperators(); … … 187 158 // BackwardsCompatibility3.3 188 159 #region Backwards compatible code, remove with 3.4 189 if ( bestKnownSolutionsParameter == null)190 bestKnownSolutionsParameter = (IValueParameter<ItemSet<Permutation>>)Parameters["BestKnownSolutions"];191 if ( bestKnownSolutionParameter == null)192 bestKnownSolutionParameter = (IValueParameter<Permutation>)Parameters["BestKnownSolution"];193 if ( weightsParameter == null)194 weightsParameter = (IValueParameter<DoubleMatrix>)Parameters["Weights"];195 if ( distancesParameter == null)196 distancesParameter = (IValueParameter<DoubleMatrix>)Parameters["Distances"];197 if ( lowerBoundParameter == null)198 lowerBoundParameter = (IValueParameter<DoubleValue>)Parameters["LowerBound"];199 if ( averageQualityParameter == null)200 averageQualityParameter = (IValueParameter<DoubleValue>)Parameters["AverageQuality"];160 if (BestKnownSolutionsParameter == null) 161 BestKnownSolutionsParameter = (IValueParameter<ItemSet<Permutation>>)Parameters["BestKnownSolutions"]; 162 if (BestKnownSolutionParameter == null) 163 BestKnownSolutionParameter = (IValueParameter<Permutation>)Parameters["BestKnownSolution"]; 164 if (WeightsParameter == null) 165 WeightsParameter = (IValueParameter<DoubleMatrix>)Parameters["Weights"]; 166 if (DistancesParameter == null) 167 DistancesParameter = (IValueParameter<DoubleMatrix>)Parameters["Distances"]; 168 if (LowerBoundParameter == null) 169 LowerBoundParameter = (IValueParameter<DoubleValue>)Parameters["LowerBound"]; 170 if (AverageQualityParameter == null) 171 AverageQualityParameter = (IValueParameter<DoubleValue>)Parameters["AverageQuality"]; 201 172 #endregion 202 173 RegisterEventHandlers(); … … 204 175 205 176 #region Events 206 //TODO check with abhem if this is necessary 207 //protected override void OnSolutionCreatorChanged() { 208 // Parameterize(); 209 // base.OnSolutionCreatorChanged(); 210 //} 177 protected override void OnEncodingChanged() { 178 base.OnEncodingChanged(); 179 Parameterize(); 180 } 211 181 protected override void OnEvaluatorChanged() { 212 182 Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged; … … 217 187 Parameterize(); 218 188 } 219 private void WeightsParameter_ValueChanged(object sender, EventArgs e) {220 Weights.RowsChanged += Weights_RowsChanged;221 Weights.ColumnsChanged += Weights_ColumnsChanged;222 Weights.ToStringChanged += Weights_ToStringChanged;223 AdjustDistanceMatrix();224 }225 private void Weights_RowsChanged(object sender, EventArgs e) {226 if (Weights.Rows != Weights.Columns)227 ((IStringConvertibleMatrix)Weights).Columns = Weights.Rows;228 else {229 AdjustDistanceMatrix();230 }231 }232 private void Weights_ColumnsChanged(object sender, EventArgs e) {233 if (Weights.Rows != Weights.Columns)234 ((IStringConvertibleMatrix)Weights).Rows = Weights.Columns;235 else {236 AdjustDistanceMatrix();237 }238 }239 private void Weights_ToStringChanged(object sender, EventArgs e) {240 UpdateParameterValues();241 }242 private void DistancesParameter_ValueChanged(object sender, EventArgs e) {243 Distances.RowsChanged += Distances_RowsChanged;244 Distances.ColumnsChanged += Distances_ColumnsChanged;245 Distances.ToStringChanged += Distances_ToStringChanged;246 AdjustWeightsMatrix();247 }248 private void Distances_RowsChanged(object sender, EventArgs e) {249 if (Distances.Rows != Distances.Columns)250 ((IStringConvertibleMatrix)Distances).Columns = Distances.Rows;251 else {252 AdjustWeightsMatrix();253 }254 }255 private void Distances_ColumnsChanged(object sender, EventArgs e) {256 if (Distances.Rows != Distances.Columns)257 ((IStringConvertibleMatrix)Distances).Rows = Distances.Columns;258 else {259 AdjustWeightsMatrix();260 }261 }262 private void Distances_ToStringChanged(object sender, EventArgs e) {263 UpdateParameterValues();264 }265 189 #endregion 266 190 267 191 private void RegisterEventHandlers() { 268 WeightsParameter.ValueChanged += WeightsParameter_ValueChanged; 269 Weights.RowsChanged += Weights_RowsChanged; 270 Weights.ColumnsChanged += Weights_ColumnsChanged; 271 Weights.ToStringChanged += Weights_ToStringChanged; 272 DistancesParameter.ValueChanged += DistancesParameter_ValueChanged; 273 Distances.RowsChanged += Distances_RowsChanged; 274 Distances.ColumnsChanged += Distances_ColumnsChanged; 275 Distances.ToStringChanged += Distances_ToStringChanged; 192 Encoding.LengthParameter.Value.ValueChanged += EncodingLengthOnChanged; 193 } 194 195 private void EncodingLengthOnChanged(object sender, EventArgs e) { 196 if (Encoding.Length != Weights.Rows) Encoding.Length = Weights.Rows; 276 197 } 277 198 278 199 #region Helpers 279 200 private void InitializeOperators() { 280 var defaultOperators = new HashSet<IPermutationOperator>(new IPermutationOperator[] {281 new PartiallyMatchedCrossover(),282 new Swap2Manipulator(),283 new ExhaustiveSwap2MoveGenerator()284 });285 Operators.AddRange(defaultOperators);286 201 Operators.AddRange(ApplicationManager.Manager.GetInstances<IQAPMoveEvaluator>()); 287 202 Operators.AddRange(ApplicationManager.Manager.GetInstances<IQAPLocalImprovementOperator>()); … … 289 204 Operators.Add(new QAPAlleleFrequencyAnalyzer()); 290 205 291 Operators.Add(new HammingSimilarityCalculator());292 206 Operators.Add(new QAPSimilarityCalculator()); 293 Operators.Add(new QualitySimilarityCalculator());294 Operators.Add(new PopulationSimilarityAnalyzer(Operators.OfType<ISolutionSimilarityCalculator>()));295 207 Parameterize(); 296 208 } … … 314 226 QAPAlleleFrequencyAnalyzer.WeightsParameter.ActualName = WeightsParameter.Name; 315 227 } 316 if (QAPPopulationDiversityAnalyzer != null) {317 operators.Add(QAPPopulationDiversityAnalyzer);318 QAPPopulationDiversityAnalyzer.MaximizationParameter.ActualName = MaximizationParameter.Name;319 QAPPopulationDiversityAnalyzer.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;320 }321 228 foreach (var localOpt in Operators.OfType<IQAPLocalImprovementOperator>()) { 322 229 operators.Add(localOpt); … … 359 266 } 360 267 foreach (var similarityCalculator in Operators.OfType<ISolutionSimilarityCalculator>()) { 268 operators.Add(similarityCalculator); 361 269 similarityCalculator.SolutionVariableName = Encoding.Name; 362 270 similarityCalculator.QualityVariableName = Evaluator.QualityParameter.ActualName; … … 369 277 370 278 if (operators.Count > 0) Encoding.ConfigureOperators(operators); 371 }372 373 private void AdjustDistanceMatrix() {374 if (Distances.Rows != Weights.Rows || Distances.Columns != Weights.Columns) {375 ((IStringConvertibleMatrix)Distances).Rows = Weights.Rows;376 Encoding.Length = Weights.Rows;377 }378 }379 380 private void AdjustWeightsMatrix() {381 if (Weights.Rows != Distances.Rows || Weights.Columns != Distances.Columns) {382 ((IStringConvertibleMatrix)Weights).Rows = Distances.Rows;383 Encoding.Length = Distances.Rows;384 }385 279 } 386 280 … … 418 312 419 313 public void Load(QAPData data) { 420 var weights = new DoubleMatrix(data.Weights); 421 var distances = new DoubleMatrix(data.Distances); 314 if (data.Dimension > ProblemSizeLimit) throw new System.IO.InvalidDataException("The problem is limited to instance of size " + ProblemSizeLimit + ". You can change this limit by modifying " + nameof(QuadraticAssignmentProblem) + "." + nameof(ProblemSizeLimit) +"!"); 315 var weights = new DoubleMatrix(data.Weights, @readonly: true); 316 var distances = new DoubleMatrix(data.Distances, @readonly: true); 422 317 Name = data.Name; 423 318 Description = data.Description; … … 429 324 430 325 public void Load(TSPData data) { 431 if (data.Dimension > 1000) 432 throw new System.IO.InvalidDataException("Instances with more than 1000 customers are not supported by the QAP."); 433 var weights = new DoubleMatrix(data.Dimension, data.Dimension); 326 if (data.Dimension > ProblemSizeLimit) throw new System.IO.InvalidDataException("The problem is limited to instance of size " + ProblemSizeLimit + ". You can change this limit by modifying " + nameof(QuadraticAssignmentProblem) + "." + nameof(ProblemSizeLimit) + "!"); 327 var w = new double[data.Dimension, data.Dimension]; 434 328 for (int i = 0; i < data.Dimension; i++) 435 weights[i, (i + 1) % data.Dimension] = 1; 436 var distances = new DoubleMatrix(data.GetDistanceMatrix()); 329 w[i, (i + 1) % data.Dimension] = 1; 330 var weights = new DoubleMatrix(w, @readonly: true); 331 var distances = new DoubleMatrix(data.GetDistanceMatrix(), @readonly: true); 437 332 Name = data.Name; 438 333 Description = data.Description; … … 473 368 BestKnownSolutions = new ItemSet<Permutation> { (Permutation)vector.Clone() }; 474 369 } 370 371 public QAPData Export() { 372 return new QAPData() { 373 Name = Name, 374 Description = Description, 375 Dimension = Weights.Rows, 376 Weights = Weights.CloneAsMatrix(), 377 Distances = Distances.CloneAsMatrix(), 378 BestKnownAssignment = BestKnownSolution?.ToArray(), 379 BestKnownQuality = !double.IsNaN(BestKnownQuality) ? BestKnownQuality : (double?)null 380 }; 381 } 475 382 } 476 383 }
Note: See TracChangeset
for help on using the changeset viewer.