Changeset 4825


Ignore:
Timestamp:
11/17/10 07:41:28 (8 years ago)
Author:
swagner
Message:

Fixed memory leak when using parameters whose values are not deeply cloned (#1268)

Location:
trunk/sources
Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Optimization/3.3/Run.cs

    r4722 r4825  
    2323using System.Collections.Generic;
    2424using System.Drawing;
     25using System.Linq;
    2526using HeuristicLab.Common;
    2627using HeuristicLab.Core;
     
    8788
    8889    private void Initialize(IAlgorithm algorithm) {
    89       IAlgorithm clone = (IAlgorithm)algorithm.Clone();
    9090      parameters = new Dictionary<string, IItem>();
    9191      results = new Dictionary<string, IItem>();
    92       clone.CollectParameterValues(parameters);
    93       clone.CollectResultValues(results);
    94       if (clone.StoreAlgorithmInEachRun) {
     92
     93      if (algorithm.StoreAlgorithmInEachRun) {
     94        IAlgorithm clone = (IAlgorithm)algorithm.Clone();
     95        clone.CollectParameterValues(parameters);
     96        clone.CollectResultValues(results);
    9597        clone.Prepare(true);
    9698        this.algorithm = clone;
     99      } else {
     100        algorithm.CollectParameterValues(parameters);
     101        algorithm.CollectResultValues(results);
     102        Cloner cloner = new Cloner();
     103        parameters = parameters.Select(x => new KeyValuePair<string, IItem>(x.Key, (IItem)x.Value.Clone(cloner))).ToDictionary(x => x.Key, x => x.Value);
     104        results = results.Select(x => new KeyValuePair<string, IItem>(x.Key, (IItem)x.Value.Clone(cloner))).ToDictionary(x => x.Key, x => x.Value);
    97105      }
    98106    }
  • trunk/sources/HeuristicLab.Parameters/3.3/OptionalValueParameter.cs

    r4722 r4825  
    7878    }
    7979
     80    [Storable(DefaultValue = true)]
     81    private bool reactOnValueToStringChangedAndValueItemImageChanged;
     82    /// <summary>
     83    ///   True if this parameter should react on the ToStringChanged and ItemImageChanged events of its value, otherwise false.
     84    /// </summary>
     85    /// <remarks>
     86    ///   In some rare cases when the value of the parameter is not deeply cloned, this property has to be set to false
     87    ///   to avoid a memory leak (cf. ticket #1268). In all other cases this property should always be true.
     88    /// </remarks>
     89    public bool ReactOnValueToStringChangedAndValueItemImageChanged {
     90      get { return reactOnValueToStringChangedAndValueItemImageChanged; }
     91      set {
     92        if (value != reactOnValueToStringChangedAndValueItemImageChanged) {
     93          reactOnValueToStringChangedAndValueItemImageChanged = value;
     94          if (reactOnValueToStringChangedAndValueItemImageChanged)
     95            RegisterValueEvents();
     96          else
     97            DeregisterValueEvents();
     98        }
     99      }
     100    }
     101
    80102    #region Constructors
    81103    [StorableConstructor]
     
    85107      value = cloner.Clone(original.value);
    86108      getsCollected = original.getsCollected;
     109      reactOnValueToStringChangedAndValueItemImageChanged = original.reactOnValueToStringChangedAndValueItemImageChanged;
    87110      RegisterValueEvents();
    88111    }
     
    90113      : base("Anonymous", typeof(T)) {
    91114      this.getsCollected = true;
     115      this.reactOnValueToStringChangedAndValueItemImageChanged = true;
    92116    }
    93117    public OptionalValueParameter(string name)
    94118      : base(name, typeof(T)) {
    95119      this.getsCollected = true;
     120      this.reactOnValueToStringChangedAndValueItemImageChanged = true;
    96121    }
    97122    public OptionalValueParameter(string name, bool getsCollected)
    98123      : base(name, typeof(T)) {
    99124      this.getsCollected = getsCollected;
     125      this.reactOnValueToStringChangedAndValueItemImageChanged = true;
    100126    }
    101127    public OptionalValueParameter(string name, T value)
     
    103129      this.value = value;
    104130      this.getsCollected = true;
     131      this.reactOnValueToStringChangedAndValueItemImageChanged = true;
    105132      RegisterValueEvents();
    106133    }
     
    109136      this.value = value;
    110137      this.getsCollected = getsCollected;
     138      this.reactOnValueToStringChangedAndValueItemImageChanged = true;
    111139      RegisterValueEvents();
    112140    }
     
    114142      : base(name, description, typeof(T)) {
    115143      this.getsCollected = true;
     144      this.reactOnValueToStringChangedAndValueItemImageChanged = true;
    116145    }
    117146    public OptionalValueParameter(string name, string description, bool getsCollected)
    118147      : base(name, description, typeof(T)) {
    119148      this.getsCollected = getsCollected;
     149      this.reactOnValueToStringChangedAndValueItemImageChanged = true;
    120150    }
    121151    public OptionalValueParameter(string name, string description, T value)
     
    123153      this.value = value;
    124154      this.getsCollected = true;
     155      this.reactOnValueToStringChangedAndValueItemImageChanged = true;
    125156      RegisterValueEvents();
    126157    }
     
    129160      this.value = value;
    130161      this.getsCollected = getsCollected;
     162      this.reactOnValueToStringChangedAndValueItemImageChanged = true;
    131163      RegisterValueEvents();
    132164    }
     
    143175
    144176    public override string ToString() {
    145       return Name + ": " + (Value != null ? Value.ToString() : "null");
     177      if (reactOnValueToStringChangedAndValueItemImageChanged)
     178        return Name + ": " + (Value != null ? Value.ToString() : "null");
     179      else
     180        return Name;
    146181    }
    147182
     
    167202
    168203    private void RegisterValueEvents() {
    169       if (value != null) {
     204      if ((value != null) && reactOnValueToStringChangedAndValueItemImageChanged) {
    170205        value.ItemImageChanged += new EventHandler(Value_ItemImageChanged);
    171206        value.ToStringChanged += new EventHandler(Value_ToStringChanged);
  • trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/Evaluators/TSPCoordinatesPathEvaluator.cs

    r4722 r4825  
    4040      get { return (ILookupParameter<DoubleMatrix>)Parameters["Coordinates"]; }
    4141    }
    42     public ILookupParameter<DoubleMatrix> DistanceMatrixParameter {
    43       get { return (ILookupParameter<DoubleMatrix>)Parameters["DistanceMatrix"]; }
     42    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
     43      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
    4444    }
    4545    public ILookupParameter<BoolValue> UseDistanceMatrixParameter {
     
    5454      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The TSP solution given in path representation which should be evaluated."));
    5555      Parameters.Add(new LookupParameter<DoubleMatrix>("Coordinates", "The x- and y-Coordinates of the cities."));
    56       Parameters.Add(new LookupParameter<DoubleMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
     56      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
    5757      Parameters.Add(new LookupParameter<BoolValue>("UseDistanceMatrix", "True if a distance matrix should be calculated and used for evaluation, otherwise false."));
     58    }
     59
     60    [StorableHook(HookType.AfterDeserialization)]
     61    private void AfterDeserialization() {
     62      // BackwardsCompatibility3.3
     63      #region Backwards compatible code (remove with 3.4)
     64      LookupParameter<DoubleMatrix> oldDistanceMatrixParameter = Parameters["DistanceMatrix"] as LookupParameter<DoubleMatrix>;
     65      if (oldDistanceMatrixParameter != null) {
     66        Parameters.Remove(oldDistanceMatrixParameter);
     67        Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
     68        DistanceMatrixParameter.ActualName = oldDistanceMatrixParameter.ActualName;
     69      }
     70      #endregion
    5871    }
    5972
     
    6174      if (UseDistanceMatrixParameter.ActualValue.Value) {
    6275        Permutation p = PermutationParameter.ActualValue;
    63         DoubleMatrix dm = DistanceMatrixParameter.ActualValue;
     76        DistanceMatrix dm = DistanceMatrixParameter.ActualValue;
    6477
    6578        if (dm == null) {  // calculate distance matrix
    6679          DoubleMatrix c = CoordinatesParameter.ActualValue;
    6780
    68           dm = new DoubleMatrix(c.Rows, c.Rows);
     81          dm = new DistanceMatrix(c.Rows, c.Rows);
    6982          for (int i = 0; i < dm.Rows; i++) {
    7083            for (int j = 0; j < dm.Columns; j++)
    7184              dm[i, j] = CalculateDistance(c[i, 0], c[i, 1], c[j, 0], c[j, 1]);
    7285          }
    73           DistanceMatrixParameter.ActualValue = (DoubleMatrix)dm.AsReadOnly();
     86          DistanceMatrixParameter.ActualValue = (DistanceMatrix)dm.AsReadOnly();
    7487        }
    7588
  • trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/HeuristicLab.Problems.TravelingSalesman-3.3.csproj

    r4703 r4825  
    109109    <Compile Include="Analyzers\TSPPopulationDiversityAnalyzer.cs" />
    110110    <Compile Include="Analyzers\TSPAlleleFrequencyAnalyzer.cs" />
     111    <Compile Include="DistanceMatrix.cs" />
    111112    <Compile Include="Evaluators\TSPEuclideanPathEvaluator.cs" />
    112113    <Compile Include="Evaluators\TSPGeoPathEvaluator.cs" />
  • trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPCoordinatesPathEvaluator.cs

    r4068 r4825  
    2929  public interface ITSPCoordinatesPathEvaluator : ITSPPathEvaluator {
    3030    ILookupParameter<DoubleMatrix> CoordinatesParameter { get; }
    31     ILookupParameter<DoubleMatrix> DistanceMatrixParameter { get; }
     31    ILookupParameter<DistanceMatrix> DistanceMatrixParameter { get; }
    3232    ILookupParameter<BoolValue> UseDistanceMatrixParameter { get; }
    3333  }
  • trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPPathMoveEvaluator.cs

    r4068 r4825  
    2727  public interface ITSPPathMoveEvaluator : ITSPMoveEvaluator, IPermutationMoveOperator {
    2828    ILookupParameter<DoubleMatrix> CoordinatesParameter { get; }
    29     ILookupParameter<DoubleMatrix> DistanceMatrixParameter { get; }
     29    ILookupParameter<DistanceMatrix> DistanceMatrixParameter { get; }
    3030    ILookupParameter<BoolValue> UseDistanceMatrixParameter { get; }
    3131  }
  • trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TSPPathMoveEvaluator.cs

    r4722 r4825  
    4040      get { return (ILookupParameter<DoubleMatrix>)Parameters["Coordinates"]; }
    4141    }
    42     public ILookupParameter<DoubleMatrix> DistanceMatrixParameter {
    43       get { return (ILookupParameter<DoubleMatrix>)Parameters["DistanceMatrix"]; }
     42    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
     43      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
    4444    }
    4545    public ILookupParameter<BoolValue> UseDistanceMatrixParameter {
     
    5454      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
    5555      Parameters.Add(new LookupParameter<DoubleMatrix>("Coordinates", "The city's coordinates."));
    56       Parameters.Add(new LookupParameter<DoubleMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
     56      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
    5757      Parameters.Add(new LookupParameter<BoolValue>("UseDistanceMatrix", "True if a distance matrix should be calculated (if it does not exist already) and used for evaluation, otherwise false."));
     58    }
     59
     60    [StorableHook(HookType.AfterDeserialization)]
     61    private void AfterDeserialization() {
     62      // BackwardsCompatibility3.3
     63      #region Backwards compatible code (remove with 3.4)
     64      LookupParameter<DoubleMatrix> oldDistanceMatrixParameter = Parameters["DistanceMatrix"] as LookupParameter<DoubleMatrix>;
     65      if (oldDistanceMatrixParameter != null) {
     66        Parameters.Remove(oldDistanceMatrixParameter);
     67        Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
     68        DistanceMatrixParameter.ActualName = oldDistanceMatrixParameter.ActualName;
     69      }
     70      #endregion
    5871    }
    5972
     
    6376      double relativeQualityDifference = 0;
    6477      if (UseDistanceMatrixParameter.ActualValue.Value) {
    65         DoubleMatrix distanceMatrix = DistanceMatrixParameter.ActualValue;
     78        DistanceMatrix distanceMatrix = DistanceMatrixParameter.ActualValue;
    6679        if (distanceMatrix == null) {
    6780          distanceMatrix = CalculateDistanceMatrix(coordinates);
     
    7790
    7891    protected abstract double CalculateDistance(double x1, double y1, double x2, double y2);
    79     protected abstract double EvaluateByDistanceMatrix(Permutation permutation, DoubleMatrix distanceMatrix);
     92    protected abstract double EvaluateByDistanceMatrix(Permutation permutation, DistanceMatrix distanceMatrix);
    8093    protected abstract double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates);
    8194
    82     private DoubleMatrix CalculateDistanceMatrix(DoubleMatrix c) {
    83       DoubleMatrix distanceMatrix = new DoubleMatrix(c.Rows, c.Rows);
     95    private DistanceMatrix CalculateDistanceMatrix(DoubleMatrix c) {
     96      DistanceMatrix distanceMatrix = new DistanceMatrix(c.Rows, c.Rows);
    8497      for (int i = 0; i < distanceMatrix.Rows; i++) {
    8598        for (int j = 0; j < distanceMatrix.Columns; j++)
    8699          distanceMatrix[i, j] = CalculateDistance(c[i, 0], c[i, 1], c[j, 0], c[j, 1]);
    87100      }
    88       return distanceMatrix;
     101      return (DistanceMatrix)distanceMatrix.AsReadOnly();
    89102    }
    90103  }
  • trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMovePathEvaluator.cs

    r4722 r4825  
    8282    }
    8383
    84     protected override double EvaluateByDistanceMatrix(Permutation permutation, DoubleMatrix distanceMatrix) {
     84    protected override double EvaluateByDistanceMatrix(Permutation permutation, DistanceMatrix distanceMatrix) {
    8585      TranslocationMove move = TranslocationMoveParameter.ActualValue;
    8686      int edge1source = permutation.GetCircular(move.Index1 - 1);
  • trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMovePathEvaluator.cs

    r4722 r4825  
    6767    }
    6868
    69     protected override double EvaluateByDistanceMatrix(Permutation permutation, DoubleMatrix distanceMatrix) {
     69    protected override double EvaluateByDistanceMatrix(Permutation permutation, DistanceMatrix distanceMatrix) {
    7070      InversionMove move = InversionMoveParameter.ActualValue;
    7171      int edge1source = permutation.GetCircular(move.Index1 - 1);
  • trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/TravelingSalesmanProblem.cs

    r4722 r4825  
    5555      get { return (ValueParameter<DoubleMatrix>)Parameters["Coordinates"]; }
    5656    }
    57     public OptionalValueParameter<DoubleMatrix> DistanceMatrixParameter {
    58       get { return (OptionalValueParameter<DoubleMatrix>)Parameters["DistanceMatrix"]; }
     57    public OptionalValueParameter<DistanceMatrix> DistanceMatrixParameter {
     58      get { return (OptionalValueParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
    5959    }
    6060    public ValueParameter<BoolValue> UseDistanceMatrixParameter {
     
    8989      set { CoordinatesParameter.Value = value; }
    9090    }
    91     public DoubleMatrix DistanceMatrix {
     91    public DistanceMatrix DistanceMatrix {
    9292      get { return DistanceMatrixParameter.Value; }
    9393      set { DistanceMatrixParameter.Value = value; }
     
    144144      : base(original, cloner) {
    145145      this.operators = original.operators.Select(x => (IOperator)cloner.Clone(x)).ToList();
    146       this.DistanceMatrixParameter.Value = original.DistanceMatrixParameter.Value;
    147146      AttachEventHandlers();
    148147    }
     
    157156      Parameters.Add(new ValueParameter<BoolValue>("Maximization", "Set to false as the Traveling Salesman Problem is a minimization problem.", new BoolValue(false)));
    158157      Parameters.Add(new ValueParameter<DoubleMatrix>("Coordinates", "The x- and y-Coordinates of the cities."));
    159       Parameters.Add(new OptionalValueParameter<DoubleMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
     158      Parameters.Add(new OptionalValueParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
    160159      Parameters.Add(new ValueParameter<BoolValue>("UseDistanceMatrix", "True if a distance matrix should be calculated and used for evaluation, otherwise false.", new BoolValue(true)));
    161160      Parameters.Add(new ValueParameter<IPermutationCreator>("SolutionCreator", "The operator which should be used to create new TSP solutions.", creator));
     
    163162      Parameters.Add(new OptionalValueParameter<DoubleValue>("BestKnownQuality", "The quality of the best known solution of this TSP instance."));
    164163      Parameters.Add(new OptionalValueParameter<Permutation>("BestKnownSolution", "The best known solution of this TSP instance."));
     164
     165      DistanceMatrixParameter.ReactOnValueToStringChangedAndValueItemImageChanged = false;
    165166
    166167      Coordinates = new DoubleMatrix(new double[,] {
     
    258259      // BackwardsCompatibility3.3
    259260      #region Backwards compatible code (remove with 3.4)
     261      OptionalValueParameter<DoubleMatrix> oldDistanceMatrixParameter = Parameters["DistanceMatrix"] as OptionalValueParameter<DoubleMatrix>;
     262      if (oldDistanceMatrixParameter != null) {
     263        Parameters.Remove(oldDistanceMatrixParameter);
     264        Parameters.Add(new OptionalValueParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
     265        DistanceMatrixParameter.GetsCollected = oldDistanceMatrixParameter.GetsCollected;
     266        DistanceMatrixParameter.ReactOnValueToStringChangedAndValueItemImageChanged = false;
     267        if (oldDistanceMatrixParameter.Value != null) {
     268          DoubleMatrix oldDM = oldDistanceMatrixParameter.Value;
     269          DistanceMatrix newDM = new DistanceMatrix(oldDM.Rows, oldDM.Columns, oldDM.ColumnNames, oldDM.RowNames);
     270          newDM.SortableView = oldDM.SortableView;
     271          for (int i = 0; i < newDM.Rows; i++)
     272            for (int j = 0; j < newDM.Columns; j++)
     273              newDM[i, j] = oldDM[i, j];
     274          DistanceMatrixParameter.Value = (DistanceMatrix)newDM.AsReadOnly();
     275        }
     276      }
     277
    260278      if (operators == null) InitializeOperators();
    261279      #endregion
Note: See TracChangeset for help on using the changeset viewer.