Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 5124 was 4722, checked in by swagner, 14 years ago

Merged cloning refactoring branch back into trunk (#922)

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