Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 6831 was 6476, checked in by gkronber, 13 years ago

#1553: added remaining unit tests to create and run optimizer samples.

File size: 17.7 KB
RevLine 
[3070]1#region License Information
2/* HeuristicLab
[5445]3 * Copyright (C) 2002-2011 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.Drawing;
25using System.Linq;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Data;
29using HeuristicLab.Encodings.BinaryVectorEncoding;
30using HeuristicLab.Optimization;
31using HeuristicLab.Parameters;
32using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
33using HeuristicLab.PluginInfrastructure;
34
35namespace HeuristicLab.Problems.Knapsack {
[4513]36  [Item("Knapsack Problem", "Represents a Knapsack problem.")]
[3070]37  [Creatable("Problems")]
38  [StorableClass]
[5809]39  public sealed class KnapsackProblem : ParameterizedNamedItem, ISingleObjectiveHeuristicOptimizationProblem, IStorableContent {
[4419]40    public string Filename { get; set; }
41
[3070]42    public override Image ItemImage {
[5287]43      get { return HeuristicLab.Common.Resources.VSImageLibrary.Type; }
[3070]44    }
45
46    #region Parameter Properties
47    public ValueParameter<BoolValue> MaximizationParameter {
48      get { return (ValueParameter<BoolValue>)Parameters["Maximization"]; }
49    }
[5809]50    IParameter ISingleObjectiveHeuristicOptimizationProblem.MaximizationParameter {
[3070]51      get { return MaximizationParameter; }
52    }
53    public ValueParameter<IntValue> KnapsackCapacityParameter {
54      get { return (ValueParameter<IntValue>)Parameters["KnapsackCapacity"]; }
55    }
56    public ValueParameter<IntArray> WeightsParameter {
57      get { return (ValueParameter<IntArray>)Parameters["Weights"]; }
58    }
59    public ValueParameter<IntArray> ValuesParameter {
60      get { return (ValueParameter<IntArray>)Parameters["Values"]; }
61    }
[3109]62    public ValueParameter<DoubleValue> PenaltyParameter {
63      get { return (ValueParameter<DoubleValue>)Parameters["Penalty"]; }
64    }
[3070]65    public ValueParameter<IBinaryVectorCreator> SolutionCreatorParameter {
66      get { return (ValueParameter<IBinaryVectorCreator>)Parameters["SolutionCreator"]; }
67    }
[5809]68    IParameter IHeuristicOptimizationProblem.SolutionCreatorParameter {
[3070]69      get { return SolutionCreatorParameter; }
70    }
71    public ValueParameter<IKnapsackEvaluator> EvaluatorParameter {
72      get { return (ValueParameter<IKnapsackEvaluator>)Parameters["Evaluator"]; }
73    }
[5809]74    IParameter IHeuristicOptimizationProblem.EvaluatorParameter {
[3070]75      get { return EvaluatorParameter; }
76    }
[3071]77    public OptionalValueParameter<DoubleValue> BestKnownQualityParameter {
78      get { return (OptionalValueParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
79    }
[5809]80    IParameter ISingleObjectiveHeuristicOptimizationProblem.BestKnownQualityParameter {
[3080]81      get { return BestKnownQualityParameter; }
82    }
[3787]83    public OptionalValueParameter<BinaryVector> BestKnownSolutionParameter {
84      get { return (OptionalValueParameter<BinaryVector>)Parameters["BestKnownSolution"]; }
85    }
[3070]86    #endregion
87
88    #region Properties
[6476]89    public BoolValue Maximization {
90      get { return MaximizationParameter.Value; }
91      set { MaximizationParameter.Value = value; }
92    }
[3109]93    public IntValue KnapsackCapacity {
94      get { return KnapsackCapacityParameter.Value; }
95      set { KnapsackCapacityParameter.Value = value; }
96    }
97    public IntArray Weights {
98      get { return WeightsParameter.Value; }
99      set { WeightsParameter.Value = value; }
100    }
101    public IntArray Values {
102      get { return ValuesParameter.Value; }
103      set { ValuesParameter.Value = value; }
104    }
105    public DoubleValue Penalty {
106      get { return PenaltyParameter.Value; }
107      set { PenaltyParameter.Value = value; }
108    }
[3070]109    public IBinaryVectorCreator SolutionCreator {
110      get { return SolutionCreatorParameter.Value; }
111      set { SolutionCreatorParameter.Value = value; }
112    }
[5809]113    ISolutionCreator IHeuristicOptimizationProblem.SolutionCreator {
[3070]114      get { return SolutionCreatorParameter.Value; }
115    }
116    public IKnapsackEvaluator Evaluator {
117      get { return EvaluatorParameter.Value; }
118      set { EvaluatorParameter.Value = value; }
119    }
[5809]120    ISingleObjectiveEvaluator ISingleObjectiveHeuristicOptimizationProblem.Evaluator {
[3070]121      get { return EvaluatorParameter.Value; }
122    }
[5809]123    IEvaluator IHeuristicOptimizationProblem.Evaluator {
[3070]124      get { return EvaluatorParameter.Value; }
125    }
[3071]126    public DoubleValue BestKnownQuality {
127      get { return BestKnownQualityParameter.Value; }
128      set { BestKnownQualityParameter.Value = value; }
129    }
[3787]130    public BinaryVector BestKnownSolution {
131      get { return BestKnownSolutionParameter.Value; }
132      set { BestKnownSolutionParameter.Value = value; }
133    }
[3070]134    public IEnumerable<IOperator> Operators {
135      get { return operators.Cast<IOperator>(); }
136    }
[3667]137    private BestKnapsackSolutionAnalyzer BestKnapsackSolutionAnalyzer {
138      get { return operators.OfType<BestKnapsackSolutionAnalyzer>().FirstOrDefault(); }
[3641]139    }
[3070]140    #endregion
141
[4098]142    [Storable]
143    private List<IOperator> operators;
[3125]144
[4098]145    [StorableConstructor]
[4118]146    private KnapsackProblem(bool deserializing) : base(deserializing) { }
[4722]147    private KnapsackProblem(KnapsackProblem original, Cloner cloner)
148      : base(original, cloner) {
149      this.operators = original.operators.Select(x => (IOperator)cloner.Clone(x)).ToList();
150      AttachEventHandlers();
151    }
152    public override IDeepCloneable Clone(Cloner cloner) {
153      return new KnapsackProblem(this, cloner);
154    }
[3166]155    public KnapsackProblem()
[3070]156      : base() {
157      RandomBinaryVectorCreator creator = new RandomBinaryVectorCreator();
158      KnapsackEvaluator evaluator = new KnapsackEvaluator();
159
160      Parameters.Add(new ValueParameter<BoolValue>("Maximization", "Set to true as the Knapsack Problem is a maximization problem.", new BoolValue(true)));
161      Parameters.Add(new ValueParameter<IntValue>("KnapsackCapacity", "Capacity of the Knapsack.", new IntValue(0)));
162      Parameters.Add(new ValueParameter<IntArray>("Weights", "The weights of the items.", new IntArray(5)));
163      Parameters.Add(new ValueParameter<IntArray>("Values", "The values of the items.", new IntArray(5)));
164      Parameters.Add(new ValueParameter<DoubleValue>("Penalty", "The penalty value for each unit of overweight.", new DoubleValue(1)));
165      Parameters.Add(new ValueParameter<IBinaryVectorCreator>("SolutionCreator", "The operator which should be used to create new Knapsack solutions.", creator));
166      Parameters.Add(new ValueParameter<IKnapsackEvaluator>("Evaluator", "The operator which should be used to evaluate Knapsack solutions.", evaluator));
[3071]167      Parameters.Add(new OptionalValueParameter<DoubleValue>("BestKnownQuality", "The quality of the best known solution of this Knapsack instance."));
[3787]168      Parameters.Add(new OptionalValueParameter<BinaryVector>("BestKnownSolution", "The best known solution of this Knapsack instance."));
[3070]169
170      creator.BinaryVectorParameter.ActualName = "KnapsackSolution";
[3125]171
172      InitializeRandomKnapsackInstance();
[5287]173
[3070]174      ParameterizeSolutionCreator();
175      ParameterizeEvaluator();
176
[4098]177      InitializeOperators();
178      AttachEventHandlers();
[3070]179    }
180
181    #region Events
182    public event EventHandler SolutionCreatorChanged;
183    private void OnSolutionCreatorChanged() {
[3739]184      EventHandler handler = SolutionCreatorChanged;
185      if (handler != null) handler(this, EventArgs.Empty);
[3070]186    }
187    public event EventHandler EvaluatorChanged;
188    private void OnEvaluatorChanged() {
[3739]189      EventHandler handler = EvaluatorChanged;
190      if (handler != null) handler(this, EventArgs.Empty);
[3070]191    }
192    public event EventHandler OperatorsChanged;
193    private void OnOperatorsChanged() {
[3739]194      EventHandler handler = OperatorsChanged;
195      if (handler != null) handler(this, EventArgs.Empty);
[3070]196    }
[3739]197    public event EventHandler Reset;
198    private void OnReset() {
199      EventHandler handler = Reset;
200      if (handler != null) handler(this, EventArgs.Empty);
201    }
[3070]202
203    private void SolutionCreatorParameter_ValueChanged(object sender, EventArgs e) {
[3641]204      SolutionCreator.BinaryVectorParameter.ActualNameChanged += new EventHandler(SolutionCreator_BinaryVectorParameter_ActualNameChanged);
[3070]205      ParameterizeSolutionCreator();
206      ParameterizeEvaluator();
[3667]207      ParameterizeAnalyzer();
[3070]208      ParameterizeOperators();
209      OnSolutionCreatorChanged();
210    }
[3641]211    private void SolutionCreator_BinaryVectorParameter_ActualNameChanged(object sender, EventArgs e) {
[3070]212      ParameterizeEvaluator();
[3667]213      ParameterizeAnalyzer();
[3070]214      ParameterizeOperators();
215    }
216    private void EvaluatorParameter_ValueChanged(object sender, EventArgs e) {
217      ParameterizeEvaluator();
[3667]218      ParameterizeAnalyzer();
[3070]219      OnEvaluatorChanged();
220    }
[3109]221    void KnapsackCapacityParameter_ValueChanged(object sender, EventArgs e) {
222      ParameterizeEvaluator();
[3667]223      ParameterizeAnalyzer();
[3070]224    }
[3109]225    void WeightsParameter_ValueChanged(object sender, EventArgs e) {
226      ParameterizeEvaluator();
[3667]227      ParameterizeAnalyzer();
[3110]228      ParameterizeSolutionCreator();
[3111]229
230      WeightsParameter.Value.Reset += new EventHandler(WeightsValue_Reset);
[3070]231    }
[3111]232    void WeightsValue_Reset(object sender, EventArgs e) {
233      ParameterizeSolutionCreator();
[3463]234
235      if (WeightsParameter.Value != null && ValuesParameter.Value != null)
236        ((IStringConvertibleArray)ValuesParameter.Value).Length = WeightsParameter.Value.Length;
[3111]237    }
[3109]238    void ValuesParameter_ValueChanged(object sender, EventArgs e) {
239      ParameterizeEvaluator();
[3667]240      ParameterizeAnalyzer();
[3110]241      ParameterizeSolutionCreator();
[3111]242
243      ValuesParameter.Value.Reset += new EventHandler(ValuesValue_Reset);
[3109]244    }
[3111]245    void ValuesValue_Reset(object sender, EventArgs e) {
246      ParameterizeSolutionCreator();
[3463]247
248      if (WeightsParameter.Value != null && ValuesParameter.Value != null)
249        ((IStringConvertibleArray)WeightsParameter.Value).Length = ValuesParameter.Value.Length;
[3111]250    }
[3109]251    void PenaltyParameter_ValueChanged(object sender, EventArgs e) {
252      ParameterizeEvaluator();
253    }
[3124]254    void OneBitflipMoveParameter_ActualNameChanged(object sender, EventArgs e) {
255      string name = ((ILookupParameter<OneBitflipMove>)sender).ActualName;
256      foreach (IOneBitflipMoveOperator op in Operators.OfType<IOneBitflipMoveOperator>()) {
257        op.OneBitflipMoveParameter.ActualName = name;
258      }
259    }
[3070]260    #endregion
261
262    #region Helpers
263    [StorableHook(HookType.AfterDeserialization)]
[4722]264    private void AfterDeserialization() {
[4118]265      // BackwardsCompatibility3.3
266      #region Backwards compatible code (remove with 3.4)
267      if (operators == null) InitializeOperators();
268      #endregion
269      AttachEventHandlers();
270    }
271
[4098]272    private void AttachEventHandlers() {
[3070]273      SolutionCreatorParameter.ValueChanged += new EventHandler(SolutionCreatorParameter_ValueChanged);
[3641]274      SolutionCreator.BinaryVectorParameter.ActualNameChanged += new EventHandler(SolutionCreator_BinaryVectorParameter_ActualNameChanged);
[3070]275      EvaluatorParameter.ValueChanged += new EventHandler(EvaluatorParameter_ValueChanged);
[3109]276      KnapsackCapacityParameter.ValueChanged += new EventHandler(KnapsackCapacityParameter_ValueChanged);
277      WeightsParameter.ValueChanged += new EventHandler(WeightsParameter_ValueChanged);
[3111]278      WeightsParameter.Value.Reset += new EventHandler(WeightsValue_Reset);
[3109]279      ValuesParameter.ValueChanged += new EventHandler(ValuesParameter_ValueChanged);
[3111]280      ValuesParameter.Value.Reset += new EventHandler(ValuesValue_Reset);
[3109]281      PenaltyParameter.ValueChanged += new EventHandler(PenaltyParameter_ValueChanged);
[3070]282    }
283    private void ParameterizeSolutionCreator() {
[5287]284      if (SolutionCreator.LengthParameter.Value == null ||
[3070]285        SolutionCreator.LengthParameter.Value.Value != WeightsParameter.Value.Length)
286        SolutionCreator.LengthParameter.Value = new IntValue(WeightsParameter.Value.Length);
287    }
288    private void ParameterizeEvaluator() {
289      if (Evaluator is KnapsackEvaluator) {
290        KnapsackEvaluator knapsackEvaluator =
291          (KnapsackEvaluator)Evaluator;
292        knapsackEvaluator.BinaryVectorParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName;
[6053]293        knapsackEvaluator.BinaryVectorParameter.Hidden = true;
[3109]294        knapsackEvaluator.KnapsackCapacityParameter.ActualName = KnapsackCapacityParameter.Name;
[6053]295        knapsackEvaluator.KnapsackCapacityParameter.Hidden = true;
[3070]296        knapsackEvaluator.WeightsParameter.ActualName = WeightsParameter.Name;
[6053]297        knapsackEvaluator.WeightsParameter.Hidden = true;
[3070]298        knapsackEvaluator.ValuesParameter.ActualName = ValuesParameter.Name;
[6053]299        knapsackEvaluator.ValuesParameter.Hidden = true;
[3070]300        knapsackEvaluator.PenaltyParameter.ActualName = PenaltyParameter.Name;
[6053]301        knapsackEvaluator.PenaltyParameter.Hidden = true;
[3070]302      }
303    }
[3667]304    private void ParameterizeAnalyzer() {
[3789]305      BestKnapsackSolutionAnalyzer.MaximizationParameter.ActualName = MaximizationParameter.Name;
[6053]306      BestKnapsackSolutionAnalyzer.MaximizationParameter.Hidden = true;
[3789]307      BestKnapsackSolutionAnalyzer.BestKnownQualityParameter.ActualName = BestKnownQualityParameter.Name;
[6053]308      BestKnapsackSolutionAnalyzer.BestKnownQualityParameter.Hidden = true;
[3789]309      BestKnapsackSolutionAnalyzer.BestKnownSolutionParameter.ActualName = BestKnownSolutionParameter.Name;
[6053]310      BestKnapsackSolutionAnalyzer.BestKnownSolutionParameter.Hidden = true;
[3667]311      BestKnapsackSolutionAnalyzer.BinaryVectorParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName;
[6053]312      BestKnapsackSolutionAnalyzer.BinaryVectorParameter.Hidden = true;
[3667]313      BestKnapsackSolutionAnalyzer.KnapsackCapacityParameter.ActualName = KnapsackCapacityParameter.Name;
[6053]314      BestKnapsackSolutionAnalyzer.KnapsackCapacityParameter.Hidden = true;
[3667]315      BestKnapsackSolutionAnalyzer.WeightsParameter.ActualName = WeightsParameter.Name;
[6053]316      BestKnapsackSolutionAnalyzer.WeightsParameter.Hidden = true;
[3667]317      BestKnapsackSolutionAnalyzer.ValuesParameter.ActualName = ValuesParameter.Name;
[6053]318      BestKnapsackSolutionAnalyzer.ValuesParameter.Hidden = true;
[3467]319    }
[3070]320    private void InitializeOperators() {
[3641]321      operators = new List<IOperator>();
322      operators.Add(new BestKnapsackSolutionAnalyzer());
[3667]323      ParameterizeAnalyzer();
[3303]324      foreach (IBinaryVectorOperator op in ApplicationManager.Manager.GetInstances<IBinaryVectorOperator>()) {
325        if (!(op is ISingleObjectiveMoveEvaluator) || (op is IKnapsackMoveEvaluator)) {
326          operators.Add(op);
[3127]327        }
[3070]328      }
[3303]329      ParameterizeOperators();
[3124]330      InitializeMoveGenerators();
[3070]331    }
[3124]332    private void InitializeMoveGenerators() {
333      foreach (IOneBitflipMoveOperator op in Operators.OfType<IOneBitflipMoveOperator>()) {
334        if (op is IMoveGenerator) {
335          op.OneBitflipMoveParameter.ActualNameChanged += new EventHandler(OneBitflipMoveParameter_ActualNameChanged);
336        }
337      }
338    }
[3070]339    private void ParameterizeOperators() {
340      foreach (IBinaryVectorCrossover op in Operators.OfType<IBinaryVectorCrossover>()) {
341        op.ParentsParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName;
[6053]342        op.ParentsParameter.Hidden = true;
[3070]343        op.ChildParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName;
[6053]344        op.ChildParameter.Hidden = true;
[3070]345      }
346      foreach (IBinaryVectorManipulator op in Operators.OfType<IBinaryVectorManipulator>()) {
347        op.BinaryVectorParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName;
[6053]348        op.BinaryVectorParameter.Hidden = true;
[3070]349      }
[3124]350      foreach (IBinaryVectorMoveOperator op in Operators.OfType<IBinaryVectorMoveOperator>()) {
351        op.BinaryVectorParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName;
[6053]352        op.BinaryVectorParameter.Hidden = true;
[3124]353      }
354      foreach (IKnapsackMoveEvaluator op in Operators.OfType<IKnapsackMoveEvaluator>()) {
355        op.KnapsackCapacityParameter.ActualName = KnapsackCapacityParameter.Name;
[6053]356        op.KnapsackCapacityParameter.Hidden = true;
[3124]357        op.PenaltyParameter.ActualName = PenaltyParameter.Name;
[6053]358        op.PenaltyParameter.Hidden = true;
[3124]359        op.WeightsParameter.ActualName = WeightsParameter.Name;
[6053]360        op.WeightsParameter.Hidden = true;
[3124]361        op.ValuesParameter.ActualName = ValuesParameter.Name;
[6053]362        op.ValuesParameter.Hidden = true;
[3124]363      }
[6053]364      foreach (var op in Operators.OfType<IBinaryVectorMultiNeighborhoodShakingOperator>()) {
[6042]365        op.BinaryVectorParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName;
[6053]366        op.BinaryVectorParameter.Hidden = true;
367      }
[3070]368    }
369    #endregion
[4098]370
371    private void InitializeRandomKnapsackInstance() {
372      System.Random rand = new System.Random();
373
374      int itemCount = rand.Next(10, 100);
375      Weights = new IntArray(itemCount);
376      Values = new IntArray(itemCount);
377
378      double totalWeight = 0;
379
380      for (int i = 0; i < itemCount; i++) {
381        int value = rand.Next(1, 10);
382        int weight = rand.Next(1, 10);
383
384        Values[i] = value;
385        Weights[i] = weight;
386        totalWeight += weight;
387      }
388
389      int capacity = (int)Math.Round(0.7 * totalWeight);
390      KnapsackCapacity = new IntValue(capacity);
391    }
[3070]392  }
393}
Note: See TracBrowser for help on using the repository browser.