Free cookie consent management tool by TermsFeed Policy Generator

source: branches/WebJobManager/HeuristicLab.Problems.QuadraticAssignment/3.3/QuadraticAssignmentProblem.cs @ 13777

Last change on this file since 13777 was 13656, checked in by ascheibe, 9 years ago

#2582 created branch for Hive Web Job Manager

File size: 24.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
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
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Encodings.PermutationEncoding;
29using HeuristicLab.Optimization;
30using HeuristicLab.Parameters;
31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32using HeuristicLab.PluginInfrastructure;
33using HeuristicLab.Problems.Instances;
34
35namespace HeuristicLab.Problems.QuadraticAssignment {
36  [Item("Quadratic Assignment Problem (QAP)", "The Quadratic Assignment Problem (QAP) can be described as the problem of assigning N facilities to N fixed locations such that there is exactly one facility in each location and that the sum of the distances multiplied by the connection strength between the facilities becomes minimal.")]
37  [Creatable(CreatableAttribute.Categories.CombinatorialProblems, Priority = 140)]
38  [StorableClass]
39  public sealed class QuadraticAssignmentProblem : SingleObjectiveHeuristicOptimizationProblem<IQAPEvaluator, IPermutationCreator>, IStorableContent,
40    IProblemInstanceConsumer<QAPData>,
41    IProblemInstanceConsumer<TSPData> {
42    public string Filename { get; set; }
43
44
45
46    #region Parameter Properties
47    public IValueParameter<ItemSet<Permutation>> BestKnownSolutionsParameter
48    {
49      get { return (IValueParameter<ItemSet<Permutation>>)Parameters["BestKnownSolutions"]; }
50    }
51    public IValueParameter<Permutation> BestKnownSolutionParameter
52    {
53      get { return (IValueParameter<Permutation>)Parameters["BestKnownSolution"]; }
54    }
55    public IValueParameter<DoubleMatrix> WeightsParameter
56    {
57      get { return (IValueParameter<DoubleMatrix>)Parameters["Weights"]; }
58    }
59    public IValueParameter<DoubleMatrix> DistancesParameter
60    {
61      get { return (IValueParameter<DoubleMatrix>)Parameters["Distances"]; }
62    }
63    public IValueParameter<DoubleValue> LowerBoundParameter
64    {
65      get { return (IValueParameter<DoubleValue>)Parameters["LowerBound"]; }
66    }
67    public IValueParameter<DoubleValue> AverageQualityParameter
68    {
69      get { return (IValueParameter<DoubleValue>)Parameters["AverageQuality"]; }
70    }
71    #endregion
72
73    #region Properties
74    public ItemSet<Permutation> BestKnownSolutions
75    {
76      get { return BestKnownSolutionsParameter.Value; }
77      set { BestKnownSolutionsParameter.Value = value; }
78    }
79    public Permutation BestKnownSolution
80    {
81      get { return BestKnownSolutionParameter.Value; }
82      set { BestKnownSolutionParameter.Value = value; }
83    }
84    public DoubleMatrix Weights
85    {
86      get { return WeightsParameter.Value; }
87      set { WeightsParameter.Value = value; }
88    }
89    public DoubleMatrix Distances
90    {
91      get { return DistancesParameter.Value; }
92      set { DistancesParameter.Value = value; }
93    }
94    public DoubleValue LowerBound
95    {
96      get { return LowerBoundParameter.Value; }
97      set { LowerBoundParameter.Value = value; }
98    }
99    public DoubleValue AverageQuality
100    {
101      get { return AverageQualityParameter.Value; }
102      set { AverageQualityParameter.Value = value; }
103    }
104
105    private BestQAPSolutionAnalyzer BestQAPSolutionAnalyzer
106    {
107      get { return Operators.OfType<BestQAPSolutionAnalyzer>().FirstOrDefault(); }
108    }
109
110    private QAPAlleleFrequencyAnalyzer QAPAlleleFrequencyAnalyzer
111    {
112      get { return Operators.OfType<QAPAlleleFrequencyAnalyzer>().FirstOrDefault(); }
113    }
114
115    private QAPPopulationDiversityAnalyzer QAPPopulationDiversityAnalyzer
116    {
117      get { return Operators.OfType<QAPPopulationDiversityAnalyzer>().FirstOrDefault(); }
118    }
119    #endregion
120
121    [StorableConstructor]
122    private QuadraticAssignmentProblem(bool deserializing) : base(deserializing) { }
123    private QuadraticAssignmentProblem(QuadraticAssignmentProblem original, Cloner cloner)
124      : base(original, cloner) {
125      RegisterEventHandlers();
126    }
127    public QuadraticAssignmentProblem()
128      : base(new QAPEvaluator(), new RandomPermutationCreator()) {
129      Parameters.Add(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));
130      Parameters.Add(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));
131      Parameters.Add(new ValueParameter<DoubleMatrix>("Weights", "The strength of the connection between the facilities.", new DoubleMatrix(5, 5)));
132      Parameters.Add(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)));
133      Parameters.Add(new OptionalValueParameter<DoubleValue>("LowerBound", "The Gilmore-Lawler lower bound to the solution quality."));
134      Parameters.Add(new OptionalValueParameter<DoubleValue>("AverageQuality", "The expected quality of a random solution."));
135
136      Maximization.Value = false;
137      MaximizationParameter.Hidden = true;
138
139      WeightsParameter.GetsCollected = false;
140      Weights = new DoubleMatrix(new double[,] {
141        { 0, 1, 0, 0, 1 },
142        { 1, 0, 1, 0, 0 },
143        { 0, 1, 0, 1, 0 },
144        { 0, 0, 1, 0, 1 },
145        { 1, 0, 0, 1, 0 }
146      });
147
148      DistancesParameter.GetsCollected = false;
149      Distances = new DoubleMatrix(new double[,] {
150        {   0, 360, 582, 582, 360 },
151        { 360,   0, 360, 582, 582 },
152        { 582, 360,   0, 360, 582 },
153        { 582, 582, 360,   0, 360 },
154        { 360, 582, 582, 360,   0 }
155      });
156
157      SolutionCreator.PermutationParameter.ActualName = "Assignment";
158      ParameterizeSolutionCreator();
159      ParameterizeEvaluator();
160
161      InitializeOperators();
162      RegisterEventHandlers();
163    }
164
165    public override IDeepCloneable Clone(Cloner cloner) {
166      return new QuadraticAssignmentProblem(this, cloner);
167    }
168
169    [StorableHook(HookType.AfterDeserialization)]
170    private void AfterDeserialization() {
171      // BackwardsCompatibility3.3
172      #region Backwards compatible code, remove with 3.4
173      if (!Parameters.ContainsKey("BestKnownSolutions")) {
174        Parameters.Add(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));
175      } else if (Parameters["BestKnownSolutions"].GetType().Equals(typeof(OptionalValueParameter<ItemList<Permutation>>))) {
176        ItemList<Permutation> list = ((OptionalValueParameter<ItemList<Permutation>>)Parameters["BestKnownSolutions"]).Value;
177        Parameters.Remove("BestKnownSolutions");
178        Parameters.Add(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.", (list != null ? new ItemSet<Permutation>(list) : null)));
179      }
180      if (Parameters.ContainsKey("DistanceMatrix")) {
181        DoubleMatrix d = ((ValueParameter<DoubleMatrix>)Parameters["DistanceMatrix"]).Value;
182        Parameters.Remove("DistanceMatrix");
183        Parameters.Add(new ValueParameter<DoubleMatrix>("Distances", "The distance matrix which can either be specified directly without the coordinates, or can be calculated automatically from the coordinates.", d));
184      }
185      if (!Parameters.ContainsKey("LowerBound")) {
186        Parameters.Add(new OptionalValueParameter<DoubleValue>("LowerBound", "The Gilmore-Lawler lower bound to the solution quality."));
187        LowerBound = new DoubleValue(GilmoreLawlerBoundCalculator.CalculateLowerBound(Weights, Distances));
188      }
189      if (!Parameters.ContainsKey("AverageQuality")) {
190        Parameters.Add(new OptionalValueParameter<DoubleValue>("AverageQuality", "The expected quality of a random solution."));
191        AverageQuality = new DoubleValue(ComputeAverageQuality());
192      }
193      #endregion
194      RegisterEventHandlers();
195    }
196
197    #region Events
198    protected override void OnSolutionCreatorChanged() {
199      SolutionCreator.PermutationParameter.ActualNameChanged += new EventHandler(SolutionCreator_PermutationParameter_ActualNameChanged);
200      ParameterizeSolutionCreator();
201      ParameterizeEvaluator();
202      ParameterizeAnalyzers();
203      ParameterizeOperators();
204      base.OnSolutionCreatorChanged();
205    }
206    protected override void OnEvaluatorChanged() {
207      Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
208      ParameterizeEvaluator();
209      ParameterizeAnalyzers();
210      ParameterizeOperators();
211      base.OnEvaluatorChanged();
212    }
213
214    private void SolutionCreator_PermutationParameter_ActualNameChanged(object sender, EventArgs e) {
215      ParameterizeEvaluator();
216      ParameterizeAnalyzers();
217      ParameterizeOperators();
218    }
219    private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
220      ParameterizeAnalyzers();
221      ParameterizeOperators();
222    }
223    private void WeightsParameter_ValueChanged(object sender, EventArgs e) {
224      Weights.RowsChanged += new EventHandler(Weights_RowsChanged);
225      Weights.ColumnsChanged += new EventHandler(Weights_ColumnsChanged);
226      Weights.ToStringChanged += new EventHandler(Weights_ToStringChanged);
227      ParameterizeSolutionCreator();
228      ParameterizeEvaluator();
229      ParameterizeOperators();
230      AdjustDistanceMatrix();
231    }
232    private void Weights_RowsChanged(object sender, EventArgs e) {
233      if (Weights.Rows != Weights.Columns)
234        ((IStringConvertibleMatrix)Weights).Columns = Weights.Rows;
235      else {
236        ParameterizeSolutionCreator();
237        ParameterizeEvaluator();
238        ParameterizeOperators();
239        AdjustDistanceMatrix();
240      }
241    }
242    private void Weights_ColumnsChanged(object sender, EventArgs e) {
243      if (Weights.Rows != Weights.Columns)
244        ((IStringConvertibleMatrix)Weights).Rows = Weights.Columns;
245      else {
246        ParameterizeSolutionCreator();
247        ParameterizeEvaluator();
248        ParameterizeOperators();
249        AdjustDistanceMatrix();
250      }
251    }
252    private void Weights_ToStringChanged(object sender, EventArgs e) {
253      UpdateParameterValues();
254    }
255    private void DistancesParameter_ValueChanged(object sender, EventArgs e) {
256      Distances.RowsChanged += new EventHandler(Distances_RowsChanged);
257      Distances.ColumnsChanged += new EventHandler(Distances_ColumnsChanged);
258      Distances.ToStringChanged += new EventHandler(Distances_ToStringChanged);
259      ParameterizeSolutionCreator();
260      ParameterizeEvaluator();
261      ParameterizeOperators();
262      AdjustWeightsMatrix();
263    }
264    private void Distances_RowsChanged(object sender, EventArgs e) {
265      if (Distances.Rows != Distances.Columns)
266        ((IStringConvertibleMatrix)Distances).Columns = Distances.Rows;
267      else {
268        ParameterizeSolutionCreator();
269        ParameterizeEvaluator();
270        ParameterizeOperators();
271        AdjustWeightsMatrix();
272      }
273    }
274    private void Distances_ColumnsChanged(object sender, EventArgs e) {
275      if (Distances.Rows != Distances.Columns)
276        ((IStringConvertibleMatrix)Distances).Rows = Distances.Columns;
277      else {
278        ParameterizeSolutionCreator();
279        ParameterizeEvaluator();
280        ParameterizeOperators();
281        AdjustWeightsMatrix();
282      }
283    }
284    private void Distances_ToStringChanged(object sender, EventArgs e) {
285      UpdateParameterValues();
286    }
287    #endregion
288
289    private void RegisterEventHandlers() {
290      SolutionCreator.PermutationParameter.ActualNameChanged += new EventHandler(SolutionCreator_PermutationParameter_ActualNameChanged);
291      Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
292      WeightsParameter.ValueChanged += new EventHandler(WeightsParameter_ValueChanged);
293      Weights.RowsChanged += new EventHandler(Weights_RowsChanged);
294      Weights.ColumnsChanged += new EventHandler(Weights_ColumnsChanged);
295      Weights.ToStringChanged += new EventHandler(Weights_ToStringChanged);
296      DistancesParameter.ValueChanged += new EventHandler(DistancesParameter_ValueChanged);
297      Distances.RowsChanged += new EventHandler(Distances_RowsChanged);
298      Distances.ColumnsChanged += new EventHandler(Distances_ColumnsChanged);
299      Distances.ToStringChanged += new EventHandler(Distances_ToStringChanged);
300    }
301
302    #region Helpers
303    private void InitializeOperators() {
304      var defaultOperators = new HashSet<IPermutationOperator>(new IPermutationOperator[] {
305        new PartiallyMatchedCrossover(),
306        new Swap2Manipulator(),
307        new ExhaustiveSwap2MoveGenerator()
308      });
309      Operators.AddRange(defaultOperators);
310      Operators.AddRange(ApplicationManager.Manager.GetInstances<IPermutationOperator>().Except(defaultOperators, new TypeEqualityComparer<IPermutationOperator>()));
311      Operators.RemoveAll(x => x is ISingleObjectiveMoveEvaluator);
312      Operators.AddRange(ApplicationManager.Manager.GetInstances<IQAPMoveEvaluator>());
313      Operators.Add(new BestQAPSolutionAnalyzer());
314      Operators.Add(new QAPAlleleFrequencyAnalyzer());
315      Operators.Add(new QAPPopulationDiversityAnalyzer());
316
317      Operators.Add(new QAPExhaustiveInsertionLocalImprovement());
318      Operators.Add(new QAPExhaustiveInversionLocalImprovement());
319      Operators.Add(new QAPStochasticScrambleLocalImprovement());
320      Operators.Add(new QAPExhaustiveSwap2LocalImprovement());
321
322      Operators.Add(new QAPSimilarityCalculator());
323      ParameterizeAnalyzers();
324      ParameterizeOperators();
325    }
326    private void ParameterizeSolutionCreator() {
327      if (SolutionCreator != null) {
328        SolutionCreator.PermutationTypeParameter.Value = new PermutationType(PermutationTypes.Absolute);
329        SolutionCreator.LengthParameter.Value = new IntValue(Weights.Rows);
330      }
331    }
332    private void ParameterizeEvaluator() {
333      if (Evaluator != null) {
334        Evaluator.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
335        Evaluator.DistancesParameter.ActualName = DistancesParameter.Name;
336        Evaluator.WeightsParameter.ActualName = WeightsParameter.Name;
337      }
338    }
339    private void ParameterizeAnalyzers() {
340      if (BestQAPSolutionAnalyzer != null) {
341        BestQAPSolutionAnalyzer.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
342        BestQAPSolutionAnalyzer.DistancesParameter.ActualName = DistancesParameter.Name;
343        BestQAPSolutionAnalyzer.WeightsParameter.ActualName = WeightsParameter.Name;
344        BestQAPSolutionAnalyzer.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
345        BestQAPSolutionAnalyzer.ResultsParameter.ActualName = "Results";
346        BestQAPSolutionAnalyzer.BestKnownQualityParameter.ActualName = BestKnownQualityParameter.Name;
347        BestQAPSolutionAnalyzer.BestKnownSolutionsParameter.ActualName = BestKnownSolutionsParameter.Name;
348        BestQAPSolutionAnalyzer.MaximizationParameter.ActualName = MaximizationParameter.Name;
349      }
350      if (QAPAlleleFrequencyAnalyzer != null) {
351        QAPAlleleFrequencyAnalyzer.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
352        QAPAlleleFrequencyAnalyzer.BestKnownSolutionParameter.ActualName = BestKnownSolutionParameter.Name;
353        QAPAlleleFrequencyAnalyzer.DistancesParameter.ActualName = DistancesParameter.Name;
354        QAPAlleleFrequencyAnalyzer.MaximizationParameter.ActualName = MaximizationParameter.Name;
355        QAPAlleleFrequencyAnalyzer.ResultsParameter.ActualName = "Results";
356        QAPAlleleFrequencyAnalyzer.SolutionParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
357        QAPAlleleFrequencyAnalyzer.WeightsParameter.ActualName = WeightsParameter.Name;
358      }
359      if (QAPPopulationDiversityAnalyzer != null) {
360        QAPPopulationDiversityAnalyzer.MaximizationParameter.ActualName = MaximizationParameter.Name;
361        QAPPopulationDiversityAnalyzer.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
362        QAPPopulationDiversityAnalyzer.ResultsParameter.ActualName = "Results";
363        QAPPopulationDiversityAnalyzer.SolutionParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
364      }
365    }
366    private void ParameterizeOperators() {
367      foreach (IPermutationCrossover op in Operators.OfType<IPermutationCrossover>()) {
368        op.ParentsParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
369        op.ChildParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
370      }
371      foreach (IPermutationManipulator op in Operators.OfType<IPermutationManipulator>()) {
372        op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
373      }
374      foreach (IPermutationMoveOperator op in Operators.OfType<IPermutationMoveOperator>()) {
375        op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
376      }
377      if (Operators.OfType<IMoveGenerator>().Any()) {
378        if (Operators.OfType<IMoveGenerator>().OfType<IPermutationInversionMoveOperator>().Any()) {
379          string inversionMove = Operators.OfType<IMoveGenerator>().OfType<IPermutationInversionMoveOperator>().First().InversionMoveParameter.ActualName;
380          foreach (IPermutationInversionMoveOperator op in Operators.OfType<IPermutationInversionMoveOperator>())
381            op.InversionMoveParameter.ActualName = inversionMove;
382        }
383        if (Operators.OfType<IMoveGenerator>().OfType<IPermutationTranslocationMoveOperator>().Any()) {
384          string translocationMove = Operators.OfType<IMoveGenerator>().OfType<IPermutationTranslocationMoveOperator>().First().TranslocationMoveParameter.ActualName;
385          foreach (IPermutationTranslocationMoveOperator op in Operators.OfType<IPermutationTranslocationMoveOperator>())
386            op.TranslocationMoveParameter.ActualName = translocationMove;
387        }
388        if (Operators.OfType<IMoveGenerator>().OfType<IPermutationSwap2MoveOperator>().Any()) {
389          string swapMove = Operators.OfType<IMoveGenerator>().OfType<IPermutationSwap2MoveOperator>().First().Swap2MoveParameter.ActualName;
390          foreach (IPermutationSwap2MoveOperator op in Operators.OfType<IPermutationSwap2MoveOperator>()) {
391            op.Swap2MoveParameter.ActualName = swapMove;
392          }
393        }
394      }
395      foreach (var op in Operators.OfType<IPermutationMultiNeighborhoodShakingOperator>())
396        op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
397
398      QAPExhaustiveSwap2LocalImprovement localOpt = Operators.OfType<QAPExhaustiveSwap2LocalImprovement>().SingleOrDefault();
399      if (localOpt != null) {
400        localOpt.AssignmentParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
401        localOpt.DistancesParameter.ActualName = DistancesParameter.Name;
402        localOpt.MaximizationParameter.ActualName = MaximizationParameter.Name;
403        localOpt.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
404        localOpt.WeightsParameter.ActualName = WeightsParameter.Name;
405      }
406
407      QAPSimilarityCalculator similarityCalculator = Operators.OfType<QAPSimilarityCalculator>().SingleOrDefault();
408      if (similarityCalculator != null) {
409        similarityCalculator.SolutionVariableName = SolutionCreator.PermutationParameter.ActualName;
410        similarityCalculator.QualityVariableName = Evaluator.QualityParameter.ActualName;
411      }
412    }
413
414    private void AdjustDistanceMatrix() {
415      if (Distances.Rows != Weights.Rows || Distances.Columns != Weights.Columns) {
416        ((IStringConvertibleMatrix)Distances).Rows = Weights.Rows;
417      }
418    }
419
420    private void AdjustWeightsMatrix() {
421      if (Weights.Rows != Distances.Rows || Weights.Columns != Distances.Columns) {
422        ((IStringConvertibleMatrix)Weights).Rows = Distances.Rows;
423      }
424    }
425
426    private void UpdateParameterValues() {
427      Permutation lbSolution;
428      // calculate the optimum of a LAP relaxation and use it as lower bound of our QAP
429      LowerBound = new DoubleValue(GilmoreLawlerBoundCalculator.CalculateLowerBound(Weights, Distances, out lbSolution));
430      // evalute the LAP optimal solution as if it was a QAP solution
431      var lbSolutionQuality = QAPEvaluator.Apply(lbSolution, Weights, Distances);
432      // in case both qualities are the same it means that the LAP optimum is also a QAP optimum
433      if (LowerBound.Value.IsAlmost(lbSolutionQuality)) {
434        BestKnownSolution = lbSolution;
435        BestKnownQuality = new DoubleValue(LowerBound.Value);
436      }
437      AverageQuality = new DoubleValue(ComputeAverageQuality());
438    }
439
440    private double ComputeAverageQuality() {
441      double rt = 0, rd = 0, wt = 0, wd = 0;
442      int n = Weights.Rows;
443      for (int i = 0; i < n; i++)
444        for (int j = 0; j < n; j++) {
445          if (i == j) {
446            rd += Distances[i, i];
447            wd += Weights[i, i];
448          } else {
449            rt += Distances[i, j];
450            wt += Weights[i, j];
451          }
452        }
453
454      return rt * wt / (n * (n - 1)) + rd * wd / n;
455    }
456    #endregion
457
458    public void Load(QAPData data) {
459      var weights = new DoubleMatrix(data.Weights);
460      var distances = new DoubleMatrix(data.Distances);
461      Name = data.Name;
462      Description = data.Description;
463      Load(weights, distances);
464      if (data.BestKnownQuality.HasValue) BestKnownQuality = new DoubleValue(data.BestKnownQuality.Value);
465      EvaluateAndLoadAssignment(data.BestKnownAssignment);
466      OnReset();
467    }
468
469    public void Load(TSPData data) {
470      if (data.Dimension > 1000)
471        throw new System.IO.InvalidDataException("Instances with more than 1000 customers are not supported by the QAP.");
472      var weights = new DoubleMatrix(data.Dimension, data.Dimension);
473      for (int i = 0; i < data.Dimension; i++)
474        weights[i, (i + 1) % data.Dimension] = 1;
475      var distances = new DoubleMatrix(data.GetDistanceMatrix());
476      Name = data.Name;
477      Description = data.Description;
478      Load(weights, distances);
479      if (data.BestKnownQuality.HasValue) BestKnownQuality = new DoubleValue(data.BestKnownQuality.Value);
480      EvaluateAndLoadAssignment(data.BestKnownTour);
481      OnReset();
482    }
483
484    public void Load(DoubleMatrix weights, DoubleMatrix distances) {
485      if (weights == null || weights.Rows == 0)
486        throw new System.IO.InvalidDataException("The given instance does not contain weights!");
487      if (weights.Rows != weights.Columns)
488        throw new System.IO.InvalidDataException("The weights matrix is not a square matrix!");
489      if (distances == null || distances.Rows == 0)
490        throw new System.IO.InvalidDataException("The given instance does not contain distances!");
491      if (distances.Rows != distances.Columns)
492        throw new System.IO.InvalidDataException("The distances matrix is not a square matrix!");
493      if (weights.Rows != distances.Columns)
494        throw new System.IO.InvalidDataException("The weights matrix and the distance matrix are not of equal size!");
495
496      Weights = weights;
497      Distances = distances;
498
499      BestKnownQuality = null;
500      BestKnownSolution = null;
501      BestKnownSolutions = null;
502      UpdateParameterValues();
503    }
504
505    public void EvaluateAndLoadAssignment(int[] assignment) {
506      if (assignment == null || assignment.Length == 0) return;
507      var vector = new Permutation(PermutationTypes.Absolute, assignment);
508      var result = QAPEvaluator.Apply(vector, Weights, Distances);
509      BestKnownQuality = new DoubleValue(result);
510      BestKnownSolution = vector;
511      BestKnownSolutions = new ItemSet<Permutation>();
512      BestKnownSolutions.Add((Permutation)vector.Clone());
513    }
514  }
515}
Note: See TracBrowser for help on using the repository browser.