public static IEnumerable <double[]> SelectNonDominatedVectors(IEnumerable <double[]> qualities, bool[] maximization, bool dominateOnEqualQualities)
        {
            List <double[]> front = new List <double[]>();

            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 override IOperation Apply()
        {
            bool dominateOnEqualQualities = DominateOnEqualQualitiesParameter.ActualValue.Value;

            bool[]     maximization = MaximizationParameter.ActualValue.ToArray();
            double[][] qualities    = QualitiesParameter.ActualValue.Select(x => x.ToArray()).ToArray();
            if (qualities == null)
            {
                throw new InvalidOperationException(Name + ": No qualities found.");
            }

            IScope scope          = ExecutionContext.Scope;
            int    populationSize = scope.SubScopes.Count;

            List <ScopeList> fronts = new List <ScopeList>();
            Dictionary <IScope, List <int> > dominatedScopes = new Dictionary <IScope, List <int> >();

            int[] dominationCounter   = new int[populationSize];
            ItemArray <IntValue> rank = new ItemArray <IntValue>(populationSize);

            for (int pI = 0; pI < populationSize - 1; pI++)
            {
                IScope     p = scope.SubScopes[pI];
                List <int> dominatedScopesByp;
                if (!dominatedScopes.TryGetValue(p, out dominatedScopesByp))
                {
                    dominatedScopes[p] = dominatedScopesByp = new List <int>();
                }
                for (int qI = pI + 1; qI < populationSize; qI++)
                {
                    DominationResult test = Dominates(qualities[pI], qualities[qI], maximization, dominateOnEqualQualities);
                    if (test == DominationResult.Dominates)
                    {
                        dominatedScopesByp.Add(qI);
                        dominationCounter[qI] += 1;
                    }
                    else if (test == DominationResult.IsDominated)
                    {
                        dominationCounter[pI] += 1;
                        if (!dominatedScopes.ContainsKey(scope.SubScopes[qI]))
                        {
                            dominatedScopes.Add(scope.SubScopes[qI], new List <int>());
                        }
                        dominatedScopes[scope.SubScopes[qI]].Add(pI);
                    }
                    if (pI == populationSize - 2 &&
                        qI == populationSize - 1 &&
                        dominationCounter[qI] == 0)
                    {
                        rank[qI] = new IntValue(0);
                        AddToFront(scope.SubScopes[qI], fronts, 0);
                    }
                }
                if (dominationCounter[pI] == 0)
                {
                    rank[pI] = new IntValue(0);
                    AddToFront(p, fronts, 0);
                }
            }
            int i = 0;

            while (i < fronts.Count && fronts[i].Count > 0)
            {
                ScopeList nextFront = new ScopeList();
                foreach (IScope p in fronts[i])
                {
                    List <int> dominatedScopesByp;
                    if (dominatedScopes.TryGetValue(p, out dominatedScopesByp))
                    {
                        for (int k = 0; k < dominatedScopesByp.Count; k++)
                        {
                            int dominatedScope = dominatedScopesByp[k];
                            dominationCounter[dominatedScope] -= 1;
                            if (dominationCounter[dominatedScope] == 0)
                            {
                                rank[dominatedScope] = new IntValue(i + 1);
                                nextFront.Add(scope.SubScopes[dominatedScope]);
                            }
                        }
                    }
                }
                i += 1;
                fronts.Add(nextFront);
            }

            RankParameter.ActualValue = rank;

            scope.SubScopes.Clear();

            for (i = 0; i < fronts.Count; i++)
            {
                Scope frontScope = new Scope("Front " + i);
                foreach (var p in fronts[i])
                {
                    frontScope.SubScopes.Add(p);
                }
                if (frontScope.SubScopes.Count > 0)
                {
                    scope.SubScopes.Add(frontScope);
                }
            }
            return(base.Apply());
        }