Changeset 17248


Ignore:
Timestamp:
09/11/19 21:35:59 (12 days ago)
Author:
abeham
Message:

#2521: working on TSP refactoring

Location:
branches/2521_ProblemRefactoring
Files:
9 added
4 deleted
7 edited

Legend:

Unmodified
Added
Removed
  • branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/DoubleMatrix.cs

    r17226 r17248  
    2222using System.Collections.Generic;
    2323using System.Text;
     24using HEAL.Attic;
    2425using HeuristicLab.Common;
    2526using HeuristicLab.Core;
    26 using HEAL.Attic;
    2727
    2828namespace HeuristicLab.Data {
     
    3939    public DoubleMatrix(int rows, int columns, IEnumerable<string> columnNames) : base(rows, columns, columnNames) { }
    4040    public DoubleMatrix(int rows, int columns, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(rows, columns, columnNames, rowNames) { }
    41     public DoubleMatrix(double[,] elements) : base(elements) { }
    42     public DoubleMatrix(double[,] elements, IEnumerable<string> columnNames) : base(elements, columnNames) { }
    43     public DoubleMatrix(double[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(elements, columnNames, rowNames) { }
     41    public DoubleMatrix(double[,] elements, bool @readonly = false) : base(elements, @readonly) { }
     42    public DoubleMatrix(double[,] elements, IEnumerable<string> columnNames, bool @readonly = false) : base(elements, columnNames, @readonly) { }
     43    public DoubleMatrix(double[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames, bool @readonly = false) : base(elements, columnNames, rowNames, @readonly) { }
    4444
    4545    public override IDeepCloneable Clone(Cloner cloner) {
  • branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/ValueTypeMatrix.cs

    r17226 r17248  
    2626using System.Linq;
    2727using System.Text;
     28using HEAL.Attic;
    2829using HeuristicLab.Common;
    2930using HeuristicLab.Core;
    30 using HEAL.Attic;
    3131
    3232namespace HeuristicLab.Data {
     
    172172      RowNames = rowNames;
    173173    }
    174     protected ValueTypeMatrix(T[,] elements) {
     174    protected ValueTypeMatrix(T[,] elements, bool @readonly = false) {
    175175      if (elements == null) throw new ArgumentNullException();
    176176      matrix = (T[,])elements.Clone();
     
    178178      rowNames = new List<string>();
    179179      sortableView = false;
    180       readOnly = false;
    181     }
    182     protected ValueTypeMatrix(T[,] elements, IEnumerable<string> columnNames)
    183       : this(elements) {
     180      readOnly = @readonly;
     181    }
     182    protected ValueTypeMatrix(T[,] elements, IEnumerable<string> columnNames, bool @readonly = false)
     183      : this(elements, @readonly) {
    184184      ColumnNames = columnNames;
    185185    }
    186     protected ValueTypeMatrix(T[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames)
    187       : this(elements, columnNames) {
     186    protected ValueTypeMatrix(T[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames, bool @readonly = false)
     187      : this(elements, columnNames, @readonly) {
    188188      RowNames = rowNames;
    189189    }
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman.Views/3.3/HeuristicLab.Problems.TravelingSalesman.Views-3.3.csproj

    r17241 r17248  
    105105  </PropertyGroup>
    106106  <ItemGroup>
     107    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     108    <Reference Include="Microsoft.CSharp" />
    107109    <Reference Include="System" />
    108110    <Reference Include="System.Core">
     
    121123  </ItemGroup>
    122124  <ItemGroup>
    123     <Compile Include="PathTSPTourView.cs">
     125    <Compile Include="MatrixTSPDataView.cs">
    124126      <SubType>UserControl</SubType>
    125127    </Compile>
    126     <Compile Include="PathTSPTourView.Designer.cs">
    127       <DependentUpon>PathTSPTourView.cs</DependentUpon>
     128    <Compile Include="MatrixTSPDataView.Designer.cs">
     129      <DependentUpon>MatrixTSPDataView.cs</DependentUpon>
     130    </Compile>
     131    <Compile Include="TSPSolutionView.cs">
     132      <SubType>UserControl</SubType>
     133    </Compile>
     134    <Compile Include="TSPSolutionView.Designer.cs">
     135      <DependentUpon>TSPSolutionView.cs</DependentUpon>
    128136    </Compile>
    129137    <Compile Include="Plugin.cs" />
     
    173181      <Private>False</Private>
    174182    </ProjectReference>
     183    <ProjectReference Include="..\..\HeuristicLab.Data.Views\3.3\HeuristicLab.Data.Views-3.3.csproj">
     184      <Project>{72104A0B-90E7-42F3-9ABE-9BBBADD4B943}</Project>
     185      <Name>HeuristicLab.Data.Views-3.3</Name>
     186    </ProjectReference>
    175187    <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
    176188      <Project>{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}</Project>
     
    223235      <Private>False</Private>
    224236    </ProjectReference>
     237  </ItemGroup>
     238  <ItemGroup>
     239    <EmbeddedResource Include="MatrixTSPDataView.resx">
     240      <DependentUpon>MatrixTSPDataView.cs</DependentUpon>
     241    </EmbeddedResource>
     242    <EmbeddedResource Include="TSPSolutionView.resx">
     243      <DependentUpon>TSPSolutionView.cs</DependentUpon>
     244    </EmbeddedResource>
    225245  </ItemGroup>
    226246  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/HeuristicLab.Problems.TravelingSalesman-3.3.csproj

    r17241 r17248  
    120120    <Compile Include="Analyzers\TSPAlleleFrequencyAnalyzer.cs" />
    121121    <Compile Include="Improvers\TSPImprovementOperator.cs" />
    122     <Compile Include="MoveEvaluators\ThreeOpt\TSPTranslocationMoveEvaluator.cs" />
     122    <Compile Include="MoveEvaluators\TSPTranslocationMoveEvaluator.cs" />
    123123    <Compile Include="MoveEvaluators\TSPMoveEvaluator.cs" />
    124     <Compile Include="MoveEvaluators\TwoOpt\TSPInversionMoveEvaluator.cs" />
     124    <Compile Include="MoveEvaluators\TSPInversionMoveEvaluator.cs" />
    125125    <Compile Include="PathRelinkers\TSPMultipleGuidesPathRelinker.cs" />
    126126    <Compile Include="PathRelinkers\TSPPathRelinker.cs" />
     
    130130    <Compile Include="TSP.cs" />
    131131    <Compile Include="TSPData.cs" />
     132    <Compile Include="TSPSolution.cs" />
    132133  </ItemGroup>
    133134  <ItemGroup>
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TSPMoveEvaluator.cs

    r17241 r17248  
    55using HeuristicLab.Encodings.PermutationEncoding;
    66using HeuristicLab.Operators;
     7using HeuristicLab.Optimization;
    78using HeuristicLab.Parameters;
    89
    910namespace HeuristicLab.Problems.TravelingSalesman {
    1011  [StorableType("17477ad2-2c84-4b02-b5ac-f35ef6cc667f")]
    11   public interface ITSPMoveEvaluator : IOperator {
     12  public interface ITSPMoveEvaluator : IOperator, ISingleObjectiveMoveEvaluator, IMoveOperator {
    1213    ILookupParameter<Permutation> TSPTourParameter { get; }
    1314    ILookupParameter<ITSPData> TSPDataParameter { get; }
     
    2324    [Storable] public ILookupParameter<DoubleValue> TourLengthParameter { get; private set; }
    2425    [Storable] public ILookupParameter<DoubleValue> TourLengthWithMoveParameter { get; private set; }
     26
     27    ILookupParameter<DoubleValue> ISingleObjectiveMoveEvaluator.QualityParameter => TourLengthParameter;
     28    ILookupParameter<DoubleValue> ISingleObjectiveMoveEvaluator.MoveQualityParameter => TourLengthWithMoveParameter;
    2529
    2630    [StorableConstructor]
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/TSP.cs

    r17241 r17248  
    1 using System;
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 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;
    224using System.Linq;
    325using HEAL.Attic;
     
    2547
    2648    [Storable] public IValueParameter<ITSPData> TSPDataParameter { get; private set; }
    27     [Storable] public IValueParameter<Permutation> BestKnownSolutionParameter { get; private set; }
     49    [Storable] public IValueParameter<ITSPSolution> BestKnownSolutionParameter { get; private set; }
    2850
    2951    public ITSPData TSPData {
     
    3153      set { TSPDataParameter.Value = value; }
    3254    }
    33     public Permutation BestKnownSolution {
     55    public ITSPSolution BestKnownSolution {
    3456      get { return BestKnownSolutionParameter.Value; }
    3557      set { BestKnownSolutionParameter.Value = value; }
     
    4769    public TSP() : base(new PermutationEncoding("Tour", 16, PermutationTypes.RelativeUndirected)) {
    4870      Parameters.Add(TSPDataParameter = new ValueParameter<ITSPData>("TSPData", "The main parameters of the TSP."));
    49       Parameters.Add(BestKnownSolutionParameter = new OptionalValueParameter<Permutation>("BestKnownSolution", "The best known solution."));
     71      Parameters.Add(BestKnownSolutionParameter = new OptionalValueParameter<ITSPSolution>("BestKnownSolution", "The best known solution."));
    5072     
    5173      TSPData = new EuclideanTSPData() {
     
    85107        i = qualities.Select((x, index) => new { index, Fitness = x }).OrderBy(x => x.Fitness).First().index;
    86108      else i = qualities.Select((x, index) => new { index, Fitness = x }).OrderByDescending(x => x.Fitness).First().index;
     109      var solution = TSPData.GetSolution(solutions[i], qualities[i]);
    87110
    88111      if (double.IsNaN(BestKnownQuality) ||
    89112          Maximization && qualities[i] > BestKnownQuality ||
    90113          !Maximization && qualities[i] < BestKnownQuality) {
    91         BestKnownQualityParameter.ActualValue = new DoubleValue(qualities[i]);
    92         BestKnownSolutionParameter.ActualValue = (Permutation)solutions[i].Clone();
    93       }
    94 
    95       var solution = TSPData.GetSolution(solutions[i], qualities[i]);
     114        BestKnownQualityParameter.Value = new DoubleValue(qualities[i]);
     115        BestKnownSolutionParameter.Value = solution;
     116      }
    96117      results.AddOrUpdateResult("Best TSP Solution", solution);
     118    }
     119
     120    public override IEnumerable<Permutation> GetNeighbors(Permutation solution, IRandom random) {
     121      foreach (var move in ExhaustiveInversionMoveGenerator.Generate(solution)) {
     122        var clone = (Permutation)solution.Clone();
     123        InversionManipulator.Apply(clone, move.Index1, move.Index2);
     124        yield return clone;
     125      }
    97126    }
    98127
     
    141170      if (data.BestKnownTour != null) {
    142171        try {
    143           BestKnownSolution = new Permutation(PermutationTypes.RelativeUndirected, data.BestKnownTour);
    144           BestKnownQuality = Evaluate(BestKnownSolution);
     172          var tour = new Permutation(PermutationTypes.RelativeUndirected, data.BestKnownTour);
     173          var tourLength = Evaluate(tour);
     174          BestKnownSolution = new TSPSolution(data.Coordinates != null ? new DoubleMatrix(data.Coordinates) : null, tour, new DoubleValue(tourLength));
     175          BestKnownQuality = tourLength;
    145176        } catch (InvalidOperationException) {
    146177          if (data.BestKnownQuality.HasValue)
     
    170201
    171202      Operators.Add(new TSPAlleleFrequencyAnalyzer());
    172       foreach (var op in ApplicationManager.Manager.GetInstances<ITSPMoveEvaluator>())
     203      foreach (var op in ApplicationManager.Manager.GetInstances<ITSPMoveEvaluator>()) {
     204        Encoding.ConfigureOperator(op);
    173205        Operators.Add(op);
    174 
     206      }
    175207      ParameterizeOperators();
    176208    }
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/TSPData.cs

    r17241 r17248  
    1 using System;
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 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;
    223using System.ComponentModel;
    3 using System.Drawing;
    424using HEAL.Attic;
    525using HeuristicLab.Common;
     
    1535  }
    1636
    17   [StorableType("f08a63d9-0b83-4944-9251-42925baeb872")]
    18   public interface ITSPSolution : IItem {
    19     DoubleMatrix Coordinates { get; }
    20     Permutation Tour { get; }
    21     DoubleValue TourLength { get; }
    22   }
    23 
    2437  [Item("Matrix-based TSP Data", "TSP that is representd by a distance matrix.")]
    2538  [StorableType("4df58a35-679d-4414-b815-9450ae100823")]
    26   public class MatrixTSPData : Item, ITSPData {
    27     [Storable]
    28     private double[,] Matrix { get; set; }
    29 
    30     [Storable]
    31     public DoubleMatrix DisplayCoordinates { get; set; }
    32 
    33     [StorableConstructor]
    34     protected MatrixTSPData(StorableConstructorFlag _) : base(_) { }
    35     protected MatrixTSPData(MatrixTSPData original, Cloner cloner) : base(original, cloner) {
     39  public sealed class MatrixTSPData : Item, ITSPData, INotifyPropertyChanged {
     40
     41    [Storable]
     42    public DoubleMatrix Matrix { get; private set; }
     43
     44    [Storable]
     45    private DoubleMatrix displayCoordinates;
     46    public DoubleMatrix DisplayCoordinates {
     47      get => displayCoordinates;
     48      set {
     49        if (displayCoordinates == value) return;
     50        displayCoordinates = value;
     51        OnPropertyChanged(nameof(DisplayCoordinates));
     52      }
     53    }
     54
     55    [StorableConstructor]
     56    private MatrixTSPData(StorableConstructorFlag _) : base(_) { }
     57    private MatrixTSPData(MatrixTSPData original, Cloner cloner) : base(original, cloner) {
    3658      Matrix = original.Matrix;
    37       DisplayCoordinates = cloner.Clone(original.DisplayCoordinates);
     59      displayCoordinates = cloner.Clone(original.displayCoordinates);
    3860    }
    3961    public MatrixTSPData() {
    40       Matrix = new double[0, 0];
     62      Matrix = new DoubleMatrix(new double[0, 0], @readonly: true);
    4163      DisplayCoordinates = null;
    4264    }
    4365    public MatrixTSPData(double[,] matrix, double[,] coordinates = null) {
    44       Matrix = (double[,])matrix.Clone();
     66      Matrix = new DoubleMatrix(matrix, @readonly: true);
    4567      if (coordinates != null) DisplayCoordinates = new DoubleMatrix(coordinates);
    4668      if (DisplayCoordinates != null && DisplayCoordinates.Columns != 2)
    4769        throw new ArgumentException("Argument must have exactly two columns.", nameof(coordinates));
    48       if (DisplayCoordinates != null && DisplayCoordinates.Rows != Matrix.GetLength(0))
     70      if (DisplayCoordinates != null && DisplayCoordinates.Rows != Matrix.Rows)
    4971        throw new ArgumentException("Unequal number of rows in " + nameof(matrix) + " and " + nameof(coordinates) + ".");
    5072    }
    5173
    5274    public ITSPSolution GetSolution(Permutation tour, double tourLength) {
    53       return new PathTSPTour(DisplayCoordinates, tour, new DoubleValue(tourLength));
     75      return new TSPSolution(DisplayCoordinates, tour, new DoubleValue(tourLength));
    5476    }
    5577
     
    5981
    6082    public void SetMatrix(double[,] matrix, double[,] coordinates = null) {
    61       Matrix = (double[,])matrix.Clone();
     83      Matrix = new DoubleMatrix(matrix, @readonly: true);
     84      OnPropertyChanged(nameof(Matrix));
    6285      if (coordinates == null) DisplayCoordinates = null;
    6386      else DisplayCoordinates = new DoubleMatrix(coordinates);
    6487      if (DisplayCoordinates != null && DisplayCoordinates.Columns != 2)
    6588        throw new ArgumentException("Argument must have exactly two columns.", nameof(coordinates));
    66       if (DisplayCoordinates != null && DisplayCoordinates.Rows != Matrix.GetLength(0))
     89      if (DisplayCoordinates != null && DisplayCoordinates.Rows != Matrix.Rows)
    6790        throw new ArgumentException("Unequal number of rows in " + nameof(matrix) + " and " + nameof(coordinates) + ".");
    6891    }
    6992
    70     public void SetMatrix(ValueTypeMatrix<double> matrix, DoubleMatrix coordinates = null) {
    71       Matrix = matrix.CloneAsMatrix();
     93    public void SetMatrix(DoubleMatrix matrix, DoubleMatrix coordinates = null) {
     94      Matrix = (DoubleMatrix)matrix.AsReadOnly();
     95      OnPropertyChanged(nameof(Matrix));
    7296      DisplayCoordinates = (DoubleMatrix)coordinates?.Clone();
    7397      if (DisplayCoordinates != null && DisplayCoordinates.Columns != 2)
    7498        throw new ArgumentException("Argument must have exactly two columns.", nameof(coordinates));
    75       if (DisplayCoordinates != null && DisplayCoordinates.Rows != Matrix.GetLength(0))
     99      if (DisplayCoordinates != null && DisplayCoordinates.Rows != Matrix.Rows)
    76100        throw new ArgumentException("Unequal number of rows in " + nameof(matrix) + " and " + nameof(coordinates) + ".");
    77101    }
    78102
    79103    public double GetDistance(int fromCity, int toCity) => Matrix[fromCity, toCity];
     104
     105
     106    public event PropertyChangedEventHandler PropertyChanged;
     107    private void OnPropertyChanged(string property) {
     108      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
     109    }
    80110  }
    81111
     
    108138
    109139    public ITSPSolution GetSolution(Permutation tour, double tourLength) {
    110       return new PathTSPTour(Coordinates, tour, new DoubleValue(tourLength));
     140      return new TSPSolution(Coordinates, tour, new DoubleValue(tourLength));
    111141    }
    112142  }
     
    181211    }
    182212  }
    183   /// <summary>
    184   /// Represents a tour of a Traveling Salesman Problem given in path representation which can be visualized in the GUI.
    185   /// </summary>
    186   [Item("PathTSPTour", "Represents a tour of a Traveling Salesman Problem given in path representation which can be visualized in the GUI.")]
    187   [StorableType("2CAE7C49-751B-4802-9025-62E2268E47AE")]
    188   public sealed class PathTSPTour : Item, ITSPSolution, INotifyPropertyChanged {
    189     public static new Image StaticItemImage {
    190       get { return HeuristicLab.Common.Resources.VSImageLibrary.Image; }
    191     }
    192 
    193     [Storable]
    194     private DoubleMatrix coordinates;
    195     public DoubleMatrix Coordinates {
    196       get { return coordinates; }
    197       set {
    198         if (coordinates == value) return;
    199         coordinates = value;
    200         OnPropertyChanged(nameof(Coordinates));
    201       }
    202     }
    203 
    204     [Storable(Name = "tour", OldName = "permutation")]
    205     private Permutation tour;
    206     public Permutation Tour {
    207       get { return tour; }
    208       set {
    209         if (tour == value) return;
    210         tour = value;
    211         OnPropertyChanged(nameof(Tour));
    212       }
    213     }
    214     [Storable(Name = "tourLength", OldName = "quality")]
    215     private DoubleValue tourLength;
    216     public DoubleValue TourLength {
    217       get { return tourLength; }
    218       set {
    219         if (tourLength == value) return;
    220         tourLength = value;
    221         OnPropertyChanged(nameof(TourLength));
    222       }
    223     }
    224 
    225     [StorableConstructor]
    226     private PathTSPTour(StorableConstructorFlag _) : base(_) { }
    227     private PathTSPTour(PathTSPTour original, Cloner cloner)
    228       : base(original, cloner) {
    229       this.coordinates = cloner.Clone(original.coordinates);
    230       this.tour = cloner.Clone(original.tour);
    231       this.tourLength = cloner.Clone(original.tourLength);
    232     }
    233     public PathTSPTour() : base() { }
    234     public PathTSPTour(DoubleMatrix coordinates)
    235       : base() {
    236       this.coordinates = coordinates;
    237     }
    238     public PathTSPTour(DoubleMatrix coordinates, Permutation permutation)
    239       : base() {
    240       this.coordinates = coordinates;
    241       this.tour = permutation;
    242     }
    243     public PathTSPTour(DoubleMatrix coordinates, Permutation permutation, DoubleValue quality)
    244       : base() {
    245       this.coordinates = coordinates;
    246       this.tour = permutation;
    247       this.tourLength = quality;
    248     }
    249 
    250     public override IDeepCloneable Clone(Cloner cloner) {
    251       return new PathTSPTour(this, cloner);
    252     }
    253 
    254     public event PropertyChangedEventHandler PropertyChanged;
    255     private void OnPropertyChanged(string property) {
    256       PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
    257     }
    258   }
    259213}
Note: See TracChangeset for help on using the changeset viewer.