#region License Information /* HeuristicLab * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System.Collections.Generic; namespace HeuristicLab.Problems.TestFunctions.MultiObjective { public static class NonDominatedSelect { public enum DominationResult { Dominates, IsDominated, IsNonDominated }; public static IEnumerable SelectNonDominatedVectors(IEnumerable qualities, bool[] maximization, bool dominateOnEqualQualities) { List front = new List(); foreach (double[] row in qualities) { bool insert = true; for (int i = 0; i < front.Count; i++) { DominationResult res = Dominates(front[i], row, maximization, dominateOnEqualQualities); if (res == DominationResult.Dominates) { insert = false; break; } //Vector domiates Row else if (res == DominationResult.IsDominated) { //Row dominates Vector front.RemoveAt(i); } } if (insert) { front.Add(row); } } return front; } public static IEnumerable GetDominatingVectors(IEnumerable qualities, double[] reference, bool[] maximization, bool dominateOnEqualQualities) { List front = new List(); foreach (double[] vec in qualities) { if (Dominates(vec, reference, maximization, dominateOnEqualQualities) == DominationResult.Dominates) { front.Add(vec); } } return front; } public static DominationResult Dominates(double[] left, double[] right, bool[] maximizations, bool dominateOnEqualQualities) { //mkommend Caution: do not use LINQ.SequenceEqual for comparing the two quality arrays (left and right) due to performance reasons if (dominateOnEqualQualities) { var equal = true; for (int i = 0; i < left.Length; i++) { if (left[i] != right[i]) { equal = false; break; } } if (equal) return DominationResult.Dominates; } bool leftIsBetter = false, rightIsBetter = false; for (int i = 0; i < left.Length; i++) { if (IsDominated(left[i], right[i], maximizations[i])) rightIsBetter = true; else if (IsDominated(right[i], left[i], maximizations[i])) leftIsBetter = true; if (leftIsBetter && rightIsBetter) break; } if (leftIsBetter && !rightIsBetter) return DominationResult.Dominates; if (!leftIsBetter && rightIsBetter) return DominationResult.IsDominated; return DominationResult.IsNonDominated; } private static bool IsDominated(double left, double right, bool maximization) { return maximization && left < right || !maximization && left > right; } } }