///|
pub(all) enum Method {
Additive(Normalization)
IdealDistance(Normalization)
Product
Compromise(Double)
Outranking(Array[Preference])
} derive(@debug.Debug)
///|
pub fn evaluate(
m : DecisionMatrix,
weights : Array[Double],
algorithm : Method,
tolerance~ : Double = 1.0e-10,
) -> Ranking raise ChoiceError {
match algorithm {
Additive(normalization) =>
saw(m, weights, normalization~, tolerance~).ranking
IdealDistance(normalization) =>
topsis(m, weights, normalization~, tolerance~).ranking
Product => weighted_product(m, weights, tolerance~).ranking
Compromise(v) => vikor(m, weights, v~, tolerance~).ranking
Outranking(preferences) =>
promethee(m, weights, preferences, tolerance~).ranking
}
}
///|
pub(all) struct MethodComparison {
rankings : Array[Ranking]
agreements : Array[Array[RankAgreement]]
} derive(@debug.Debug)
///|
pub fn compare_methods(
m : DecisionMatrix,
weights : Array[Double],
methods : Array[Method],
tolerance~ : Double = 1.0e-10,
) -> MethodComparison raise ChoiceError {
if methods.length() == 0 || methods.length() > 16 {
raise Budget("algorithm count must be 1..16")
}
let rankings = methods.map(algorithm => {
evaluate(m, weights, algorithm, tolerance~)
})
let agreements = rankings.map(a => rankings.map(b => rank_agreement(a, b)))
{ rankings, agreements, }
}
///|
pub extend Method with @debug.Debug::{to_repr}
///|
pub extend MethodComparison with @debug.Debug::{to_repr}