mirror of
https://git.proxmox.com/git/proxmox-resource-scheduling
synced 2025-10-04 19:03:15 +00:00
drop Topsis prefix of all the types in topsis::
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
4ac19a0016
commit
5a50196a13
@ -1,7 +1,7 @@
|
||||
use anyhow::Error;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::topsis::TopsisMatrix;
|
||||
use crate::topsis;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
@ -115,7 +115,7 @@ pub fn score_nodes_to_start_service(
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let scores =
|
||||
crate::topsis::score_alternatives(&TopsisMatrix::new(matrix)?, &PVE_HA_TOPSIS_CRITERIA)?;
|
||||
topsis::score_alternatives(&topsis::Matrix::new(matrix)?, &PVE_HA_TOPSIS_CRITERIA)?;
|
||||
|
||||
Ok(scores
|
||||
.into_iter()
|
||||
|
@ -17,7 +17,7 @@ fn l2_norm(values: &[f64]) -> f64 {
|
||||
}
|
||||
|
||||
/// A criterion that can be used when scoring with the TOPSIS algorithm.
|
||||
pub struct TopsisCriterion {
|
||||
pub struct Criterion {
|
||||
/// Name of the criterion.
|
||||
name: String,
|
||||
/// The relative weight of the criterion. Is non-negative.
|
||||
@ -26,8 +26,8 @@ pub struct TopsisCriterion {
|
||||
maximize: bool,
|
||||
}
|
||||
|
||||
impl TopsisCriterion {
|
||||
/// Construct a new `TopsisCriterion`. Use a negative weight if the value for the criterion
|
||||
impl Criterion {
|
||||
/// Construct a new `Criterion`. Use a negative weight if the value for the criterion
|
||||
/// should be minimized rather than maximized.
|
||||
///
|
||||
/// Assumes that `weight` is finite.
|
||||
@ -38,7 +38,7 @@ impl TopsisCriterion {
|
||||
(false, -weight)
|
||||
};
|
||||
|
||||
TopsisCriterion {
|
||||
Criterion {
|
||||
name,
|
||||
weight,
|
||||
maximize,
|
||||
@ -46,14 +46,14 @@ impl TopsisCriterion {
|
||||
}
|
||||
}
|
||||
|
||||
/// A normalized array of `TopsisCriterion`.
|
||||
pub struct TopsisCriteria<const N_CRITERIA: usize>([TopsisCriterion; N_CRITERIA]);
|
||||
/// A normalized array of `Criterion`.
|
||||
pub struct Criteria<const N_CRITERIA: usize>([Criterion; N_CRITERIA]);
|
||||
|
||||
impl<const N: usize> TopsisCriteria<N> {
|
||||
impl<const N: usize> Criteria<N> {
|
||||
/// Create a new instance of normalized TOPSIS criteria.
|
||||
///
|
||||
/// Assumes that the sum of weights can be calculated to a finite, non-zero value.
|
||||
pub fn new(mut criteria: [TopsisCriterion; N]) -> Result<Self, Error> {
|
||||
pub fn new(mut criteria: [Criterion; N]) -> Result<Self, Error> {
|
||||
let divisor = criteria
|
||||
.iter()
|
||||
.fold(0.0, |sum, criterion| sum + criterion.weight);
|
||||
@ -73,7 +73,7 @@ impl<const N: usize> TopsisCriteria<N> {
|
||||
}
|
||||
}
|
||||
|
||||
Ok(TopsisCriteria(criteria))
|
||||
Ok(Criteria(criteria))
|
||||
}
|
||||
|
||||
/// Weigh each value according to the weight of its corresponding criterion.
|
||||
@ -86,9 +86,9 @@ impl<const N: usize> TopsisCriteria<N> {
|
||||
}
|
||||
|
||||
/// A normalized matrix used for scoring with the TOPSIS algorithm.
|
||||
pub struct TopsisMatrix<const N_CRITERIA: usize>(Vec<[f64; N_CRITERIA]>);
|
||||
pub struct Matrix<const N_CRITERIA: usize>(Vec<[f64; N_CRITERIA]>);
|
||||
|
||||
impl<const N: usize> TopsisMatrix<N> {
|
||||
impl<const N: usize> Matrix<N> {
|
||||
/// Values of the matrix for the fixed critierion with index `index`.
|
||||
fn fixed_criterion(&self, index: usize) -> Vec<f64> {
|
||||
self.0
|
||||
@ -105,12 +105,12 @@ impl<const N: usize> TopsisMatrix<N> {
|
||||
.collect::<Vec<&mut _>>()
|
||||
}
|
||||
|
||||
/// Create a normalized `TopsisMatrix` based on the given values.
|
||||
/// Create a normalized `Matrix` based on the given values.
|
||||
///
|
||||
/// Assumes that the sum of squares for each fixed criterion in `matrix` can be calculated to a
|
||||
/// finite value.
|
||||
pub fn new(matrix: Vec<[f64; N]>) -> Result<Self, Error> {
|
||||
let mut matrix = TopsisMatrix(matrix);
|
||||
let mut matrix = Matrix(matrix);
|
||||
for n in 0..N {
|
||||
let divisor = l2_norm(&matrix.fixed_criterion(n));
|
||||
|
||||
@ -129,17 +129,17 @@ impl<const N: usize> TopsisMatrix<N> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Idealized alternatives from a `TopsisMatrix`. That is, the alternative consisting of the best
|
||||
/// Idealized alternatives from a `Matrix`. That is, the alternative consisting of the best
|
||||
/// (respectively worst) value among the alternatives in the matrix for each single criterion.
|
||||
struct TopsisIdealAlternatives<const N_CRITERIA: usize> {
|
||||
struct IdealAlternatives<const N_CRITERIA: usize> {
|
||||
best: [f64; N_CRITERIA],
|
||||
worst: [f64; N_CRITERIA],
|
||||
}
|
||||
|
||||
impl<const N: usize> TopsisIdealAlternatives<N> {
|
||||
impl<const N: usize> IdealAlternatives<N> {
|
||||
/// Compute the idealized alternatives from the given `matrix`. The `criteria` are required to know
|
||||
/// if a critierion should be maximized or minimized.
|
||||
fn compute(matrix: &TopsisMatrix<N>, criteria: &TopsisCriteria<N>) -> Self {
|
||||
fn compute(matrix: &Matrix<N>, criteria: &Criteria<N>) -> Self {
|
||||
let criteria = &criteria.0;
|
||||
|
||||
let mut best = [0.0; N];
|
||||
@ -170,10 +170,10 @@ impl<const N: usize> TopsisIdealAlternatives<N> {
|
||||
/// alternative. Scores range from 0.0 to 1.0 and a low score indicates closness to the ideal worst
|
||||
/// and/or distance to the ideal best alternatives.
|
||||
pub fn score_alternatives<const N: usize>(
|
||||
matrix: &TopsisMatrix<N>,
|
||||
criteria: &TopsisCriteria<N>,
|
||||
matrix: &Matrix<N>,
|
||||
criteria: &Criteria<N>,
|
||||
) -> Result<Vec<f64>, Error> {
|
||||
let ideal_alternatives = TopsisIdealAlternatives::compute(matrix, criteria);
|
||||
let ideal_alternatives = IdealAlternatives::compute(matrix, criteria);
|
||||
let ideal_best = &ideal_alternatives.best;
|
||||
let ideal_worst = &ideal_alternatives.worst;
|
||||
|
||||
@ -201,8 +201,8 @@ pub fn score_alternatives<const N: usize>(
|
||||
|
||||
/// Similar to `score_alternatives`, but returns the list of indices decreasing by score.
|
||||
pub fn rank_alternatives<const N: usize>(
|
||||
matrix: &TopsisMatrix<N>,
|
||||
criteria: &TopsisCriteria<N>,
|
||||
matrix: &Matrix<N>,
|
||||
criteria: &Criteria<N>,
|
||||
) -> Result<Vec<usize>, Error> {
|
||||
let scores = score_alternatives(matrix, criteria)?;
|
||||
|
||||
@ -243,10 +243,10 @@ macro_rules! criteria_struct {
|
||||
}
|
||||
|
||||
::lazy_static::lazy_static! {
|
||||
static ref $criteria_name: $crate::topsis::TopsisCriteria<$count_name> =
|
||||
$crate::topsis::TopsisCriteria::new([
|
||||
static ref $criteria_name: $crate::topsis::Criteria<$count_name> =
|
||||
$crate::topsis::Criteria::new([
|
||||
$(
|
||||
$crate::topsis::TopsisCriterion::new($crit_name.to_string(), $crit_weight),
|
||||
$crate::topsis::Criterion::new($crit_name.to_string(), $crit_weight),
|
||||
)*
|
||||
])
|
||||
.unwrap();
|
||||
|
154
tests/topsis.rs
154
tests/topsis.rs
@ -1,64 +1,60 @@
|
||||
use anyhow::Error;
|
||||
|
||||
use proxmox_resource_scheduling::topsis::{
|
||||
rank_alternatives, TopsisCriteria, TopsisCriterion, TopsisMatrix,
|
||||
};
|
||||
use proxmox_resource_scheduling::topsis::{rank_alternatives, Criteria, Criterion, Matrix};
|
||||
|
||||
#[test]
|
||||
fn test_topsis_single_criterion() -> Result<(), Error> {
|
||||
let criteria_pos =
|
||||
TopsisCriteria::new([TopsisCriterion::new("the one and only".to_string(), 1.0)])?;
|
||||
let criteria_pos = Criteria::new([Criterion::new("the one and only".to_string(), 1.0)])?;
|
||||
|
||||
let criteria_neg =
|
||||
TopsisCriteria::new([TopsisCriterion::new("the one and only".to_string(), -1.0)])?;
|
||||
let criteria_neg = Criteria::new([Criterion::new("the one and only".to_string(), -1.0)])?;
|
||||
|
||||
let matrix = vec![[0.0]];
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix.clone())?, &criteria_pos)?,
|
||||
rank_alternatives(&Matrix::new(matrix.clone())?, &criteria_pos)?,
|
||||
vec![0],
|
||||
);
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix)?, &criteria_neg)?,
|
||||
rank_alternatives(&Matrix::new(matrix)?, &criteria_neg)?,
|
||||
vec![0],
|
||||
);
|
||||
|
||||
let matrix = vec![[0.0], [2.0]];
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix.clone())?, &criteria_pos)?,
|
||||
rank_alternatives(&Matrix::new(matrix.clone())?, &criteria_pos)?,
|
||||
vec![1, 0],
|
||||
);
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix)?, &criteria_neg)?,
|
||||
rank_alternatives(&Matrix::new(matrix)?, &criteria_neg)?,
|
||||
vec![0, 1],
|
||||
);
|
||||
|
||||
let matrix = vec![[1.0], [2.0]];
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix.clone())?, &criteria_pos)?,
|
||||
rank_alternatives(&Matrix::new(matrix.clone())?, &criteria_pos)?,
|
||||
vec![1, 0],
|
||||
);
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix)?, &criteria_neg)?,
|
||||
rank_alternatives(&Matrix::new(matrix)?, &criteria_neg)?,
|
||||
vec![0, 1],
|
||||
);
|
||||
|
||||
let matrix = vec![[1.0], [2.0], [5.0], [3.0], [4.0]];
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix.clone())?, &criteria_pos)?,
|
||||
rank_alternatives(&Matrix::new(matrix.clone())?, &criteria_pos)?,
|
||||
vec![2, 4, 3, 1, 0],
|
||||
);
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix)?, &criteria_neg)?,
|
||||
rank_alternatives(&Matrix::new(matrix)?, &criteria_neg)?,
|
||||
vec![0, 1, 3, 4, 2],
|
||||
);
|
||||
|
||||
let matrix = vec![[-2.0], [-5.0], [-4.0], [1.0], [-3.0]];
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix.clone())?, &criteria_pos)?,
|
||||
rank_alternatives(&Matrix::new(matrix.clone())?, &criteria_pos)?,
|
||||
vec![3, 0, 4, 2, 1],
|
||||
);
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix)?, &criteria_neg)?,
|
||||
rank_alternatives(&Matrix::new(matrix)?, &criteria_neg)?,
|
||||
vec![1, 2, 4, 0, 3],
|
||||
);
|
||||
|
||||
@ -67,38 +63,38 @@ fn test_topsis_single_criterion() -> Result<(), Error> {
|
||||
|
||||
#[test]
|
||||
fn test_topsis_two_criteria() -> Result<(), Error> {
|
||||
let criteria_max_min = TopsisCriteria::new([
|
||||
TopsisCriterion::new("max".to_string(), 1.0),
|
||||
TopsisCriterion::new("min".to_string(), -1.0),
|
||||
let criteria_max_min = Criteria::new([
|
||||
Criterion::new("max".to_string(), 1.0),
|
||||
Criterion::new("min".to_string(), -1.0),
|
||||
])?;
|
||||
let criteria_min_max = TopsisCriteria::new([
|
||||
TopsisCriterion::new("min".to_string(), -1.0),
|
||||
TopsisCriterion::new("max".to_string(), 1.0),
|
||||
let criteria_min_max = Criteria::new([
|
||||
Criterion::new("min".to_string(), -1.0),
|
||||
Criterion::new("max".to_string(), 1.0),
|
||||
])?;
|
||||
let criteria_min_min = TopsisCriteria::new([
|
||||
TopsisCriterion::new("min1".to_string(), -1.0),
|
||||
TopsisCriterion::new("min2".to_string(), -1.0),
|
||||
let criteria_min_min = Criteria::new([
|
||||
Criterion::new("min1".to_string(), -1.0),
|
||||
Criterion::new("min2".to_string(), -1.0),
|
||||
])?;
|
||||
let criteria_max_max = TopsisCriteria::new([
|
||||
TopsisCriterion::new("max1".to_string(), 1.0),
|
||||
TopsisCriterion::new("max2".to_string(), 1.0),
|
||||
let criteria_max_max = Criteria::new([
|
||||
Criterion::new("max1".to_string(), 1.0),
|
||||
Criterion::new("max2".to_string(), 1.0),
|
||||
])?;
|
||||
|
||||
let matrix = vec![[0.0, 0.0]];
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix.clone())?, &criteria_max_min)?,
|
||||
rank_alternatives(&Matrix::new(matrix.clone())?, &criteria_max_min)?,
|
||||
vec![0],
|
||||
);
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix.clone())?, &criteria_min_max)?,
|
||||
rank_alternatives(&Matrix::new(matrix.clone())?, &criteria_min_max)?,
|
||||
vec![0],
|
||||
);
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix.clone())?, &criteria_min_min)?,
|
||||
rank_alternatives(&Matrix::new(matrix.clone())?, &criteria_min_min)?,
|
||||
vec![0],
|
||||
);
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix)?, &criteria_max_max)?,
|
||||
rank_alternatives(&Matrix::new(matrix)?, &criteria_max_max)?,
|
||||
vec![0],
|
||||
);
|
||||
|
||||
@ -111,19 +107,19 @@ fn test_topsis_two_criteria() -> Result<(), Error> {
|
||||
[0.0, 0.0],
|
||||
];
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix.clone())?, &criteria_max_min)?,
|
||||
rank_alternatives(&Matrix::new(matrix.clone())?, &criteria_max_min)?,
|
||||
vec![2, 1, 4, 3, 0],
|
||||
);
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix.clone())?, &criteria_min_max)?,
|
||||
rank_alternatives(&Matrix::new(matrix.clone())?, &criteria_min_max)?,
|
||||
vec![0, 3, 4, 1, 2],
|
||||
);
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix.clone())?, &criteria_min_min)?,
|
||||
rank_alternatives(&Matrix::new(matrix.clone())?, &criteria_min_min)?,
|
||||
vec![2, 4, 1, 0, 3],
|
||||
);
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix)?, &criteria_max_max)?,
|
||||
rank_alternatives(&Matrix::new(matrix)?, &criteria_max_max)?,
|
||||
vec![3, 0, 1, 4, 2],
|
||||
);
|
||||
|
||||
@ -137,19 +133,19 @@ fn test_topsis_two_criteria() -> Result<(), Error> {
|
||||
[4.0, 7.0],
|
||||
];
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix.clone())?, &criteria_max_min)?,
|
||||
rank_alternatives(&Matrix::new(matrix.clone())?, &criteria_max_min)?,
|
||||
vec![0, 1, 4, 2, 3],
|
||||
);
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix.clone())?, &criteria_min_max)?,
|
||||
rank_alternatives(&Matrix::new(matrix.clone())?, &criteria_min_max)?,
|
||||
vec![3, 2, 4, 1, 0],
|
||||
);
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix.clone())?, &criteria_min_min)?,
|
||||
rank_alternatives(&Matrix::new(matrix.clone())?, &criteria_min_min)?,
|
||||
vec![2, 3, 1, 0, 4],
|
||||
);
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix)?, &criteria_max_max)?,
|
||||
rank_alternatives(&Matrix::new(matrix)?, &criteria_max_max)?,
|
||||
vec![4, 0, 1, 3, 2],
|
||||
);
|
||||
|
||||
@ -158,25 +154,25 @@ fn test_topsis_two_criteria() -> Result<(), Error> {
|
||||
|
||||
#[test]
|
||||
fn test_topsis_three_criteria() -> Result<(), Error> {
|
||||
let criteria_first = TopsisCriteria::new([
|
||||
TopsisCriterion::new("more".to_string(), 10.0),
|
||||
TopsisCriterion::new("less".to_string(), 0.2),
|
||||
TopsisCriterion::new("least".to_string(), 0.1),
|
||||
let criteria_first = Criteria::new([
|
||||
Criterion::new("more".to_string(), 10.0),
|
||||
Criterion::new("less".to_string(), 0.2),
|
||||
Criterion::new("least".to_string(), 0.1),
|
||||
])?;
|
||||
let criteria_second = TopsisCriteria::new([
|
||||
TopsisCriterion::new("less".to_string(), 0.2),
|
||||
TopsisCriterion::new("more".to_string(), 10.0),
|
||||
TopsisCriterion::new("least".to_string(), 0.1),
|
||||
let criteria_second = Criteria::new([
|
||||
Criterion::new("less".to_string(), 0.2),
|
||||
Criterion::new("more".to_string(), 10.0),
|
||||
Criterion::new("least".to_string(), 0.1),
|
||||
])?;
|
||||
let criteria_third = TopsisCriteria::new([
|
||||
TopsisCriterion::new("less".to_string(), 0.2),
|
||||
TopsisCriterion::new("least".to_string(), 0.1),
|
||||
TopsisCriterion::new("more".to_string(), 10.0),
|
||||
let criteria_third = Criteria::new([
|
||||
Criterion::new("less".to_string(), 0.2),
|
||||
Criterion::new("least".to_string(), 0.1),
|
||||
Criterion::new("more".to_string(), 10.0),
|
||||
])?;
|
||||
let criteria_min = TopsisCriteria::new([
|
||||
TopsisCriterion::new("most".to_string(), -10.0),
|
||||
TopsisCriterion::new("more".to_string(), -5.0),
|
||||
TopsisCriterion::new("less".to_string(), 0.1),
|
||||
let criteria_min = Criteria::new([
|
||||
Criterion::new("most".to_string(), -10.0),
|
||||
Criterion::new("more".to_string(), -5.0),
|
||||
Criterion::new("less".to_string(), 0.1),
|
||||
])?;
|
||||
|
||||
#[rustfmt::skip]
|
||||
@ -186,19 +182,19 @@ fn test_topsis_three_criteria() -> Result<(), Error> {
|
||||
[0.0, 0.0, 1.0],
|
||||
];
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix.clone())?, &criteria_first)?,
|
||||
rank_alternatives(&Matrix::new(matrix.clone())?, &criteria_first)?,
|
||||
vec![0, 1, 2],
|
||||
);
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix.clone())?, &criteria_second)?,
|
||||
rank_alternatives(&Matrix::new(matrix.clone())?, &criteria_second)?,
|
||||
vec![1, 0, 2],
|
||||
);
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix.clone())?, &criteria_third)?,
|
||||
rank_alternatives(&Matrix::new(matrix.clone())?, &criteria_third)?,
|
||||
vec![2, 0, 1],
|
||||
);
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix)?, &criteria_min)?,
|
||||
rank_alternatives(&Matrix::new(matrix)?, &criteria_min)?,
|
||||
vec![2, 1, 0],
|
||||
);
|
||||
|
||||
@ -210,19 +206,19 @@ fn test_topsis_three_criteria() -> Result<(), Error> {
|
||||
];
|
||||
// normalization ensures that it's still the same as above
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix.clone())?, &criteria_first)?,
|
||||
rank_alternatives(&Matrix::new(matrix.clone())?, &criteria_first)?,
|
||||
vec![0, 1, 2],
|
||||
);
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix.clone())?, &criteria_second)?,
|
||||
rank_alternatives(&Matrix::new(matrix.clone())?, &criteria_second)?,
|
||||
vec![1, 0, 2],
|
||||
);
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix.clone())?, &criteria_third)?,
|
||||
rank_alternatives(&Matrix::new(matrix.clone())?, &criteria_third)?,
|
||||
vec![2, 0, 1],
|
||||
);
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix)?, &criteria_min)?,
|
||||
rank_alternatives(&Matrix::new(matrix)?, &criteria_min)?,
|
||||
vec![2, 1, 0],
|
||||
);
|
||||
|
||||
@ -233,19 +229,19 @@ fn test_topsis_three_criteria() -> Result<(), Error> {
|
||||
[0.0, 0.0, 1.0],
|
||||
];
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix.clone())?, &criteria_first)?,
|
||||
rank_alternatives(&Matrix::new(matrix.clone())?, &criteria_first)?,
|
||||
vec![2, 1, 0],
|
||||
);
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix.clone())?, &criteria_second)?,
|
||||
rank_alternatives(&Matrix::new(matrix.clone())?, &criteria_second)?,
|
||||
vec![2, 0, 1],
|
||||
);
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix.clone())?, &criteria_third)?,
|
||||
rank_alternatives(&Matrix::new(matrix.clone())?, &criteria_third)?,
|
||||
vec![2, 1, 0],
|
||||
);
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix)?, &criteria_min)?,
|
||||
rank_alternatives(&Matrix::new(matrix)?, &criteria_min)?,
|
||||
vec![0, 1, 2],
|
||||
);
|
||||
|
||||
@ -260,22 +256,22 @@ fn test_nan() {
|
||||
[0.0, -1.0, 0.0],
|
||||
[0.0, f64::NAN, 1.0],
|
||||
];
|
||||
assert!(TopsisMatrix::new(matrix).is_err());
|
||||
assert!(Matrix::new(matrix).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zero() -> Result<(), Error> {
|
||||
let criteria_zero = TopsisCriteria::new([
|
||||
TopsisCriterion::new("z".to_string(), 0.0),
|
||||
TopsisCriterion::new("e".to_string(), 0.0),
|
||||
TopsisCriterion::new("ro".to_string(), 0.0),
|
||||
let criteria_zero = Criteria::new([
|
||||
Criterion::new("z".to_string(), 0.0),
|
||||
Criterion::new("e".to_string(), 0.0),
|
||||
Criterion::new("ro".to_string(), 0.0),
|
||||
]);
|
||||
assert!(criteria_zero.is_err());
|
||||
|
||||
let criteria_first = TopsisCriteria::new([
|
||||
TopsisCriterion::new("more".to_string(), 10.0),
|
||||
TopsisCriterion::new("less".to_string(), 0.2),
|
||||
TopsisCriterion::new("least".to_string(), 0.1),
|
||||
let criteria_first = Criteria::new([
|
||||
Criterion::new("more".to_string(), 10.0),
|
||||
Criterion::new("less".to_string(), 0.2),
|
||||
Criterion::new("least".to_string(), 0.1),
|
||||
])?;
|
||||
|
||||
#[rustfmt::skip]
|
||||
@ -285,7 +281,7 @@ fn test_zero() -> Result<(), Error> {
|
||||
[0.0, 0.0, 1.0],
|
||||
];
|
||||
assert_eq!(
|
||||
rank_alternatives(&TopsisMatrix::new(matrix)?, &criteria_first)?,
|
||||
rank_alternatives(&Matrix::new(matrix)?, &criteria_first)?,
|
||||
vec![1, 2, 0],
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user