Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Problems.Knapsack/3.3/KnapsackProblem.cs @ 7351

Last change on this file since 7351 was 7351, checked in by abeham, 12 years ago

#1722

  • fixed some problems that were identified with the first existing FxCop rules (duplicate storable hook in ExternalEvaluationProblem, multiple wrong names)
  • generally renamed AttachEventHandlers to RegisterEventHandlers to be consistent
  • fixed some backwards compatible regions to use the format from the snippet and the comment
File size: 13.9 KB
RevLine 
[3070]1#region License Information
2/* HeuristicLab
[7259]3 * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[3070]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;
24using System.Linq;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Encodings.BinaryVectorEncoding;
29using HeuristicLab.Optimization;
30using HeuristicLab.Parameters;
31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32using HeuristicLab.PluginInfrastructure;
33
34namespace HeuristicLab.Problems.Knapsack {
[4513]35  [Item("Knapsack Problem", "Represents a Knapsack problem.")]
[3070]36  [Creatable("Problems")]
37  [StorableClass]
[6938]38  public sealed class KnapsackProblem : SingleObjectiveHeuristicOptimizationProblem<IKnapsackEvaluator, IBinaryVectorCreator>, IStorableContent {
[4419]39    public string Filename { get; set; }
40
[3070]41    #region Parameter Properties
42    public ValueParameter<IntValue> KnapsackCapacityParameter {
43      get { return (ValueParameter<IntValue>)Parameters["KnapsackCapacity"]; }
44    }
45    public ValueParameter<IntArray> WeightsParameter {
46      get { return (ValueParameter<IntArray>)Parameters["Weights"]; }
47    }
48    public ValueParameter<IntArray> ValuesParameter {
49      get { return (ValueParameter<IntArray>)Parameters["Values"]; }
50    }
[3109]51    public ValueParameter<DoubleValue> PenaltyParameter {
52      get { return (ValueParameter<DoubleValue>)Parameters["Penalty"]; }
53    }
[3787]54    public OptionalValueParameter<BinaryVector> BestKnownSolutionParameter {
55      get { return (OptionalValueParameter<BinaryVector>)Parameters["BestKnownSolution"]; }
56    }
[3070]57    #endregion
58
59    #region Properties
[3109]60    public IntValue KnapsackCapacity {
61      get { return KnapsackCapacityParameter.Value; }
62      set { KnapsackCapacityParameter.Value = value; }
63    }
64    public IntArray Weights {
65      get { return WeightsParameter.Value; }
66      set { WeightsParameter.Value = value; }
67    }
68    public IntArray Values {
69      get { return ValuesParameter.Value; }
70      set { ValuesParameter.Value = value; }
71    }
72    public DoubleValue Penalty {
73      get { return PenaltyParameter.Value; }
74      set { PenaltyParameter.Value = value; }
75    }
[3787]76    public BinaryVector BestKnownSolution {
77      get { return BestKnownSolutionParameter.Value; }
78      set { BestKnownSolutionParameter.Value = value; }
79    }
[3667]80    private BestKnapsackSolutionAnalyzer BestKnapsackSolutionAnalyzer {
[6938]81      get { return Operators.OfType<BestKnapsackSolutionAnalyzer>().FirstOrDefault(); }
[3641]82    }
[3070]83    #endregion
84
[6938]85    // BackwardsCompatibility3.3
86    #region Backwards compatible code, remove with 3.4
87    [Obsolete]
88    [Storable(Name = "operators")]
89    private IEnumerable<IOperator> oldOperators {
90      get { return null; }
91      set {
92        if (value != null && value.Any())
93          Operators.AddRange(value);
94      }
95    }
96    #endregion
[3125]97
[4098]98    [StorableConstructor]
[4118]99    private KnapsackProblem(bool deserializing) : base(deserializing) { }
[4722]100    private KnapsackProblem(KnapsackProblem original, Cloner cloner)
101      : base(original, cloner) {
[7351]102      RegisterEventHandlers();
[4722]103    }
104    public override IDeepCloneable Clone(Cloner cloner) {
105      return new KnapsackProblem(this, cloner);
106    }
[3166]107    public KnapsackProblem()
[6938]108      : base(new KnapsackEvaluator(), new RandomBinaryVectorCreator()) {
[3070]109      Parameters.Add(new ValueParameter<IntValue>("KnapsackCapacity", "Capacity of the Knapsack.", new IntValue(0)));
110      Parameters.Add(new ValueParameter<IntArray>("Weights", "The weights of the items.", new IntArray(5)));
111      Parameters.Add(new ValueParameter<IntArray>("Values", "The values of the items.", new IntArray(5)));
112      Parameters.Add(new ValueParameter<DoubleValue>("Penalty", "The penalty value for each unit of overweight.", new DoubleValue(1)));
[3787]113      Parameters.Add(new OptionalValueParameter<BinaryVector>("BestKnownSolution", "The best known solution of this Knapsack instance."));
[3070]114
[6938]115      Maximization.Value = true;
[6939]116      MaximizationParameter.Hidden = true;
[3125]117
[6938]118      SolutionCreator.BinaryVectorParameter.ActualName = "KnapsackSolution";
119
[3125]120      InitializeRandomKnapsackInstance();
[5287]121
[3070]122      ParameterizeSolutionCreator();
123      ParameterizeEvaluator();
124
[4098]125      InitializeOperators();
[7351]126      RegisterEventHandlers();
[3070]127    }
128
129    #region Events
[6938]130    protected override void OnSolutionCreatorChanged() {
131      base.OnSolutionCreatorChanged();
[3641]132      SolutionCreator.BinaryVectorParameter.ActualNameChanged += new EventHandler(SolutionCreator_BinaryVectorParameter_ActualNameChanged);
[3070]133      ParameterizeSolutionCreator();
134      ParameterizeEvaluator();
[3667]135      ParameterizeAnalyzer();
[3070]136      ParameterizeOperators();
137    }
[6938]138    protected override void OnEvaluatorChanged() {
139      base.OnEvaluatorChanged();
[3070]140      ParameterizeEvaluator();
[3667]141      ParameterizeAnalyzer();
[3070]142    }
[6938]143    private void SolutionCreator_BinaryVectorParameter_ActualNameChanged(object sender, EventArgs e) {
[3070]144      ParameterizeEvaluator();
[3667]145      ParameterizeAnalyzer();
[6938]146      ParameterizeOperators();
[3070]147    }
[6938]148    private void KnapsackCapacityParameter_ValueChanged(object sender, EventArgs e) {
[3109]149      ParameterizeEvaluator();
[3667]150      ParameterizeAnalyzer();
[3070]151    }
[6938]152    private void WeightsParameter_ValueChanged(object sender, EventArgs e) {
[3109]153      ParameterizeEvaluator();
[3667]154      ParameterizeAnalyzer();
[3110]155      ParameterizeSolutionCreator();
[3111]156
157      WeightsParameter.Value.Reset += new EventHandler(WeightsValue_Reset);
[3070]158    }
[6938]159    private void WeightsValue_Reset(object sender, EventArgs e) {
[3111]160      ParameterizeSolutionCreator();
[3463]161
162      if (WeightsParameter.Value != null && ValuesParameter.Value != null)
163        ((IStringConvertibleArray)ValuesParameter.Value).Length = WeightsParameter.Value.Length;
[3111]164    }
[6938]165    private void ValuesParameter_ValueChanged(object sender, EventArgs e) {
[3109]166      ParameterizeEvaluator();
[3667]167      ParameterizeAnalyzer();
[3110]168      ParameterizeSolutionCreator();
[3111]169
170      ValuesParameter.Value.Reset += new EventHandler(ValuesValue_Reset);
[3109]171    }
[6938]172    private void ValuesValue_Reset(object sender, EventArgs e) {
[3111]173      ParameterizeSolutionCreator();
[3463]174
175      if (WeightsParameter.Value != null && ValuesParameter.Value != null)
176        ((IStringConvertibleArray)WeightsParameter.Value).Length = ValuesParameter.Value.Length;
[3111]177    }
[6938]178    private void PenaltyParameter_ValueChanged(object sender, EventArgs e) {
[3109]179      ParameterizeEvaluator();
180    }
[6938]181    private void OneBitflipMoveParameter_ActualNameChanged(object sender, EventArgs e) {
[3124]182      string name = ((ILookupParameter<OneBitflipMove>)sender).ActualName;
183      foreach (IOneBitflipMoveOperator op in Operators.OfType<IOneBitflipMoveOperator>()) {
184        op.OneBitflipMoveParameter.ActualName = name;
185      }
186    }
[3070]187    #endregion
188
189    #region Helpers
190    [StorableHook(HookType.AfterDeserialization)]
[4722]191    private void AfterDeserialization() {
[4118]192      // BackwardsCompatibility3.3
193      #region Backwards compatible code (remove with 3.4)
[6939]194      if (Operators.Count == 0) InitializeOperators();
[4118]195      #endregion
[7351]196      RegisterEventHandlers();
[4118]197    }
198
[7351]199    private void RegisterEventHandlers() {
[3641]200      SolutionCreator.BinaryVectorParameter.ActualNameChanged += new EventHandler(SolutionCreator_BinaryVectorParameter_ActualNameChanged);
[3109]201      KnapsackCapacityParameter.ValueChanged += new EventHandler(KnapsackCapacityParameter_ValueChanged);
202      WeightsParameter.ValueChanged += new EventHandler(WeightsParameter_ValueChanged);
[3111]203      WeightsParameter.Value.Reset += new EventHandler(WeightsValue_Reset);
[3109]204      ValuesParameter.ValueChanged += new EventHandler(ValuesParameter_ValueChanged);
[3111]205      ValuesParameter.Value.Reset += new EventHandler(ValuesValue_Reset);
[3109]206      PenaltyParameter.ValueChanged += new EventHandler(PenaltyParameter_ValueChanged);
[3070]207    }
208    private void ParameterizeSolutionCreator() {
[5287]209      if (SolutionCreator.LengthParameter.Value == null ||
[3070]210        SolutionCreator.LengthParameter.Value.Value != WeightsParameter.Value.Length)
211        SolutionCreator.LengthParameter.Value = new IntValue(WeightsParameter.Value.Length);
212    }
213    private void ParameterizeEvaluator() {
214      if (Evaluator is KnapsackEvaluator) {
215        KnapsackEvaluator knapsackEvaluator =
216          (KnapsackEvaluator)Evaluator;
217        knapsackEvaluator.BinaryVectorParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName;
[6053]218        knapsackEvaluator.BinaryVectorParameter.Hidden = true;
[3109]219        knapsackEvaluator.KnapsackCapacityParameter.ActualName = KnapsackCapacityParameter.Name;
[6053]220        knapsackEvaluator.KnapsackCapacityParameter.Hidden = true;
[3070]221        knapsackEvaluator.WeightsParameter.ActualName = WeightsParameter.Name;
[6053]222        knapsackEvaluator.WeightsParameter.Hidden = true;
[3070]223        knapsackEvaluator.ValuesParameter.ActualName = ValuesParameter.Name;
[6053]224        knapsackEvaluator.ValuesParameter.Hidden = true;
[3070]225        knapsackEvaluator.PenaltyParameter.ActualName = PenaltyParameter.Name;
[6053]226        knapsackEvaluator.PenaltyParameter.Hidden = true;
[3070]227      }
228    }
[3667]229    private void ParameterizeAnalyzer() {
[3789]230      BestKnapsackSolutionAnalyzer.MaximizationParameter.ActualName = MaximizationParameter.Name;
[6053]231      BestKnapsackSolutionAnalyzer.MaximizationParameter.Hidden = true;
[3789]232      BestKnapsackSolutionAnalyzer.BestKnownQualityParameter.ActualName = BestKnownQualityParameter.Name;
[6053]233      BestKnapsackSolutionAnalyzer.BestKnownQualityParameter.Hidden = true;
[3789]234      BestKnapsackSolutionAnalyzer.BestKnownSolutionParameter.ActualName = BestKnownSolutionParameter.Name;
[6053]235      BestKnapsackSolutionAnalyzer.BestKnownSolutionParameter.Hidden = true;
[3667]236      BestKnapsackSolutionAnalyzer.BinaryVectorParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName;
[6053]237      BestKnapsackSolutionAnalyzer.BinaryVectorParameter.Hidden = true;
[3667]238      BestKnapsackSolutionAnalyzer.KnapsackCapacityParameter.ActualName = KnapsackCapacityParameter.Name;
[6053]239      BestKnapsackSolutionAnalyzer.KnapsackCapacityParameter.Hidden = true;
[3667]240      BestKnapsackSolutionAnalyzer.WeightsParameter.ActualName = WeightsParameter.Name;
[6053]241      BestKnapsackSolutionAnalyzer.WeightsParameter.Hidden = true;
[3667]242      BestKnapsackSolutionAnalyzer.ValuesParameter.ActualName = ValuesParameter.Name;
[6053]243      BestKnapsackSolutionAnalyzer.ValuesParameter.Hidden = true;
[3467]244    }
[3070]245    private void InitializeOperators() {
[6938]246      Operators.Add(new BestKnapsackSolutionAnalyzer());
[3667]247      ParameterizeAnalyzer();
[3303]248      foreach (IBinaryVectorOperator op in ApplicationManager.Manager.GetInstances<IBinaryVectorOperator>()) {
249        if (!(op is ISingleObjectiveMoveEvaluator) || (op is IKnapsackMoveEvaluator)) {
[6938]250          Operators.Add(op);
[3127]251        }
[3070]252      }
[3303]253      ParameterizeOperators();
[3124]254      InitializeMoveGenerators();
[3070]255    }
[3124]256    private void InitializeMoveGenerators() {
257      foreach (IOneBitflipMoveOperator op in Operators.OfType<IOneBitflipMoveOperator>()) {
258        if (op is IMoveGenerator) {
259          op.OneBitflipMoveParameter.ActualNameChanged += new EventHandler(OneBitflipMoveParameter_ActualNameChanged);
260        }
261      }
262    }
[3070]263    private void ParameterizeOperators() {
264      foreach (IBinaryVectorCrossover op in Operators.OfType<IBinaryVectorCrossover>()) {
265        op.ParentsParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName;
[6053]266        op.ParentsParameter.Hidden = true;
[3070]267        op.ChildParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName;
[6053]268        op.ChildParameter.Hidden = true;
[3070]269      }
270      foreach (IBinaryVectorManipulator op in Operators.OfType<IBinaryVectorManipulator>()) {
271        op.BinaryVectorParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName;
[6053]272        op.BinaryVectorParameter.Hidden = true;
[3070]273      }
[3124]274      foreach (IBinaryVectorMoveOperator op in Operators.OfType<IBinaryVectorMoveOperator>()) {
275        op.BinaryVectorParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName;
[6053]276        op.BinaryVectorParameter.Hidden = true;
[3124]277      }
278      foreach (IKnapsackMoveEvaluator op in Operators.OfType<IKnapsackMoveEvaluator>()) {
279        op.KnapsackCapacityParameter.ActualName = KnapsackCapacityParameter.Name;
[6053]280        op.KnapsackCapacityParameter.Hidden = true;
[3124]281        op.PenaltyParameter.ActualName = PenaltyParameter.Name;
[6053]282        op.PenaltyParameter.Hidden = true;
[3124]283        op.WeightsParameter.ActualName = WeightsParameter.Name;
[6053]284        op.WeightsParameter.Hidden = true;
[3124]285        op.ValuesParameter.ActualName = ValuesParameter.Name;
[6053]286        op.ValuesParameter.Hidden = true;
[3124]287      }
[6053]288      foreach (var op in Operators.OfType<IBinaryVectorMultiNeighborhoodShakingOperator>()) {
[6042]289        op.BinaryVectorParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName;
[6053]290        op.BinaryVectorParameter.Hidden = true;
291      }
[3070]292    }
293    #endregion
[4098]294
295    private void InitializeRandomKnapsackInstance() {
296      System.Random rand = new System.Random();
297
298      int itemCount = rand.Next(10, 100);
299      Weights = new IntArray(itemCount);
300      Values = new IntArray(itemCount);
301
302      double totalWeight = 0;
303
304      for (int i = 0; i < itemCount; i++) {
305        int value = rand.Next(1, 10);
306        int weight = rand.Next(1, 10);
307
308        Values[i] = value;
309        Weights[i] = weight;
310        totalWeight += weight;
311      }
312
313      int capacity = (int)Math.Round(0.7 * totalWeight);
314      KnapsackCapacity = new IntValue(capacity);
315    }
[3070]316  }
317}
Note: See TracBrowser for help on using the repository browser.