Free cookie consent management tool by TermsFeed Policy Generator

source: branches/1614_GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAP.cs @ 16728

Last change on this file since 16728 was 16728, checked in by abeham, 6 years ago

#1614: updated to new persistence and .NET 4.6.1

File size: 22.4 KB
RevLine 
[6956]1#region License Information
2/* HeuristicLab
[16728]3 * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[6956]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
[7311]22using System;
[15504]23using System.Collections.Generic;
[6956]24using System.Linq;
[16728]25using HEAL.Attic;
[15504]26using HeuristicLab.Analysis;
[6956]27using HeuristicLab.Common;
28using HeuristicLab.Core;
29using HeuristicLab.Data;
30using HeuristicLab.Encodings.IntegerVectorEncoding;
31using HeuristicLab.Optimization;
[15504]32using HeuristicLab.Optimization.Operators;
[6956]33using HeuristicLab.Parameters;
34using HeuristicLab.PluginInfrastructure;
[7443]35using HeuristicLab.Problems.Instances;
[16728]36using HEAL.Attic;
[6956]37
38namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
[15490]39  [Item("Generalized Quadratic Assignment Problem (GQAP)", "The Generalized Quadratic Assignment Problem (GQAP) is a generalization of the QAP in that it allows to assign multiple facilities (here called equipment) to a single location. The problem is described in Lee, C.G., and Ma, Z. 2003. The Generalized Quadratic Assignment Problem. Technical Report M5S 3G8, University of Toronto, Canada.")]
[16728]40  [Creatable(CreatableAttribute.Categories.CombinatorialProblems)]
41  [StorableType("20DC9B2F-F667-425E-A235-B0192CCB1BF4")]
[15504]42  public sealed class GQAP : SingleObjectiveBasicProblem<IntegerVectorEncoding>,
[7548]43    IProblemInstanceConsumer<QAPData>,
44    IProblemInstanceConsumer<CTAPData>,
45    IProblemInstanceConsumer<TSPData>,
46    IProblemInstanceConsumer<ATSPData>,
47    IProblemInstanceConsumer<GQAPData> {
[7419]48
[15504]49    public override bool Maximization { get { return false; } }
[6956]50
[15506]51    [Storable]
52    private bool initialized; // ABE: helper variable that defines if the constructor has completed
53
[7419]54    #region Parameter Descriptions
[7423]55    public static readonly string BestKnownQualityDescription = "The best known quality (if available).";
56    public static readonly string BestKnownSolutionDescription = "The best known solution (if available).";
[7438]57    public static readonly string BestKnownSolutionsDescription = "Contains an archive of best-known solutions regarding flow-distance quality and installation quality.";
[15504]58    public static readonly string ProblemInstanceDescription = "The problem instance that is to be solved.";
59    public static readonly string EvaluationDescription = "The evaluation result of a solution to the GQAP.";
[7419]60    #endregion
61
[6956]62    #region Parameter Properties
[7470]63    public OptionalValueParameter<GQAPAssignment> BestKnownSolutionParameter {
64      get { return (OptionalValueParameter<GQAPAssignment>)Parameters["BestKnownSolution"]; }
[6956]65    }
[7438]66    public OptionalValueParameter<GQAPAssignmentArchive> BestKnownSolutionsParameter {
67      get { return (OptionalValueParameter<GQAPAssignmentArchive>)Parameters["BestKnownSolutions"]; }
68    }
[15504]69    public IValueParameter<GQAPInstance> ProblemInstanceParameter {
70      get { return (IValueParameter<GQAPInstance>)Parameters["ProblemInstance"]; }
[7415]71    }
[6956]72    #endregion
73
74    #region Properties
[7470]75    public GQAPAssignment BestKnownSolution {
[7443]76      get { return BestKnownSolutionParameter.Value; }
77      set { BestKnownSolutionParameter.Value = value; }
78    }
[7448]79    public GQAPAssignmentArchive BestKnownSolutions {
80      get { return BestKnownSolutionsParameter.Value; }
81      set { BestKnownSolutionsParameter.Value = value; }
82    }
[15504]83    public GQAPInstance ProblemInstance {
84      get { return ProblemInstanceParameter.Value; }
85      set { ProblemInstanceParameter.Value = value; }
86    }
[6956]87    #endregion
88
89    [StorableConstructor]
[16728]90    private GQAP(StorableConstructorFlag _) : base(_) { }
[15504]91    private GQAP(GQAP original, Cloner cloner)
[6956]92      : base(original, cloner) {
[7432]93      RegisterEventHandlers();
[15506]94      initialized = original.initialized;
[6956]95    }
[15504]96    public GQAP() : base() {
97      Encoding = new IntegerVectorEncoding("Assignment");
[7480]98      Parameters.Add(new OptionalValueParameter<GQAPAssignment>("BestKnownSolution", BestKnownSolutionDescription, null, false));
[7438]99      Parameters.Add(new OptionalValueParameter<GQAPAssignmentArchive>("BestKnownSolutions", BestKnownSolutionsDescription, null, false));
[15504]100      Parameters.Add(new ValueParameter<GQAPInstance>("ProblemInstance", "The problem instance that is to be solved.", new GQAPInstance(), false));
[6956]101
[15504]102      InitializeOperators();
103      RegisterEventHandlers();
[15506]104      initialized = true;
105      Parameterize();
[15504]106    }
[6956]107
[15504]108    public override IDeepCloneable Clone(Cloner cloner) {
109      return new GQAP(this, cloner);
110    }
[6956]111
[15504]112    public override double Evaluate(Individual individual, IRandom random = null) {
113      var assignment = individual.IntegerVector();
114      var evaluation = ProblemInstance.Evaluate(assignment);
115      individual["Evaluation"] = evaluation;
116      return ProblemInstance.ToSingleObjective(evaluation);
117    }
[6956]118
[15504]119    public double Evaluate(IntegerVector assignment) {
120      var evaluation = ProblemInstance.Evaluate(assignment);
121      return ProblemInstance.ToSingleObjective(evaluation);
122    }
[6956]123
[15504]124    public override void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, IRandom random) {
125      AnalyzeBestSolution(results, GetBestIndividual(individuals, qualities));
126      AnalyzeParetoArchive(results,
127        individuals.Select(i => Tuple.Create((IntegerVector)i.IntegerVector().Clone(),
128        (Evaluation)i["Evaluation"])));
129    }
[6956]130
[15504]131    private void AnalyzeBestSolution(ResultCollection results, Tuple<Individual, double> best) {
132      var bestVector = best.Item1.IntegerVector();
133      var bestEvaluation = (Evaluation)best.Item1["Evaluation"];
[6956]134
[15504]135      IResult bestResult;
136      if (!results.TryGetValue("Best Solution", out bestResult)) {
137        bestResult = new Result("Best Solution", typeof(GQAPAssignment));
138        results.Add(bestResult);
139      }
140      var item = bestResult.Value as GQAPAssignment;
141      if (item == null) bestResult.Value = new GQAPAssignment((IntegerVector)bestVector.Clone(), ProblemInstance, bestEvaluation);
142      else if (ProblemInstance.ToSingleObjective(bestEvaluation)
[16728]143        < ProblemInstance.ToSingleObjective(item.Solution.Evaluation)) {
[15504]144        item.ProblemInstance = ProblemInstance;
[16728]145        item.Solution = new GQAPSolution((IntegerVector)bestVector.Clone(), bestEvaluation);
[15504]146      }
[6956]147    }
148
[15504]149    private void AnalyzeParetoArchive(ResultCollection results, IEnumerable<Tuple<IntegerVector, Evaluation>> solutions) {
150      IResult archiveResult;
151      if (!results.TryGetValue("Solution Archive", out archiveResult)) {
152        archiveResult = new Result("Solution Archive", typeof(GQAPAssignmentArchive));
153        results.Add(archiveResult);
154      }
155      var archive = archiveResult.Value as GQAPAssignmentArchive;
[15510]156      if (archive == null) {
157        archive = new GQAPAssignmentArchive(ProblemInstance);
158        archiveResult.Value = archive;
159      } else archive.ProblemInstance = ProblemInstance;
[15504]160     
161      var combinedArchive = solutions
162        .Select(x => new GQAPSolution(x.Item1, x.Item2))
163        .Concat(archive.Solutions);
164      archive.Solutions = GetFeasibleParetoFront(combinedArchive);
165     
166      if (BestKnownSolutions == null) {
167        BestKnownSolutions = archive;
168      } else {
169        var combinedArchive2 = solutions
170        .Select(x => new GQAPSolution(x.Item1, x.Item2))
171        .Concat(BestKnownSolutions.Solutions);
172        BestKnownSolutions.Solutions = GetFeasibleParetoFront(combinedArchive2);
173      }
[6956]174    }
175
[7548]176    #region Problem Instance Loading
177    public void Load(QAPData data) {
178      Name = data.Name;
179      Description = data.Description;
[7448]180
[7548]181      var weights = new DoubleMatrix(data.Weights);
182      var distances = new DoubleMatrix(data.Distances);
183      var installationCosts = new DoubleMatrix(weights.Rows, distances.Columns); // all zero
184      var capacities = new DoubleArray(Enumerable.Range(0, distances.Rows).Select(x => 1.0).ToArray());
185      var demands = new DoubleArray(Enumerable.Range(0, weights.Rows).Select(x => 1.0).ToArray());
[7443]186
[7548]187      Load(demands, capacities, weights, distances, installationCosts, new DoubleValue(1));
188      EvaluateAndLoadAssignment(data.BestKnownAssignment);
189    }
[7445]190
[7548]191    public void Load(CTAPData data) {
192      Name = data.Name;
193      Description = data.Description;
194
195      var capacities = new DoubleArray(data.MemoryCapacities);
196      var demands = new DoubleArray(data.MemoryRequirements);
197      var weights = new DoubleMatrix(data.CommunicationCosts);
198      var installationCosts = new DoubleMatrix(data.ExecutionCosts.Transpose());
199      var distances = new DoubleMatrix(capacities.Length, capacities.Length);
200      for (int i = 0; i < capacities.Length - 1; i++)
201        for (int j = i + 1; j < capacities.Length; j++) {
202          distances[i, j] = 1;
[7466]203        }
[7548]204
205      Load(demands, capacities, weights, distances, installationCosts, new DoubleValue(1));
206      EvaluateAndLoadAssignment(data.BestKnownAssignment);
[7443]207    }
208
[7548]209    public void Load(TSPData data) {
210      if (data.Dimension > 1000)
211        throw new System.IO.InvalidDataException("Instances with more than 1000 cities are not supported.");
[7448]212
[7548]213      Name = data.Name;
214      Description = data.Description;
[7466]215
[7548]216      var capacities = new DoubleArray(data.Dimension);
217      var demands = new DoubleArray(data.Dimension);
218      for (int i = 0; i < data.Dimension; i++) {
219        capacities[i] = 1;
220        demands[i] = 1;
221      }
222      var installationCosts = new DoubleMatrix(data.Dimension, data.Dimension);
223      var weights = new DoubleMatrix(data.Dimension, data.Dimension);
224      for (int i = 0; i < data.Dimension; i++)
225        weights[i, (i + 1) % data.Dimension] = 1;
226      var distances = new DoubleMatrix(data.GetDistanceMatrix());
[7466]227
[7548]228      Load(demands, capacities, weights, distances, installationCosts, new DoubleValue(1));
229      EvaluateAndLoadAssignment(data.BestKnownTour);
230    }
231
232    public void Load(ATSPData data) {
233      Name = data.Name;
234      Description = data.Description;
235
236      var capacities = new DoubleArray(data.Dimension);
237      var demands = new DoubleArray(data.Dimension);
238      for (int i = 0; i < data.Dimension; i++) {
239        capacities[i] = 1;
240        demands[i] = 1;
[7466]241      }
[7548]242      var installationCosts = new DoubleMatrix(data.Dimension, data.Dimension);
243      var weights = new DoubleMatrix(data.Dimension, data.Dimension);
244      for (int i = 0; i < data.Dimension; i++)
245        weights[i, (i + 1) % data.Dimension] = 1;
246      var distances = new DoubleMatrix(data.Distances);
247
248      Load(demands, capacities, weights, distances, installationCosts, new DoubleValue(1));
249      EvaluateAndLoadAssignment(data.BestKnownTour);
[7466]250    }
[7445]251
[7548]252    public void Load(GQAPData data) {
253      Name = data.Name;
254      Description = data.Description;
[7470]255
[7548]256      var capacities = new DoubleArray(data.Capacities);
257      var demands = new DoubleArray(data.Demands);
258      var installationCosts = new DoubleMatrix(data.InstallationCosts);
259      var weights = new DoubleMatrix(data.Weights);
260      var distances = new DoubleMatrix(data.Distances);
261      var transportationCosts = new DoubleValue(data.TransportationCosts);
[7445]262
[7548]263      Load(demands, capacities, weights, distances, installationCosts, transportationCosts);
264      EvaluateAndLoadAssignment(data.BestKnownAssignment);
[7466]265
[7548]266      if (data.BestKnownAssignment == null && data.BestKnownQuality.HasValue) {
[15504]267        BestKnownQuality = data.BestKnownQuality.Value;
[7445]268      }
269    }
270
[7548]271    public void Load(DoubleArray demands, DoubleArray capacities,
272      DoubleMatrix weights, DoubleMatrix distances, DoubleMatrix installationCosts,
[7970]273      DoubleValue transportationCosts) {
[7548]274      if (weights == null || weights.Rows == 0)
275        throw new System.IO.InvalidDataException(
276@"The given instance does not contain weights!");
277      if (weights.Rows != weights.Columns)
278        throw new System.IO.InvalidDataException(
[7970]279@"The weights matrix of the given instance contains
280an unequal number of rows and columns.");
[7548]281      if (distances == null || distances.Rows == 0)
282        throw new System.IO.InvalidDataException(
283@"The given instance does not contain distances!");
284      if (distances.Rows != distances.Columns)
285        throw new System.IO.InvalidDataException(
[7970]286@"The distances matrix of the given instance contains
287an unequal number of rows and columns.");
[7548]288      if (installationCosts == null || installationCosts.Rows == 0)
289        throw new System.IO.InvalidDataException(
290@"The given instance does not contain installation costs!");
291      if (installationCosts.Rows != weights.Rows
292        || installationCosts.Columns != distances.Columns)
293        throw new System.IO.InvalidDataException(
[7970]294@"The installation costs matrix of the given instance
295contains different number of rows than given in the
296weights matrix and a different number of columns than
[7548]297given in the distances matrix.");
298      if (capacities == null || capacities.Length == 0)
299        throw new System.IO.InvalidDataException(
300@"The given instance does not contain capacities!");
301      if (capacities.Length != distances.Rows)
302        throw new System.IO.InvalidDataException(
[7970]303@"The given instance contains a different number of
304capacities than rows given in the distances matrix.");
[7548]305      if (demands == null || demands.Length == 0)
306        throw new System.IO.InvalidDataException(
307@"The given instance does not contain demands!");
308      if (demands.Length != weights.Rows)
309        throw new System.IO.InvalidDataException(
[7970]310@"The given instance contains a different number of
311demands than rows given in the weights matrix.");
[7548]312      if (transportationCosts == null)
313        throw new System.IO.InvalidDataException(
314@"The given instance does not contain transportation costs.");
[7523]315
[15504]316      ProblemInstance = new GQAPInstance() {
317        Weights = weights,
318        Distances = distances,
319        InstallationCosts = installationCosts,
320        Capacities = capacities,
321        Demands = demands,
322        TransportationCosts = transportationCosts.Value
323      };
324      BestKnownQualityParameter.Value = null;
[7548]325      BestKnownSolution = null;
326      BestKnownSolutions = null;
[15504]327      ProblemInstance.CalculatePenaltyLevel();
[7523]328    }
[7445]329    private void EvaluateAndLoadAssignment(int[] vector) {
[7548]330      if (vector == null || vector.Length == 0) return;
[7471]331      EvaluateAndLoadAssignment(new IntegerVector(vector));
332    }
[7548]333    public void EvaluateAndLoadAssignment(IntegerVector assignment) {
[15504]334      if (!ProblemInstance.IsValid()) {
335        BestKnownQualityParameter.Value = null;
[7523]336        BestKnownSolution = null;
337        BestKnownSolutions = null;
[15504]338        return;
[7523]339      }
[15504]340      var evaluation = ProblemInstance.Evaluate(assignment);
341      var quality = ProblemInstance.ToSingleObjective(evaluation);
342     
343      BestKnownSolution = new GQAPAssignment((IntegerVector)assignment.Clone(), ProblemInstance, evaluation);
344      BestKnownQuality = quality;
345      BestKnownSolutions = new GQAPAssignmentArchive(ProblemInstance);
346      BestKnownSolutions.Solutions.Add(new GQAPSolution((IntegerVector)assignment.Clone(), evaluation));
[7445]347    }
[7548]348    #endregion
[7445]349
[6956]350    #region Events
[7311]351    protected override void OnOperatorsChanged() {
352      base.OnOperatorsChanged();
[15506]353      if (!initialized) return;
[7311]354      Parameterize();
355    }
[15504]356    protected override void OnEncodingChanged() {
357      base.OnEncodingChanged();
[15506]358      if (!initialized) return;
[7311]359      Parameterize();
360    }
[6956]361    #endregion
362
363    #region Helpers
364    [StorableHook(HookType.AfterDeserialization)]
[7412]365    private void AfterDeserialization() {
[7432]366      RegisterEventHandlers();
[6956]367    }
368
[7432]369    private void RegisterEventHandlers() {
[15504]370      ProblemInstanceParameter.ValueChanged += ProblemInstanceParameterOnValueChanged;
371      ProblemInstance.CapacitiesParameter.ValueChanged += ProblemInstanceCapacitiesParameterOnValueChanged;
372      ProblemInstance.DemandsParameter.ValueChanged += ProblemInstanceDemandsParameterOnValueChanged;
373      ProblemInstance.Capacities.Reset += ProblemInstanceCapacitiesOnReset;
374      ProblemInstance.Demands.Reset += ProblemInstanceDemandsOnReset;
[6956]375    }
376
[15504]377    private void ProblemInstanceParameterOnValueChanged(object sender, EventArgs e) {
378      ProblemInstance.CapacitiesParameter.ValueChanged += ProblemInstanceCapacitiesParameterOnValueChanged;
379      ProblemInstance.Capacities.Reset += ProblemInstanceCapacitiesOnReset;
380      ProblemInstance.DemandsParameter.ValueChanged += ProblemInstanceDemandsParameterOnValueChanged;
381      ProblemInstance.Demands.Reset += ProblemInstanceDemandsOnReset;
382      UpdateEncoding();
383    }
384    private void ProblemInstanceCapacitiesParameterOnValueChanged(object sender, EventArgs e) {
385      ProblemInstance.Capacities.Reset += ProblemInstanceCapacitiesOnReset;
386      UpdateEncoding();
387    }
388    private void ProblemInstanceDemandsParameterOnValueChanged(object sender, EventArgs e) {
389      ProblemInstance.Demands.Reset += ProblemInstanceDemandsOnReset;
390      UpdateEncoding();
391    }
392    private void ProblemInstanceDemandsOnReset(object sender, EventArgs e) {
393      UpdateEncoding();
394    }
395    private void ProblemInstanceCapacitiesOnReset(object sender, EventArgs e) {
396      UpdateEncoding();
397    }
398
399    private void UpdateEncoding() {
400      Encoding.Length = ProblemInstance.Demands.Length;
401      Encoding.Bounds = new IntMatrix(new int[,] { { 0, ProblemInstance.Capacities.Length } });
402    }
403
[6956]404    private void InitializeOperators() {
[15510]405      Operators.RemoveAll(x => x is ISingleObjectiveMoveOperator);
406      Operators.RemoveAll(x => x is SingleObjectiveImprover);
[7415]407      Operators.AddRange(ApplicationManager.Manager.GetInstances<IGQAPOperator>());
[7413]408      Operators.AddRange(ApplicationManager.Manager.GetInstances<IGQAPMoveEvaluator>());
[15506]409      Operators.Add(new HammingSimilarityCalculator() { SolutionVariableName = Encoding.Name, QualityVariableName = Evaluator.QualityParameter.ActualName });
410      Operators.Add(new QualitySimilarityCalculator() { SolutionVariableName = Encoding.Name, QualityVariableName = Evaluator.QualityParameter.ActualName });
[15504]411     
412      Operators.Add(new PopulationSimilarityAnalyzer(Operators.OfType<ISolutionSimilarityCalculator>()));
[6956]413    }
[7311]414
415    private void Parameterize() {
[7419]416      var operators = Operators.Union(new IOperator[] { SolutionCreator, Evaluator }).ToArray();
[15506]417      Encoding.ConfigureOperators(operators.OfType<IOperator>());
418      foreach (var op in operators.OfType<IAssignmentAwareGQAPOperator>()) {
419        op.AssignmentParameter.ActualName = Encoding.Name;
420        op.AssignmentParameter.Hidden = true;
421      }
[7419]422      foreach (var op in operators.OfType<IBestKnownQualityAwareGQAPOperator>()) {
423        op.BestKnownQualityParameter.ActualName = BestKnownQualityParameter.Name;
[7970]424        op.BestKnownQualityParameter.Hidden = true;
[7419]425      }
426      foreach (var op in operators.OfType<IBestKnownSolutionAwareGQAPOperator>()) {
427        op.BestKnownSolutionParameter.ActualName = BestKnownSolutionParameter.Name;
[7970]428        op.BestKnownSolutionParameter.Hidden = true;
[7419]429      }
[7438]430      foreach (var op in operators.OfType<IBestKnownSolutionsAwareGQAPOperator>()) {
431        op.BestKnownSolutionsParameter.ActualName = BestKnownSolutionsParameter.Name;
[7970]432        op.BestKnownSolutionsParameter.Hidden = true;
[7438]433      }
[7419]434      foreach (var op in operators.OfType<IGQAPCrossover>()) {
[15504]435        op.ParentsParameter.ActualName = Encoding.Name;
[7970]436        op.ParentsParameter.Hidden = true;
[15504]437        op.ChildParameter.ActualName = Encoding.Name;
[7970]438        op.ChildParameter.Hidden = true;
[7319]439      }
[7419]440      var moveEvaluator = operators.OfType<IGQAPMoveEvaluator>().FirstOrDefault();
441      foreach (var op in operators.OfType<IGQAPMoveEvaluator>()) { // synchronize all move evaluators
442        if (moveEvaluator != null) {
443          op.MoveQualityParameter.ActualName = moveEvaluator.MoveQualityParameter.ActualName;
[7970]444          op.MoveQualityParameter.Hidden = true;
[15504]445          op.MoveEvaluationParameter.ActualName = "MoveEvaluation";
446          op.MoveEvaluationParameter.Hidden = true;
[7419]447        }
448      }
449      foreach (var op in operators.OfType<IMoveQualityAwareGQAPOperator>()) {
450        if (moveEvaluator != null) {
451          op.MoveQualityParameter.ActualName = moveEvaluator.MoveQualityParameter.ActualName;
[7970]452          op.MoveQualityParameter.Hidden = true;
[15504]453          op.MoveEvaluationParameter.ActualName = "MoveEvaluation";
454          op.MoveEvaluationParameter.Hidden = true;
[7419]455        }
456      }
[15504]457      foreach (var op in operators.OfType<IProblemInstanceAwareGQAPOperator>()) {
458        op.ProblemInstanceParameter.ActualName = ProblemInstanceParameter.Name;
459        op.ProblemInstanceParameter.Hidden = true;
[7419]460      }
461      foreach (var op in operators.OfType<IQualitiesAwareGQAPOperator>()) {
[7412]462        op.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
[7970]463        op.QualityParameter.Hidden = true;
[15504]464        op.EvaluationParameter.ActualName = "Evaluation";
465        op.EvaluationParameter.Hidden = true;
[7407]466      }
[7419]467      foreach (var op in operators.OfType<IQualityAwareGQAPOperator>()) {
[7412]468        op.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
[7970]469        op.QualityParameter.Hidden = true;
[15504]470        op.EvaluationParameter.ActualName = "Evaluation";
471        op.EvaluationParameter.Hidden = true;
[7412]472      }
[15504]473    }
474    #endregion
[7407]475
[15504]476    public static ItemList<GQAPSolution> GetFeasibleParetoFront(IEnumerable<GQAPSolution> solutions) {
477      var front = new ItemList<GQAPSolution>(solutions.Where(x => x.Evaluation.IsFeasible));
[7970]478
[15504]479      for (int i = 0; i < front.Count - 1; i++) {
480        for (int j = i + 1; j < front.Count; j++) {
481          if (front[i].Evaluation.FlowCosts <= front[j].Evaluation.FlowCosts
482            && front[i].Evaluation.InstallationCosts <= front[j].Evaluation.InstallationCosts) {
483            front.RemoveAt(j);
484            j--;
485          } else if (front[i].Evaluation.FlowCosts >= front[j].Evaluation.FlowCosts
486            && front[i].Evaluation.InstallationCosts >= front[j].Evaluation.InstallationCosts) {
487            front.RemoveAt(i);
488            j = i;
489          }
490        }
[7970]491      }
[15504]492      return front;
[6956]493    }
494  }
495}
Note: See TracBrowser for help on using the repository browser.