Free cookie consent management tool by TermsFeed Policy Generator

source: branches/ScatterSearch (trunk integration)/HeuristicLab.Problems.Knapsack/3.3/Improvers/KnapsackImprovementOperator.cs @ 8086

Last change on this file since 8086 was 8086, checked in by jkarder, 12 years ago

#1331:

  • synced branch with trunk
  • added custom interface (ISimilarityBasedOperator) to mark operators that conduct similarity calculation
  • similarity calculators are now parameterized by the algorithm
  • deleted SolutionPool2TierUpdateMethod
  • deleted KnapsackMultipleGuidesPathRelinker
  • moved IImprovementOperator, IPathRelinker and ISimilarityCalculator to HeuristicLab.Optimization
  • added parameter descriptions
  • fixed plugin references
  • fixed count of EvaluatedSolutions
  • fixed check for duplicate solutions
  • minor code improvements
File size: 6.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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.Linq;
24using HeuristicLab.Common;
25using HeuristicLab.Core;
26using HeuristicLab.Data;
27using HeuristicLab.Encodings.BinaryVectorEncoding;
28using HeuristicLab.Operators;
29using HeuristicLab.Optimization;
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>
37  [Item("KnapsackImprovementOperator", "An operator that improves knapsack solutions.")]
38  [StorableClass]
39  public sealed class KnapsackImprovementOperator : SingleSuccessorOperator, IImprovementOperator {
40    #region Parameter properties
41    public ScopeParameter CurrentScopeParameter {
42      get { return (ScopeParameter)Parameters["CurrentScope"]; }
43    }
44    public ILookupParameter<IntValue> KnapsackCapacityParameter {
45      get { return (ILookupParameter<IntValue>)Parameters["KnapsackCapacity"]; }
46    }
47    public ILookupParameter<DoubleValue> PenaltyParameter {
48      get { return (ILookupParameter<DoubleValue>)Parameters["Penalty"]; }
49    }
50    public IValueLookupParameter<IItem> TargetParameter {
51      get { return (IValueLookupParameter<IItem>)Parameters["Target"]; }
52    }
53    public ILookupParameter<IntArray> ValuesParameter {
54      get { return (ILookupParameter<IntArray>)Parameters["Values"]; }
55    }
56    public ILookupParameter<IntArray> WeightsParameter {
57      get { return (ILookupParameter<IntArray>)Parameters["Weights"]; }
58    }
59    #endregion
60
61    #region Properties
62    private IScope CurrentScope {
63      get { return CurrentScopeParameter.ActualValue; }
64    }
65    private IntValue KnapsackCapacity {
66      get { return KnapsackCapacityParameter.ActualValue; }
67      set { KnapsackCapacityParameter.ActualValue = value; }
68    }
69    private DoubleValue Penalty {
70      get { return PenaltyParameter.ActualValue; }
71      set { PenaltyParameter.ActualValue = value; }
72    }
73    private IntArray Values {
74      get { return ValuesParameter.ActualValue; }
75      set { ValuesParameter.ActualValue = value; }
76    }
77    private IntArray Weights {
78      get { return WeightsParameter.ActualValue; }
79      set { WeightsParameter.ActualValue = value; }
80    }
81    #endregion
82
83    [StorableConstructor]
84    private KnapsackImprovementOperator(bool deserializing) : base(deserializing) { }
85    private KnapsackImprovementOperator(KnapsackImprovementOperator original, Cloner cloner) : base(original, cloner) { }
86    public KnapsackImprovementOperator()
87      : base() {
88      #region Create parameters
89      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope that contains the solution to be improved."));
90      Parameters.Add(new LookupParameter<IntValue>("KnapsackCapacity", "Capacity of the Knapsack."));
91      Parameters.Add(new LookupParameter<DoubleValue>("Penalty", "The penalty value for each unit of overweight."));
92      Parameters.Add(new ValueLookupParameter<IItem>("Target", "This parameter is used for name translation only."));
93      Parameters.Add(new LookupParameter<IntArray>("Values", "The values of the items."));
94      Parameters.Add(new LookupParameter<IntArray>("Weights", "The weights of the items."));
95      #endregion
96    }
97
98    public override IDeepCloneable Clone(Cloner cloner) {
99      return new KnapsackImprovementOperator(this, cloner);
100    }
101
102    public override IOperation Apply() {
103      BinaryVector sol = CurrentScope.Variables[TargetParameter.ActualName].Value as BinaryVector;
104      if (sol == null)
105        throw new ArgumentException("Cannot improve solution because it has the wrong type.");
106
107      // calculate value-to-weight ratio
108      double[] ratio = new double[Values.Length];
109      for (int i = 0; i < ratio.Length; i++)
110        ratio[i] = (double)Values[i] / (double)Weights[i];
111
112
113      // calculate order for ratio
114      int[] order = new int[ratio.Length];
115      foreach (var x in ratio.Select((x, index) => new { Value = x, ValueIndex = index })
116                             .OrderBy(x => x.Value)
117                             .Select((x, index) => new { ValueIndex = x.ValueIndex, ItemIndex = index })) {
118        order[x.ItemIndex] = x.ValueIndex;
119      }
120
121      int evaluatedSolutions = 0;
122      int j = sol.Length - 1;
123      while (KnapsackEvaluator.Apply(sol, KnapsackCapacity, Penalty, Weights, Values)
124                              .SumWeights.Value > KnapsackCapacity.Value && j >= 0) {
125        sol[order[j--]] = false;
126        evaluatedSolutions++;
127      }
128
129      // calculate weight
130      int weight = 0;
131      for (int i = 0; i < sol.Length; i++)
132        if (sol[i]) weight += Weights[i];
133
134      // improve solution
135      bool feasible = true; j = 0;
136      while (feasible && j < sol.Length) {
137        while (sol[order[j]]) j++;
138        if (weight + Weights[order[j]] <= KnapsackCapacity.Value) {
139          sol[order[j]] = true;
140          weight += Weights[order[j]];
141        } else feasible = false;
142        evaluatedSolutions++;
143      }
144
145      CurrentScope.Variables[TargetParameter.ActualName].Value = sol;
146      CurrentScope.Variables.Add(new Variable("LocalEvaluatedSolutions", new IntValue(evaluatedSolutions)));
147
148      return base.Apply();
149    }
150  }
151}
Note: See TracBrowser for help on using the repository browser.