/// <summary> /// Is Dominated /// </summary> public bool IsDominated(ObjectiveItem <T> other) { if (ReferenceEquals(this, other)) { return(false); } else if (null == other) { return(false); } else if (!ReferenceEquals(Owner, other.Owner)) { return(false); } foreach (var description in Owner.ObjectiveDescriptions) { double v1 = this.ObjectiveValue(description); double v2 = other.ObjectiveValue(description); if (v2 > v1 && description.Goal == ObjectiveGoal.Min) { return(false); } if (v2 < v1 && description.Goal == ObjectiveGoal.Max) { return(false); } } return(true); }
/// <summary> /// Standard Constructor /// </summary> /// <param name="solutions">Solutions</param> /// <param name="objectives">Objectives</param> public ObjectivesScope(IEnumerable <T> solutions, IEnumerable <ObjectiveDescription <T> > objectives) { if (null == solutions) { throw new ArgumentNullException(nameof(solutions)); } else if (null == objectives) { throw new ArgumentNullException(nameof(objectives)); } m_ObjectiveDescriptions = new List <ObjectiveDescription <T> >(objectives); foreach (var solution in solutions) { if (null == solution) { continue; } ObjectiveItem <T> item = new ObjectiveItem <T>(this, solution); m_Items.Add(item); } }
public int Compare(ObjectiveItem <T> x, ObjectiveItem <T> y) { if (ReferenceEquals(x, y)) { return(0); } else if (null == x) { return(-1); } else if (null == y) { return(+1); } if (!ReferenceEquals(x.Owner, y.Owner)) { return(0); } int result = x.FrontierLevel.CompareTo(y.FrontierLevel); if (result < 0) { return(1); } else if (result > 0) { return(-1); } result = x.CrowdingDistance.CompareTo(y.CrowdingDistance); if (result != 0) { return(result); } return(0); }
/// <summary> /// Dominance: /// +1: left dominates right /// 0: left and right are not comparable /// -1: right dominates left /// </summary> public static int Dominance(ObjectiveItem <T> left, ObjectiveItem <T> right) { if (ReferenceEquals(left, right)) { return(0); } else if (null == left) { return(-1); } else if (null == right) { return(1); } else if (!ReferenceEquals(left.Owner, right.Owner)) { return(0); } bool canBeBetter = true; bool canBeWorse = true; foreach (var description in left.Owner.ObjectiveDescriptions) { double v1 = left.ObjectiveValue(description); double v2 = right.ObjectiveValue(description); if (v1 > v2 && description.Goal == ObjectiveGoal.Min) { canBeBetter = false; } else if (v1 < v2 && description.Goal == ObjectiveGoal.Max) { canBeBetter = false; } if (v2 > v1 && description.Goal == ObjectiveGoal.Min) { canBeWorse = false; } else if (v2 < v1 && description.Goal == ObjectiveGoal.Max) { canBeWorse = false; } if (!canBeBetter && !canBeWorse) { return(0); } } if (canBeBetter) { return(1); } else if (canBeWorse) { return(-1); } return(0); }
internal void CoreUpdate() { if (m_IsUpdated) { return; } m_IsUpdated = true; // dominance for (int i = 0; i < m_Items.Count; ++i) { for (int j = i + 1; j < m_Items.Count; ++j) { ObjectiveItem <T> left = m_Items[i]; ObjectiveItem <T> right = m_Items[j]; int d = ObjectiveItem <T> .Dominance(left, right); if (d > 0) { left.m_BetterThan.Add(right); right.m_WorseThan.Add(left); } else if (d < 0) { right.m_BetterThan.Add(left); left.m_WorseThan.Add(right); } } } // frontiers HashSet <ObjectiveItem <T> > agenda = new HashSet <ObjectiveItem <T> >(m_Items); HashSet <ObjectiveItem <T> > skips = new HashSet <ObjectiveItem <T> >(); int level = 0; while (agenda.Any()) { level += 1; List <ObjectiveItem <T> > exclude = new List <ObjectiveItem <T> >(m_Items.Count); foreach (var item in agenda) { if (item.WorseThan.All(x => skips.Contains(x))) { exclude.Add(item); item.m_FrontierLevel = level; } } m_Frontiers.Add(level, exclude); agenda.ExceptWith(exclude); skips.UnionWith(exclude); } }