Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2521_ProblemRefactoring/HeuristicLab.Problems.LinearAssignment/3.3/LinearAssignmentProblem.cs @ 17226

Last change on this file since 17226 was 17226, checked in by mkommend, 5 years ago

#2521: Merged trunk changes into problem refactoring branch.

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