Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
09/16/19 11:57:18 (5 years ago)
Author:
abeham
Message:

#2521: made QAP problem data readonly

  • Also refactored instance providers slightly to specify file extension for importing and exporting data and fixing dialogs
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.QuadraticAssignment/3.3/QuadraticAssignmentProblem.cs

    r17232 r17252  
    2525using System.Linq;
    2626using HEAL.Attic;
    27 using HeuristicLab.Analysis;
    2827using HeuristicLab.Common;
    2928using HeuristicLab.Core;
     
    3130using HeuristicLab.Encodings.PermutationEncoding;
    3231using HeuristicLab.Optimization;
    33 using HeuristicLab.Optimization.Operators;
    3432using HeuristicLab.Parameters;
    3533using HeuristicLab.PluginInfrastructure;
     
    4240  public sealed class QuadraticAssignmentProblem : PermutationProblem,
    4341    IProblemInstanceConsumer<QAPData>,
    44     IProblemInstanceConsumer<TSPData> {
     42    IProblemInstanceConsumer<TSPData>, IProblemInstanceExporter<QAPData> {
     43    public static int ProblemSizeLimit = 1000;
    4544
    4645    public static new Image StaticItemImage {
     
    5150
    5251    #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; }
    8358    #endregion
    8459
    8560    #region Properties
    8661    public ItemSet<Permutation> BestKnownSolutions {
    87       get { return bestKnownSolutionsParameter.Value; }
    88       set { bestKnownSolutionsParameter.Value = value; }
     62      get { return BestKnownSolutionsParameter.Value; }
     63      set { BestKnownSolutionsParameter.Value = value; }
    8964    }
    9065    public Permutation BestKnownSolution {
    91       get { return bestKnownSolutionParameter.Value; }
    92       set { bestKnownSolutionParameter.Value = value; }
     66      get { return BestKnownSolutionParameter.Value; }
     67      set { BestKnownSolutionParameter.Value = value; }
    9368    }
    9469    public DoubleMatrix Weights {
    95       get { return weightsParameter.Value; }
    96       set { weightsParameter.Value = value; }
     70      get { return WeightsParameter.Value; }
     71      set { WeightsParameter.Value = value; }
    9772    }
    9873    public DoubleMatrix Distances {
    99       get { return distancesParameter.Value; }
    100       set { distancesParameter.Value = value; }
     74      get { return DistancesParameter.Value; }
     75      set { DistancesParameter.Value = value; }
    10176    }
    10277    public DoubleValue LowerBound {
    103       get { return lowerBoundParameter.Value; }
    104       set { lowerBoundParameter.Value = value; }
     78      get { return LowerBoundParameter.Value; }
     79      set { LowerBoundParameter.Value = value; }
    10580    }
    10681    public DoubleValue AverageQuality {
    107       get { return averageQualityParameter.Value; }
    108       set { averageQualityParameter.Value = value; }
     82      get { return AverageQualityParameter.Value; }
     83      set { AverageQualityParameter.Value = value; }
    10984    }
    11085
     
    11590    private QAPAlleleFrequencyAnalyzer QAPAlleleFrequencyAnalyzer {
    11691      get { return Operators.OfType<QAPAlleleFrequencyAnalyzer>().FirstOrDefault(); }
    117     }
    118 
    119     private QAPPopulationDiversityAnalyzer QAPPopulationDiversityAnalyzer {
    120       get { return Operators.OfType<QAPPopulationDiversityAnalyzer>().FirstOrDefault(); }
    12192    }
    12293    #endregion
     
    12697    private QuadraticAssignmentProblem(QuadraticAssignmentProblem original, Cloner cloner)
    12798      : 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);
    134105      RegisterEventHandlers();
    135106    }
    136107    public QuadraticAssignmentProblem()
    137108      : 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."));
    144115
    145116      WeightsParameter.GetsCollected = false;
     
    150121        { 0, 0, 1, 0, 1 },
    151122        { 1, 0, 0, 1, 0 }
    152       });
     123      }, @readonly: true);
    153124
    154125      DistancesParameter.GetsCollected = false;
     
    159130        { 582, 582, 360,   0, 360 },
    160131        { 360, 582, 582, 360,   0 }
    161       });
     132      }, @readonly: true);
    162133
    163134      InitializeOperators();
     
    187158      // BackwardsCompatibility3.3
    188159      #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"];
    201172      #endregion
    202173      RegisterEventHandlers();
     
    204175
    205176    #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    }
    211181    protected override void OnEvaluatorChanged() {
    212182      Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged;
     
    217187      Parameterize();
    218188    }
    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     }
    265189    #endregion
    266190
    267191    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;
    276197    }
    277198
    278199    #region Helpers
    279200    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);
    286201      Operators.AddRange(ApplicationManager.Manager.GetInstances<IQAPMoveEvaluator>());
    287202      Operators.AddRange(ApplicationManager.Manager.GetInstances<IQAPLocalImprovementOperator>());
     
    289204      Operators.Add(new QAPAlleleFrequencyAnalyzer());
    290205
    291       Operators.Add(new HammingSimilarityCalculator());
    292206      Operators.Add(new QAPSimilarityCalculator());
    293       Operators.Add(new QualitySimilarityCalculator());
    294       Operators.Add(new PopulationSimilarityAnalyzer(Operators.OfType<ISolutionSimilarityCalculator>()));
    295207      Parameterize();
    296208    }
     
    314226        QAPAlleleFrequencyAnalyzer.WeightsParameter.ActualName = WeightsParameter.Name;
    315227      }
    316       if (QAPPopulationDiversityAnalyzer != null) {
    317         operators.Add(QAPPopulationDiversityAnalyzer);
    318         QAPPopulationDiversityAnalyzer.MaximizationParameter.ActualName = MaximizationParameter.Name;
    319         QAPPopulationDiversityAnalyzer.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
    320       }
    321228      foreach (var localOpt in Operators.OfType<IQAPLocalImprovementOperator>()) {
    322229        operators.Add(localOpt);
     
    359266      }
    360267      foreach (var similarityCalculator in Operators.OfType<ISolutionSimilarityCalculator>()) {
     268        operators.Add(similarityCalculator);
    361269        similarityCalculator.SolutionVariableName = Encoding.Name;
    362270        similarityCalculator.QualityVariableName = Evaluator.QualityParameter.ActualName;
     
    369277
    370278      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       }
    385279    }
    386280
     
    418312
    419313    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);
    422317      Name = data.Name;
    423318      Description = data.Description;
     
    429324
    430325    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];
    434328      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);
    437332      Name = data.Name;
    438333      Description = data.Description;
     
    473368      BestKnownSolutions = new ItemSet<Permutation> { (Permutation)vector.Clone() };
    474369    }
     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    }
    475382  }
    476383}
Note: See TracChangeset for help on using the changeset viewer.