Pareto Optimization

G
using System.Collections.Generic;
using System.Linq;

namespace Algorithms.Other;

/// <summary>
/// Almost all real complex decision-making task is described by more than one criterion.
/// Therefore, the methods of multicriteria optimization are important. For a wide range
/// of tasks multicriteria optimization, described by some axioms of "reasonable"
/// behavior in the process of choosing from a set of possible solutions X, each set of
/// selected solutions Sel X should be contained in a set optimal for Pareto.
/// </summary>
public class ParetoOptimization
{
    /// <summary>
    /// Performs decision optimizations by using Paretor's optimization algorithm.
    /// </summary>
    /// <param name="matrix">Contains a collection of the criterias sets.</param>
    /// <returns>An optimized collection of the criterias sets.</returns>
    public List<List<decimal>> Optimize(List<List<decimal>> matrix)
    {
        var optimizedMatrix = new List<List<decimal>>(matrix.Select(i => i));
        int i = 0;
        while (i < optimizedMatrix.Count)
        {
            for (int j = i + 1; j < optimizedMatrix.Count; j++)
            {
                decimal directParwiseDifference = GetMinimalPairwiseDifference(optimizedMatrix[i], optimizedMatrix[j]);
                decimal indirectParwiseDifference = GetMinimalPairwiseDifference(optimizedMatrix[j], optimizedMatrix[i]);
                /*
                 * in case all criteria of one set are larger that the criteria of another, this
                 * decision is not optimal and it has to be removed
                */
                if (directParwiseDifference >= 0 || indirectParwiseDifference >= 0)
                {
                    optimizedMatrix.RemoveAt(directParwiseDifference >= 0 ? j : i);
                    i--;
                    break;
                }
            }

            i++;
        }

        return optimizedMatrix;
    }

    /// <summary>
    /// Calculates the smallest difference between criteria of input decisions.
    /// </summary>
    /// <param name="arr1">Criterias of the first decision.</param>
    /// <param name="arr2">Criterias of the second decision.</param>
    /// <returns>Values that represent the smallest difference between criteria of input decisions.</returns>
    private decimal GetMinimalPairwiseDifference(List<decimal> arr1, List<decimal> arr2)
    {
        decimal min = decimal.MaxValue;
        if (arr1.Count == arr2.Count)
        {
            for (int i = 0; i < arr1.Count; i++)
            {
                decimal difference = arr1[i] - arr2[i];
                if (min > difference)
                {
                    min = difference;
                }
            }
        }

        return min;
    }
}