Free cookie consent management tool by TermsFeed Policy Generator

source: branches/ProblemRefactoring/HeuristicLab.Problems.Knapsack/3.3/Improvers/KnapsackImprovementOperator.cs @ 14815

Last change on this file since 14815 was 13404, checked in by abeham, 9 years ago

#2521:

  • Adapted Knapsack problem to new problem infrastructure
  • Introduced additional interfaces in binary vector encoding
  • Improved KnapsackImprovementOperator which requires less evaluated solutions in case of an infeasible start solution

Loosely related change:

  • All LookupParameters are now shown by default
  • Wiring code should make sure that wired parameters are hidden
File size: 6.9 KB
RevLine 
[7789]1#region License Information
2/* HeuristicLab
[12012]3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[7789]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
[8086]22using System;
[7789]23using System.Linq;
24using HeuristicLab.Common;
25using HeuristicLab.Core;
26using HeuristicLab.Data;
27using HeuristicLab.Encodings.BinaryVectorEncoding;
28using HeuristicLab.Operators;
[8086]29using HeuristicLab.Optimization;
[7789]30using HeuristicLab.Parameters;
31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32
33namespace HeuristicLab.Problems.Knapsack {
34  /// <summary>
35  /// An operator that improves knapsack solutions.
36  /// </summary>
[8319]37  /// <remarks>
38  /// It is implemented as described in Laguna, M. and Martí, R. (2003). Scatter Search: Methodology and Implementations in C. Operations Research/Computer Science Interfaces Series, Vol. 24. Springer.<br />
39  /// The operator first orders the elements of the knapsack according to their value-to-weight ratio, then, if the solution is not feasible, removes the element with the lowest ratio until the solution is feasible and tries to add new elements with the best ratio that are not already included yet until the knapsack is full.
40  /// </remarks>
[8327]41  [Item("KnapsackImprovementOperator", "An operator that improves knapsack solutions. It is implemented as described in Laguna, M. and Martí, R. (2003). Scatter Search: Methodology and Implementations in C. Operations Research/Computer Science Interfaces Series, Vol. 24. Springer.")]
[7789]42  [StorableClass]
[8319]43  public sealed class KnapsackImprovementOperator : SingleSuccessorOperator, ISingleObjectiveImprovementOperator {
[7789]44    #region Parameter properties
45    public ScopeParameter CurrentScopeParameter {
46      get { return (ScopeParameter)Parameters["CurrentScope"]; }
47    }
48    public ILookupParameter<IntValue> KnapsackCapacityParameter {
49      get { return (ILookupParameter<IntValue>)Parameters["KnapsackCapacity"]; }
50    }
51    public ILookupParameter<DoubleValue> PenaltyParameter {
52      get { return (ILookupParameter<DoubleValue>)Parameters["Penalty"]; }
53    }
[8319]54    public IValueLookupParameter<IItem> SolutionParameter {
55      get { return (IValueLookupParameter<IItem>)Parameters["Solution"]; }
[7789]56    }
57    public ILookupParameter<IntArray> ValuesParameter {
58      get { return (ILookupParameter<IntArray>)Parameters["Values"]; }
59    }
60    public ILookupParameter<IntArray> WeightsParameter {
61      get { return (ILookupParameter<IntArray>)Parameters["Weights"]; }
62    }
63    #endregion
64
65    #region Properties
66    private IScope CurrentScope {
67      get { return CurrentScopeParameter.ActualValue; }
68    }
69    private IntValue KnapsackCapacity {
70      get { return KnapsackCapacityParameter.ActualValue; }
71      set { KnapsackCapacityParameter.ActualValue = value; }
72    }
73    private DoubleValue Penalty {
74      get { return PenaltyParameter.ActualValue; }
75      set { PenaltyParameter.ActualValue = value; }
76    }
77    private IntArray Values {
78      get { return ValuesParameter.ActualValue; }
79      set { ValuesParameter.ActualValue = value; }
80    }
81    private IntArray Weights {
82      get { return WeightsParameter.ActualValue; }
83      set { WeightsParameter.ActualValue = value; }
84    }
85    #endregion
86
87    [StorableConstructor]
88    private KnapsackImprovementOperator(bool deserializing) : base(deserializing) { }
89    private KnapsackImprovementOperator(KnapsackImprovementOperator original, Cloner cloner) : base(original, cloner) { }
90    public KnapsackImprovementOperator()
91      : base() {
92      #region Create parameters
[8086]93      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope that contains the solution to be improved."));
94      Parameters.Add(new LookupParameter<IntValue>("KnapsackCapacity", "Capacity of the Knapsack."));
95      Parameters.Add(new LookupParameter<DoubleValue>("Penalty", "The penalty value for each unit of overweight."));
[8319]96      Parameters.Add(new ValueLookupParameter<IItem>("Solution", "The solution to be improved. This parameter is used for name translation only."));
[8086]97      Parameters.Add(new LookupParameter<IntArray>("Values", "The values of the items."));
98      Parameters.Add(new LookupParameter<IntArray>("Weights", "The weights of the items."));
[7789]99      #endregion
100    }
101
102    public override IDeepCloneable Clone(Cloner cloner) {
103      return new KnapsackImprovementOperator(this, cloner);
104    }
105
106    public override IOperation Apply() {
[8319]107      BinaryVector sol = CurrentScope.Variables[SolutionParameter.ActualName].Value as BinaryVector;
[8086]108      if (sol == null)
109        throw new ArgumentException("Cannot improve solution because it has the wrong type.");
[7789]110
111      // calculate value-to-weight ratio
112      double[] ratio = new double[Values.Length];
113      for (int i = 0; i < ratio.Length; i++)
114        ratio[i] = (double)Values[i] / (double)Weights[i];
115
116
117      // calculate order for ratio
118      int[] order = new int[ratio.Length];
[8086]119      foreach (var x in ratio.Select((x, index) => new { Value = x, ValueIndex = index })
[8320]120                             .OrderByDescending(x => x.Value)
[8086]121                             .Select((x, index) => new { ValueIndex = x.ValueIndex, ItemIndex = index })) {
122        order[x.ItemIndex] = x.ValueIndex;
123      }
[7789]124
[8086]125      int evaluatedSolutions = 0;
[7789]126      int j = sol.Length - 1;
[13404]127      var totalWeight = 0.0;
128      for (var i = 0; i < sol.Length; i++) {
129        if (sol[i]) totalWeight += Weights[i];
130      }
131      evaluatedSolutions++;
132
133      while (totalWeight > KnapsackCapacity.Value && j >= 0) {
134        totalWeight -= Weights[order[j]];
[7789]135        sol[order[j--]] = false;
[8086]136      }
[7789]137
138      // calculate weight
139      int weight = 0;
140      for (int i = 0; i < sol.Length; i++)
141        if (sol[i]) weight += Weights[i];
142
143      // improve solution
144      bool feasible = true; j = 0;
145      while (feasible && j < sol.Length) {
146        while (sol[order[j]]) j++;
147        if (weight + Weights[order[j]] <= KnapsackCapacity.Value) {
148          sol[order[j]] = true;
149          weight += Weights[order[j]];
150        } else feasible = false;
[8086]151        evaluatedSolutions++;
[7789]152      }
153
[8319]154      CurrentScope.Variables[SolutionParameter.ActualName].Value = sol;
[8086]155      CurrentScope.Variables.Add(new Variable("LocalEvaluatedSolutions", new IntValue(evaluatedSolutions)));
[7789]156
157      return base.Apply();
158    }
159  }
160}
Note: See TracBrowser for help on using the repository browser.