Changeset 17530
- Timestamp:
- 05/08/20 12:06:23 (5 years ago)
- Location:
- branches/2521_ProblemRefactoring/HeuristicLab.Problems.LinearAssignment/3.3
- Files:
-
- 3 deleted
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2521_ProblemRefactoring/HeuristicLab.Problems.LinearAssignment/3.3/HeuristicLab.Problems.LinearAssignment-3.3.csproj
r16723 r17530 122 122 <Compile Include="LAPAssignment.cs" /> 123 123 <None Include="Plugin.cs.frame" /> 124 <Compile Include="Analyzers\BestLAPSolutionAnalyzer.cs" />125 <Compile Include="Interfaces\ILAPEvaluator.cs" />126 <Compile Include="LAPEvaluator.cs" />127 124 <Compile Include="LinearAssignmentProblem.cs" /> 128 125 <Compile Include="LinearAssignmentProblemSolver.cs" /> -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.LinearAssignment/3.3/HungarianAlgorithm.cs
r17226 r17530 21 21 22 22 using System; 23 using System. Linq;24 using H euristicLab.Analysis;23 using System.Threading; 24 using HEAL.Attic; 25 25 using HeuristicLab.Common; 26 26 using HeuristicLab.Core; 27 using HeuristicLab. Operators;27 using HeuristicLab.Encodings.PermutationEncoding; 28 28 using HeuristicLab.Optimization; 29 using HeuristicLab.Parameters;30 using HEAL.Attic;31 29 32 30 namespace HeuristicLab.Problems.LinearAssignment { … … 37 35 [Creatable(CreatableAttribute.Categories.SingleSolutionAlgorithms, Priority = 170)] 38 36 [StorableType("2A2C1C1B-E0C3-4757-873B-C3F7C6D11A01")] 39 public sealed class HungarianAlgorithm : EngineAlgorithm, IStorableContent{40 public string Filename { get; set; }37 public sealed class HungarianAlgorithm : BasicAlgorithm { 38 public override bool SupportsPause => false; 41 39 42 40 #region Problem Properties … … 50 48 #endregion 51 49 52 #region Parameter Properties53 private ValueParameter<MultiAnalyzer> AnalyzerParameter {54 get { return (ValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }55 }56 #endregion57 58 #region Properties59 public MultiAnalyzer Analyzer {60 get { return AnalyzerParameter.Value; }61 set { AnalyzerParameter.Value = value; }62 }63 private LinearAssignmentProblemSolver Solver {64 get { return (LinearAssignmentProblemSolver)OperatorGraph.InitialOperator; }65 }66 #endregion67 68 50 [StorableConstructor] 69 51 private HungarianAlgorithm(StorableConstructorFlag _) : base(_) { } 70 private HungarianAlgorithm(HungarianAlgorithm original, Cloner cloner) 71 : base(original, cloner) { 72 RegisterEventHandlers(); 73 } 52 private HungarianAlgorithm(HungarianAlgorithm original, Cloner cloner) : base(original, cloner) { } 74 53 public HungarianAlgorithm() 75 54 : base() { 76 Parameters.Add(new ValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze the result.", new MultiAnalyzer()));77 78 var solver = new LinearAssignmentProblemSolver();79 OperatorGraph.InitialOperator = solver;80 81 var placeholder = new Placeholder();82 placeholder.Name = "(Analyzer)";83 placeholder.OperatorParameter.ActualName = AnalyzerParameter.Name;84 solver.Successor = placeholder;85 86 UpdateAnalyzers();87 RegisterEventHandlers();88 89 55 Problem = new LinearAssignmentProblem(); 90 56 } … … 94 60 } 95 61 96 public override void Prepare() { 97 if (Problem != null) base.Prepare(); 62 protected override void Run(CancellationToken cancellationToken) { 63 var assignment = LinearAssignmentProblemSolver.Solve(Problem.Costs, out double quality); 64 65 Problem.Analyze(new[] { new Permutation(PermutationTypes.Absolute, assignment) }, 66 new[] { quality }, Results, null); 98 67 } 99 100 #region Events101 protected override void OnProblemChanged() {102 Problem.SolutionCreatorChanged += new EventHandler(Problem_SolutionCreatorChanged);103 Problem.EvaluatorChanged += new EventHandler(Problem_EvaluatorChanged);104 UpdateAnalyzers();105 Parameterize();106 base.OnProblemChanged();107 }108 109 private void Problem_SolutionCreatorChanged(object sender, EventArgs e) {110 Parameterize();111 }112 113 private void Problem_EvaluatorChanged(object sender, EventArgs e) {114 Parameterize();115 }116 117 protected override void Problem_OperatorsChanged(object sender, EventArgs e) {118 UpdateAnalyzers();119 base.Problem_OperatorsChanged(sender, e);120 }121 #endregion122 123 #region Helpers124 [StorableHook(HookType.AfterDeserialization)]125 private void AfterDeserialization() {126 RegisterEventHandlers();127 }128 129 private void RegisterEventHandlers() {130 if (Problem != null) {131 Problem.SolutionCreatorChanged += new EventHandler(Problem_SolutionCreatorChanged);132 Problem.EvaluatorChanged += new EventHandler(Problem_EvaluatorChanged);133 }134 }135 private void UpdateAnalyzers() {136 Analyzer.Operators.Clear();137 if (Problem != null) {138 foreach (var analyzer in Problem.OperatorsParameter.Value.OfType<IAnalyzer>()) {139 foreach (IScopeTreeLookupParameter param in analyzer.Parameters.OfType<IScopeTreeLookupParameter>())140 param.Depth = 0;141 Analyzer.Operators.Add(analyzer);142 }143 }144 }145 private void Parameterize() {146 if (Problem != null) {147 Solver.AssignmentParameter.ActualName = Problem.SolutionCreator.PermutationParameter.ActualName;148 Solver.CostsParameter.ActualName = Problem.CostsParameter.Name;149 Solver.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;150 }151 }152 #endregion153 68 } 154 69 } -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.LinearAssignment/3.3/LinearAssignmentProblem.cs
r17226 r17530 23 23 using System.Drawing; 24 24 using System.Linq; 25 using System.Threading; 26 using HEAL.Attic; 25 27 using HeuristicLab.Analysis; 26 28 using HeuristicLab.Common; … … 31 33 using HeuristicLab.Optimization.Operators; 32 34 using HeuristicLab.Parameters; 33 using HEAL.Attic;34 35 using HeuristicLab.PluginInfrastructure; 35 36 … … 38 39 [Creatable(CreatableAttribute.Categories.CombinatorialProblems, Priority = 130)] 39 40 [StorableType("7766E004-A93D-4CA6-8012-AE5E8F4C4D85")] 40 public sealed class LinearAssignmentProblem : SingleObjectiveHeuristicOptimizationProblem<ILAPEvaluator, IPermutationCreator>, 41 ISingleObjectiveProblem<PermutationEncoding,Permutation>, IStorableContent { 41 public sealed class LinearAssignmentProblem : PermutationProblem { 42 42 public static readonly string CostsDescription = "The cost matrix that describes the assignment of rows to columns."; 43 43 public static readonly string RowNamesDescription = "The elements represented by the rows of the costs matrix."; 44 44 public static readonly string ColumnNamesDescription = "The elements represented by the columns of the costs matrix."; 45 45 46 public string Filename { get; set; }47 48 46 public override Image ItemImage { 49 47 get { return HeuristicLab.Common.Resources.VSImageLibrary.Type; } … … 66 64 get { return (IValueParameter<StringArray>)Parameters["ColumnNames"]; } 67 65 } 66 private IResultParameter<LAPAssignment> BestLAPSolutionParameter { 67 get { return (IResultParameter<LAPAssignment>)Parameters["Best LAP Solution"]; } 68 } 69 public IResultDefinition<LAPAssignment> BestLAPSolution => BestLAPSolutionParameter; 68 70 #endregion 69 71 … … 91 93 #endregion 92 94 93 [Storable]94 private BestLAPSolutionAnalyzer bestLAPSolutionAnalyzer;95 96 95 [StorableConstructor] 97 96 private LinearAssignmentProblem(StorableConstructorFlag _) : base(_) { } 98 97 private LinearAssignmentProblem(LinearAssignmentProblem original, Cloner cloner) 99 98 : base(original, cloner) { 100 this.bestLAPSolutionAnalyzer = cloner.Clone(original.bestLAPSolutionAnalyzer);101 99 AttachEventHandlers(); 102 100 } 103 101 public LinearAssignmentProblem() 104 : base(new LAPEvaluator(), new RandomPermutationCreator()) {102 : base(new PermutationEncoding("Assignment")) { 105 103 Parameters.Add(new ValueParameter<DoubleMatrix>("Costs", CostsDescription, new DoubleMatrix(3, 3))); 106 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)); … … 108 106 Parameters.Add(new OptionalValueParameter<StringArray>("RowNames", RowNamesDescription)); 109 107 Parameters.Add(new OptionalValueParameter<StringArray>("ColumnNames", ColumnNamesDescription)); 108 Parameters.Add(new ResultParameter<LAPAssignment>("Best LAP Solution", "The best so far LAP solution found.")); 110 109 111 110 ((ValueParameter<DoubleMatrix>)CostsParameter).ReactOnValueToStringChangedAndValueItemImageChanged = false; … … 119 118 Costs[2, 0] = 5; Costs[2, 1] = 5; Costs[2, 2] = 1; 120 119 121 bestLAPSolutionAnalyzer = new BestLAPSolutionAnalyzer();122 SolutionCreator.PermutationParameter.ActualName = "Assignment";123 120 InitializeOperators(); 124 121 Parameterize(); … … 128 125 public override IDeepCloneable Clone(Cloner cloner) { 129 126 return new LinearAssignmentProblem(this, cloner); 127 } 128 129 public override ISingleObjectiveEvaluationResult Evaluate(Permutation assignment, IRandom random, CancellationToken cancellationToken) { 130 var costs = Costs; 131 132 int len = assignment.Length; 133 double quality = 0; 134 for (int i = 0; i < len; i++) { 135 quality += costs[i, assignment[i]]; 136 } 137 138 return new SingleObjectiveEvaluationResult(quality); 139 } 140 141 public override void Analyze(Permutation[] permutations, double[] qualities, ResultCollection results, IRandom random) { 142 base.Analyze(permutations, qualities, results, random); 143 144 var costs = Costs; 145 var rowNames = RowNames; 146 var columnNames = ColumnNames; 147 bool max = Maximization; 148 149 var sorted = qualities.Select((x, index) => new { Index = index, Quality = x }).OrderBy(x => x.Quality).ToArray(); 150 if (max) Array.Reverse(sorted); 151 int i = sorted[0].Index; 152 var best = Tuple.Create(permutations[i], qualities[i]); 153 154 if (double.IsNaN(BestKnownQuality) || IsBetter(best.Item2, BestKnownQuality)) { 155 // if there isn't a best-known quality or we improved the best-known quality we'll add the current solution as best-known 156 BestKnownQuality = best.Item2; 157 BestKnownSolution = (Permutation)best.Item1.Clone(); 158 BestKnownSolutions = new ItemSet<Permutation>(new PermutationEqualityComparer()); 159 BestKnownSolutions.Add((Permutation)best.Item1.Clone()); 160 } else if (BestKnownQuality == best.Item2) { 161 // if we matched the best-known quality we'll try to set the best-known solution if it isn't null 162 // and try to add it to the pool of best solutions if it is different 163 if (BestKnownSolution == null) BestKnownSolution = (Permutation)best.Item1.Clone(); 164 if (BestKnownSolutions == null) BestKnownSolutions = new ItemSet<Permutation>(new PermutationEqualityComparer()); 165 166 foreach (var k in sorted) { // for each solution that we found check if it is in the pool of best-knowns 167 if (IsBetter(best.Item2, k.Quality)) break; // stop when we reached a solution worse than the best-known quality 168 var p = permutations[k.Index]; 169 if (!BestKnownSolutions.Contains(p)) 170 BestKnownSolutions.Add((Permutation)permutations[k.Index].Clone()); 171 } 172 } 173 174 LAPAssignment solution = BestLAPSolutionParameter.ActualValue; 175 if (solution == null) { 176 solution = new LAPAssignment(costs, rowNames, columnNames, (Permutation)best.Item1.Clone(), new DoubleValue(best.Item2)); 177 BestLAPSolutionParameter.ActualValue = solution; 178 } else { 179 if (IsBetter(best.Item2, solution.Quality.Value)) { 180 solution.Costs = costs; 181 solution.Assignment = (Permutation)best.Item1.Clone(); 182 solution.Quality.Value = best.Item2; 183 if (rowNames != null) 184 solution.RowNames = rowNames; 185 else solution.RowNames = null; 186 if (columnNames != null) 187 solution.ColumnNames = columnNames; 188 else solution.ColumnNames = null; 189 } 190 } 191 130 192 } 131 193 … … 137 199 protected override void OnOperatorsChanged() { 138 200 base.OnOperatorsChanged(); 139 Parameterize();140 }141 protected override void OnSolutionCreatorChanged() {142 base.OnSolutionCreatorChanged();143 SolutionCreator.PermutationParameter.ActualNameChanged += new EventHandler(SolutionCreator_PermutationParameter_ActualNameChanged);144 201 Parameterize(); 145 202 } … … 174 231 Costs.ColumnsChanged += new EventHandler(Costs_ColumnsChanged); 175 232 Costs.Reset += new EventHandler(Costs_Reset); 176 SolutionCreator.PermutationParameter.ActualNameChanged += new EventHandler(SolutionCreator_PermutationParameter_ActualNameChanged);177 233 } 178 234 … … 180 236 Operators.AddRange(ApplicationManager.Manager.GetInstances<IPermutationOperator>()); 181 237 Operators.RemoveAll(x => x is IMoveOperator); 182 Operators.Add(bestLAPSolutionAnalyzer);183 238 184 239 Operators.Add(new HammingSimilarityCalculator()); … … 188 243 189 244 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 245 foreach (var similarityCalculator in Operators.OfType<ISolutionSimilarityCalculator>()) { 217 similarityCalculator.SolutionVariableName = SolutionCreator.PermutationParameter.ActualName;246 similarityCalculator.SolutionVariableName = Encoding.Name; 218 247 similarityCalculator.QualityVariableName = Evaluator.QualityParameter.ActualName; 219 248 } 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 249 } 229 250 #endregion
Note: See TracChangeset
for help on using the changeset viewer.