source: branches/ProblemRefactoring/HeuristicLab.Problems.LinearAssignment/3.3/LinearAssignmentProblem.cs @ 13377

Last change on this file since 13377 was 13377, checked in by mkommend, 7 years ago

#2521: Added missing interfaces to problems.

File size: 10.3 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 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.Drawing;
24using System.Linq;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Encodings.PermutationEncoding;
29using HeuristicLab.Optimization;
30using HeuristicLab.Parameters;
31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32using HeuristicLab.PluginInfrastructure;
33
34namespace HeuristicLab.Problems.LinearAssignment {
35  [Item("Linear Assignment Problem (LAP)", "In the linear assignment problem (LAP) an assignment of workers to jobs has to be found such that each worker is assigned to exactly one job, each job is assigned to exactly one worker and the sum of the resulting costs is minimal (or maximal).")]
36  [Creatable(CreatableAttribute.Categories.CombinatorialProblems, Priority = 130)]
37  [StorableClass]
38  public sealed class LinearAssignmentProblem : SingleObjectiveHeuristicOptimizationProblem<ILAPEvaluator, IPermutationCreator>,
39    ISingleObjectiveProblem<PermutationEncoding,Permutation>, IStorableContent {
40    public static readonly string CostsDescription = "The cost matrix that describes the assignment of rows to columns.";
41    public static readonly string RowNamesDescription = "The elements represented by the rows of the costs matrix.";
42    public static readonly string ColumnNamesDescription = "The elements represented by the columns of the costs matrix.";
43
44    public string Filename { get; set; }
45
46    public override Image ItemImage {
47      get { return HeuristicLab.Common.Resources.VSImageLibrary.Type; }
48    }
49
50    #region Parameter Properties
51    public IValueParameter<DoubleMatrix> CostsParameter {
52      get { return (IValueParameter<DoubleMatrix>)Parameters["Costs"]; }
53    }
54    public IValueParameter<ItemSet<Permutation>> BestKnownSolutionsParameter {
55      get { return (IValueParameter<ItemSet<Permutation>>)Parameters["BestKnownSolutions"]; }
56    }
57    public IValueParameter<Permutation> BestKnownSolutionParameter {
58      get { return (IValueParameter<Permutation>)Parameters["BestKnownSolution"]; }
59    }
60    public IValueParameter<StringArray> RowNamesParameter {
61      get { return (IValueParameter<StringArray>)Parameters["RowNames"]; }
62    }
63    public IValueParameter<StringArray> ColumnNamesParameter {
64      get { return (IValueParameter<StringArray>)Parameters["ColumnNames"]; }
65    }
66    #endregion
67
68    #region Properties
69    public DoubleMatrix Costs {
70      get { return CostsParameter.Value; }
71      set { CostsParameter.Value = value; }
72    }
73    public StringArray RowNames {
74      get { return RowNamesParameter.Value; }
75      set { RowNamesParameter.Value = value; }
76    }
77    public StringArray ColumnNames {
78      get { return ColumnNamesParameter.Value; }
79      set { ColumnNamesParameter.Value = value; }
80    }
81    public ItemSet<Permutation> BestKnownSolutions {
82      get { return BestKnownSolutionsParameter.Value; }
83      set { BestKnownSolutionsParameter.Value = value; }
84    }
85    public Permutation BestKnownSolution {
86      get { return BestKnownSolutionParameter.Value; }
87      set { BestKnownSolutionParameter.Value = value; }
88    }
89    #endregion
90
91    [Storable]
92    private BestLAPSolutionAnalyzer bestLAPSolutionAnalyzer;
93
94    [StorableConstructor]
95    private LinearAssignmentProblem(bool deserializing) : base(deserializing) { }
96    private LinearAssignmentProblem(LinearAssignmentProblem original, Cloner cloner)
97      : base(original, cloner) {
98      this.bestLAPSolutionAnalyzer = cloner.Clone(original.bestLAPSolutionAnalyzer);
99      AttachEventHandlers();
100    }
101    public LinearAssignmentProblem()
102      : base(new LAPEvaluator(), new RandomPermutationCreator()) {
103      Parameters.Add(new ValueParameter<DoubleMatrix>("Costs", CostsDescription, new DoubleMatrix(3, 3)));
104      Parameters.Add(new OptionalValueParameter<ItemSet<Permutation>>("BestKnownSolutions", "The list of best known solutions which is updated whenever a new better solution is found or may be the optimal solution if it is known beforehand.", null));
105      Parameters.Add(new OptionalValueParameter<Permutation>("BestKnownSolution", "The best known solution which is updated whenever a new better solution is found or may be the optimal solution if it is known beforehand.", null));
106      Parameters.Add(new OptionalValueParameter<StringArray>("RowNames", RowNamesDescription));
107      Parameters.Add(new OptionalValueParameter<StringArray>("ColumnNames", ColumnNamesDescription));
108
109      ((ValueParameter<DoubleMatrix>)CostsParameter).ReactOnValueToStringChangedAndValueItemImageChanged = false;
110      ((OptionalValueParameter<StringArray>)RowNamesParameter).ReactOnValueToStringChangedAndValueItemImageChanged = false;
111      ((OptionalValueParameter<StringArray>)ColumnNamesParameter).ReactOnValueToStringChangedAndValueItemImageChanged = false;
112
113      RowNames = new StringArray(new string[] { "Eric", "Robert", "Allison" });
114      ColumnNames = new StringArray(new string[] { "MRI", "Blood test", "Angiogram" });
115      Costs[0, 0] = 4; Costs[0, 1] = 5; Costs[0, 2] = 3;
116      Costs[1, 0] = 6; Costs[1, 1] = 6; Costs[1, 2] = 4;
117      Costs[2, 0] = 5; Costs[2, 1] = 5; Costs[2, 2] = 1;
118
119      bestLAPSolutionAnalyzer = new BestLAPSolutionAnalyzer();
120      SolutionCreator.PermutationParameter.ActualName = "Assignment";
121      InitializeOperators();
122      Parameterize();
123      AttachEventHandlers();
124    }
125
126    public override IDeepCloneable Clone(Cloner cloner) {
127      return new LinearAssignmentProblem(this, cloner);
128    }
129
130    #region Events
131    protected override void OnEvaluatorChanged() {
132      base.OnEvaluatorChanged();
133      Parameterize();
134    }
135    protected override void OnOperatorsChanged() {
136      base.OnOperatorsChanged();
137      Parameterize();
138    }
139    protected override void OnSolutionCreatorChanged() {
140      base.OnSolutionCreatorChanged();
141      SolutionCreator.PermutationParameter.ActualNameChanged += new EventHandler(SolutionCreator_PermutationParameter_ActualNameChanged);
142      Parameterize();
143    }
144    private void Costs_RowsChanged(object sender, EventArgs e) {
145      if (Costs.Rows != Costs.Columns) {
146        ((IStringConvertibleMatrix)Costs).Columns = Costs.Rows;
147        Parameterize();
148      }
149    }
150    private void Costs_ColumnsChanged(object sender, EventArgs e) {
151      if (Costs.Rows != Costs.Columns) {
152        ((IStringConvertibleMatrix)Costs).Rows = Costs.Columns;
153        Parameterize();
154      }
155    }
156    private void Costs_Reset(object sender, EventArgs e) {
157      Parameterize();
158    }
159    private void SolutionCreator_PermutationParameter_ActualNameChanged(object sender, EventArgs e) {
160      Parameterize();
161    }
162    #endregion
163
164    #region Helpers
165    [StorableHook(HookType.AfterDeserialization)]
166    private void AfterDeserialization() {
167      AttachEventHandlers();
168    }
169
170    private void AttachEventHandlers() {
171      Costs.RowsChanged += new EventHandler(Costs_RowsChanged);
172      Costs.ColumnsChanged += new EventHandler(Costs_ColumnsChanged);
173      Costs.Reset += new EventHandler(Costs_Reset);
174      SolutionCreator.PermutationParameter.ActualNameChanged += new EventHandler(SolutionCreator_PermutationParameter_ActualNameChanged);
175    }
176
177    private void InitializeOperators() {
178      Operators.AddRange(ApplicationManager.Manager.GetInstances<IPermutationOperator>());
179      Operators.RemoveAll(x => x is IMoveOperator);
180      Operators.Add(bestLAPSolutionAnalyzer);
181    }
182
183    private void Parameterize() {
184      SolutionCreator.LengthParameter.Value = new IntValue(Costs.Rows);
185      SolutionCreator.LengthParameter.Hidden = true;
186      SolutionCreator.PermutationTypeParameter.Value = new PermutationType(PermutationTypes.Absolute);
187      SolutionCreator.PermutationTypeParameter.Hidden = true;
188      Evaluator.CostsParameter.ActualName = CostsParameter.Name;
189      Evaluator.CostsParameter.Hidden = true;
190      Evaluator.AssignmentParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
191      Evaluator.AssignmentParameter.Hidden = true;
192
193      foreach (var op in Operators.OfType<IPermutationCrossover>()) {
194        op.ParentsParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
195        op.ParentsParameter.Hidden = true;
196        op.ChildParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
197        op.ChildParameter.Hidden = true;
198      }
199
200      foreach (var op in Operators.OfType<IPermutationManipulator>()) {
201        op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
202        op.PermutationParameter.Hidden = true;
203      }
204
205      foreach (var op in Operators.OfType<IPermutationMultiNeighborhoodShakingOperator>()) {
206        op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
207        op.PermutationParameter.Hidden = true;
208      }
209
210      bestLAPSolutionAnalyzer.AssignmentParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
211      bestLAPSolutionAnalyzer.BestKnownQualityParameter.ActualName = BestKnownQualityParameter.Name;
212      bestLAPSolutionAnalyzer.BestKnownSolutionParameter.ActualName = BestKnownSolutionParameter.Name;
213      bestLAPSolutionAnalyzer.BestKnownSolutionsParameter.ActualName = BestKnownSolutionsParameter.Name;
214      bestLAPSolutionAnalyzer.CostsParameter.ActualName = CostsParameter.Name;
215      bestLAPSolutionAnalyzer.MaximizationParameter.ActualName = MaximizationParameter.Name;
216      bestLAPSolutionAnalyzer.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
217    }
218    #endregion
219  }
220}
Note: See TracBrowser for help on using the repository browser.