Analytic Hierarchy Process(AHP) Library
npm install ahpbash
$ npm i ahp
`
------------------------
Quick Samples
$3
`javascript
import AHP from 'ahp';
const ahpContext = new AHP();
ahpContext.addItems(['VendorA', 'VendorB', 'VendorC']);
ahpContext.addCriteria(['price', 'functionality', 'UX']);
//rank criteria with rank scale
ahpContext.rankCriteriaItem('price', [
['VendorB', 'VendorC', 1 / 2],
['VendorA', 'VendorC', 1 / 2],
['VendorA', 'VendorB', 1]
]);
//rank criteria with rank scale
ahpContext.rankCriteriaItem('functionality', [
['VendorB', 'VendorC', 1],
['VendorA', 'VendorC', 5],
['VendorA', 'VendorB', 5]
]);
//rank criteria with absolute rank scole
ahpContext.setCriteriaItemRankByGivenScores('UX', [10, 10, 1]);
ahpContext.rankCriteria(
[
['price', 'functionality', 3],
['price', 'UX', 3],
['functionality', 'UX', 1]
]
);
const output = ahpContext.run();
console.log(output);
`
Console output
`
{ error: null,
rankingMatrix:
[ [ 0.25, 0.7142857142857141, 0.4761904761904761 ],
[ 0.25, 0.14285714285714285, 0.4761904761904761 ],
[ 0.5, 0.14285714285714285, 0.047619047619047616 ] ],
itemRankMetaMap:
{ price: { ci: 0, ri: 0.58, cr: 0 },
functionality: { ci: 0, ri: 0.58, cr: 0 },
UX: { ci: 0, ri: 0.58, cr: 0 } },
criteriaRankMetaMap:
{ ci: 0,
ri: 0.58,
cr: 0,
weightedVector: [ 0.6000000000000001, 0.20000000000000004, 0.20000000000000004 ] },
rankedScoreMap:
{ VendorA: 0.3880952380952381,
VendorB: 0.27380952380952384,
VendorC: 0.33809523809523817 },
rankedScores: [ 0.3880952380952381, 0.27380952380952384, 0.33809523809523817 ] }
`
$3
`javascript
import AHP from 'ahp';
const ahpContext = new AHP();
/*
notice that in this demo, we import price item ranking with matrix,
and import UX item ranking with absolute scores. Both are supported.
*/
ahpContext.import({
items: ['VendorA', 'VendorB', 'VendorC'],
criteria: ['price', 'functionality', 'UX'],
criteriaItemRank: {
price: [
[1, 1, 0.5],
[1, 1, 0.5],
[2, 2, 1]
],
functionality: [
[1, 5, 5],
[0.2, 1, 1],
[0.2, 1, 1]
],
UX: [10, 10, 1]
},
criteriaRank: [
[1, 3, 3],
[0.3333333333333333, 1, 1],
[0.3333333333333333, 1, 1]
]
});
const output = ahpContext.run();
console.log(output);
`
Console output
`
{ error: null,
rankingMatrix:
[ [ 0.25, 0.7142857142857141, 0.4761904761904761 ],
[ 0.25, 0.14285714285714285, 0.4761904761904761 ],
[ 0.5, 0.14285714285714285, 0.047619047619047616 ] ],
itemRankMetaMap:
{ price: { ci: 0, ri: 0.58, cr: 0 },
functionality: { ci: 0, ri: 0.58, cr: 0 },
UX: { ci: 0, ri: 0.58, cr: 0 } },
criteriaRankMetaMap:
{ ci: 0,
ri: 0.58,
cr: 0,
weightedVector: [ 0.6000000000000001, 0.20000000000000004, 0.20000000000000004 ] },
rankedScoreMap:
{ VendorA: 0.3880952380952381,
VendorB: 0.27380952380952384,
VendorC: 0.33809523809523817 },
rankedScores: [ 0.3880952380952381, 0.27380952380952384, 0.33809523809523817 ] }
`
$3
`javascript
import AHP from 'ahp';
const ahpContext = new AHP();
......
const util = require('util');
console.log(util.inspect(ahpContext.export(), false, null));
`
Console output
`
{ items: [ 'VendorA', 'VendorB', 'VendorC' ],
criteria: [ 'price', 'functionality', 'UX' ],
criteriaItemRank:
{ price: [ [ 1, 1, 0.5 ], [ 1, 1, 0.5 ], [ 2, 2, 1 ] ],
functionality: [ [ 1, 5, 5 ], [ 0.2, 1, 1 ], [ 0.2, 1, 1 ] ],
UX: [ [ 1, 1, 10 ], [ 1, 1, 10 ], [ 0.1, 0.1, 1 ] ] },
criteriaRank:
[ [ 1, 3, 3 ],
[ 0.3333333333333333, 1, 1 ],
[ 0.3333333333333333, 1, 1 ] ] }
`
$3
`javascript
import AHP from 'ahp';
const ahpContext = new AHP();
......
const analyticContext = ahpContext.debug();
for(const key in analyticContext){
console.log(${key}: , analyticContext[key], '\n');
}
`
Console output
`
error: null
rankingMatrix: [ [ 0.25, 0.7142857142857141, 0.4761904761904761 ],
[ 0.25, 0.14285714285714285, 0.4761904761904761 ],
[ 0.5, 0.14285714285714285, 0.047619047619047616 ] ]
itemRankMetaMap: { price: { ci: 0, ri: 0.58, cr: 0 },
functionality: { ci: 0, ri: 0.58, cr: 0 },
UX: { ci: 0, ri: 0.58, cr: 0 } }
criteriaRankMetaMap: { ci: 0,
ri: 0.58,
cr: 0,
weightedVector: [ 0.6000000000000001, 0.20000000000000004, 0.20000000000000004 ] }
rankedScoreMap: { VendorA: 0.3880952380952381,
VendorB: 0.27380952380952384,
VendorC: 0.33809523809523817 }
rankedScores: [ 0.3880952380952381, 0.27380952380952384, 0.33809523809523817 ]
log: ==========================================
context:
items:
[ 'VendorA', 'VendorB', 'VendorC' ]
criteria:
[ 'price', 'functionality', 'UX' ]
criteriaItemRank:
{ price: [ [ 1, 1, 0.5 ], [ 1, 1, 0.5 ], [ 2, 2, 1 ] ],
functionality: [ [ 1, 5, 5 ], [ 0.2, 1, 1 ], [ 0.2, 1, 1 ] ],
UX: [ [ 1, 1, 10 ], [ 1, 1, 10 ], [ 0.1, 0.1, 1 ] ] }
criteriaRank:
[ [ 1, 3, 3 ],
[ 0.3333333333333333, 1, 1 ],
[ 0.3333333333333333, 1, 1 ] ]
__________________________________
criteriaItemRank['price']
---------------------------------------------
| | VendorA| VendorB| VendorC|
|----------|----------|----------|----------|
| VendorA| 1.000| 1.000| 0.500|
| VendorB| 1.000| 1.000| 0.500|
| VendorC| 2.000| 2.000| 1.000|
---------------------------------------------
Consistentcy index: 0
Random index: 0.58
Consistentcy ratio: 0
CR<=0.1 => sufficient consistency
__________________________________
criteriaItemRank['functionality']
---------------------------------------------
| | VendorA| VendorB| VendorC|
|----------|----------|----------|----------|
| VendorA| 1.000| 5.000| 5.000|
| VendorB| 0.200| 1.000| 1.000|
| VendorC| 0.200| 1.000| 1.000|
---------------------------------------------
Consistentcy index: 0
Random index: 0.58
Consistentcy ratio: 0
CR<=0.1 => sufficient consistency
__________________________________
criteriaItemRank['UX']
---------------------------------------------
| | VendorA| VendorB| VendorC|
|----------|----------|----------|----------|
| VendorA| 1.000| 1.000| 10.000|
| VendorB| 1.000| 1.000| 10.000|
| VendorC| 0.100| 0.100| 1.000|
---------------------------------------------
Consistentcy index: 0
Random index: 0.58
Consistentcy ratio: 0
CR<=0.1 => sufficient consistency
__________________________________
criteriaRank:
---------------------------------------------------------
| | price|functionality| UX|
|-------------|-------------|-------------|-------------|
| price| 1.000| 3.000| 3.000|
|functionality| 0.333| 1.000| 1.000|
| UX| 0.333| 1.000| 1.000|
---------------------------------------------------------
Consistentcy index: 0
Random index: 0.58
Consistentcy ratio: 0
CR<=0.1 => sufficient consistency
Criteria Weight Vector: 0.6000000000000001,0.20000000000000004,0.20000000000000004
__________________________________
rankingMatrix: (Higher score is better)
---------------------------------------
| |VendorA|VendorB|VendorC|
|-------------|-------|-------|-------|
| price| 0.250| 0.250| 0.500|
|functionality| 0.714| 0.143| 0.143|
| UX| 0.476| 0.476| 0.048|
---------------------------------------
__________________________________
ranked item scores: (Higher score is better)
---------------
| |Score|
|-------|-----|
|VendorA|0.388|
|VendorB|0.274|
|VendorC|0.338|
---------------
==========================================
`
------------------------
API
- ahp.js
- Project page
- Glossary
- Install
- Quick Samples
- Hello World Sample
- Import Data Context Sample
- Export Data Context Sample
- Output Analysis Process Information Sample
- API
- import(context)
- export()
- addItem(item)
- addItems(items)
- removeItem(item)
- removeItems(items)
- addCriterion(criterion)
- addCriteria(criteria)
- removeCriterion(criterion)
- removeCriteria(criteria)
- rankCriteria(preferences)
- setCriteriaRankByGivenScores(vector)
- rankCriteriaItem(criterion, preferences)
- setCriteriaItemRankByGivenScores(criterion, vector)
- resetCriteriaItemRank(criteria)
- resetCriteriaRank()
- findNextProblem()
- debug()
- run()
- Classes
- AHP
- ContextError
- NoItem
- NoCriteria
- MissingCriteriaItemRank
- MissingCriteriaRank
- CriteriaItemRankInsufficientConsistencyRatio
- CriteriaRankInsufficientConsistencyRatio
- Arthor contact
$3
Description:
Importing context from JSON
Parameters:
| Parameter | Type | Description | Mandatory | Default Value |
| --------- | ---- | ----------- | --------- | ------------- |
| context | object | The context | true | - |
Return:
| Type | Description |
| ---- | ----------- |
| AHP | The AHP object |
Example:
`javascript
ahpContext.import({
items: ['Vendor A', 'Vendor B', 'Vendor C'],
criteria: ['price', 'functionality', 'UX'],
criteriaItemRank:
{
price: [[1, 1, 0.5], [1, 1, 0.5], [2, 2, 1]],
functionality: [[1, 1, 5], [1, 1, 5], [0.2, 0.2, 1]],
UX: [[1, 1, 10], [1, 1, 10], [0.1, 0.1, 1]]
},
criteriaRank:
[[1, 3, 3],
[0.3333333333333333, 1, 1],
[0.3333333333333333, 1, 1]]
});
`
$3
Description:
Exporting context as JSON
Parameters:
nil
Return:
| Type | Description |
| ---- | ----------- |
| object | The exported AHP context JSON |
Example:
`javascript
ahpContext.export();
`
$3
Description:
Adding Item
Parameters:
| Parameter | Type | Description | Mandatory | Default Value |
| --------- | ---- | ----------- | --------- | ------------- |
| Item | string | The item | true | - |
Return:
| Type | Description |
| ---- | ----------- |
| AHP | The AHP object |
Example:
`javascript
ahpContext.addItem('Vendor A');
`
$3
Description:
Adding Items
Parameters:
| Parameter | Type | Description | Mandatory | Default Value |
| --------- | ---- | ----------- | --------- | ------------- |
| Items | string[] | The items | true | - |
Return:
| Type | Description |
| ---- | ----------- |
| AHP | The AHP object |
Example:
`javascript
ahpContext.addItems(['Vendor A', 'Vendor B', 'Vendor C']);
`
$3
Description:
Removing Item
Parameters:
| Parameter | Type | Description | Mandatory | Default Value |
| --------- | ---- | ----------- | --------- | ------------- |
| Item | string | The item | true | - |
Return:
| Type | Description |
| ---- | ----------- |
| AHP | The AHP object |
Example:
`javascript
ahpContext.removeItem('Vendor A');
`
$3
Description:
Removing Items
Parameters:
| Parameter | Type | Description | Mandatory | Default Value |
| --------- | ---- | ----------- | --------- | ------------- |
| Items | string[] | The items | true | - |
Return:
| Type | Description |
| ---- | ----------- |
| AHP | The AHP object |
Example:
`javascript
ahpContext.removeItems(['Vendor A', 'Vendor B', 'Vendor C']);
`
$3
Description:
Adding criterion
Parameters:
| Parameter | Type | Description | Mandatory | Default Value |
| --------- | ---- | ----------- | --------- | ------------- |
| criterion | string | The criterion | true | - |
Return:
| Type | Description |
| ---- | ----------- |
| AHP | The AHP object |
Example:
`javascript
ahpContext.addCriterion('price');
`
$3
Description:
Adding criteria
Parameters:
| Parameter | Type | Description | Mandatory | Default Value |
| --------- | ---- | ----------- | --------- | ------------- |
| criteria | string[] | The criteria | true | - |
Return:
| Type | Description |
| ---- | ----------- |
| AHP | The AHP object |
Example:
`javascript
ahpContext.addCriteria(['price', 'functionality', 'UX']);
`
$3
Description:
Removing criterion
Parameters:
| Parameter | Type | Description | Mandatory | Default Value |
| --------- | ---- | ----------- | --------- | ------------- |
| criterion | string | The criterion | true | - |
Return:
| Type | Description |
| ---- | ----------- |
| AHP | The AHP object |
Example:
`javascript
ahpContext.removeCriterion('price');
`
$3
Description:
Removing criteria
Parameters:
| Parameter | Type | Description | Mandatory | Default Value |
| --------- | ---- | ----------- | --------- | ------------- |
| criteria | string[] | The criteria | true | - |
Return:
| Type | Description |
| ---- | ----------- |
| AHP | The AHP object |
Example:
`javascript
ahpContext.removeCriteria(['price', 'functionality', 'UX']);
`
$3
Description:
Ranking criteria
Parameters:
| Parameter | Type | Description | Mandatory | Default Value |
| --------- | ---- | ----------- | --------- | ------------- |
| criteria | {{preferredCriterion:string, comparingCriterion:string, scale:number}[]\|(string\|number)[]} | Array of Preference. The 'preferredCriterion' of preference object is the preferred criterion while 'comparingCriterion' is the comparing criterion. The 'scale' is the preferred rank scale. You can pass the 3 objects as an array of 3 objects as well. | true | - |
Return:
| Type | Description |
| ---- | ----------- |
| AHP | The AHP object |
Example:
`javascript
ahpContext.rankCriteria(
[
{preferredCriterion: 'price', comparingCriterion: 'functionality', scale:3},
{preferredCriterion: 'price', comparingCriterion: 'UX', scale:3},
{preferredCriterion: 'functionality', comparingCriterion: 'UX', scale:1}
]
);
//or
ahpContext.rankCriteria(
[
['price', 'functionality', 3],
['price', 'UX', 3],
['functionality', 'UX', 1]
]
);
`
$3
Description:
Ranking criteria by Given Scores. This is suitable for the use case which you want to directly define the criteria ranking scores.
Parameters:
| Parameter | Type | Description | Mandatory | Default Value |
| --------- | ---- | ----------- | --------- | ------------- |
| vector | number[] | The array of criteria ranking scores. The sequence follow the sequence which you define criteria. | true | - |
Return:
| Type | Description |
| ---- | ----------- |
| AHP | The AHP object |
Example:
`javascript
//assume criteria = ['price', 'functionality', 'UX'];
ahpContext.setCriteriaRankByGivenScores([1, 2, 5]);
// is equivalent to
ahpContext.rankCriteria(
[
['price', 'functionality', 1/2],
['price', 'UX', 1/5],
['functionality', 'UX', 2/5]
]
);
`
$3
Description:
Rank Criteria perspective Item
Parameters:
| Parameter | Type | Description | Mandatory | Default Value |
| --------- | ---- | ----------- | --------- | ------------- |
| criterion | string | The criterion being used as perspective to rank the items | true | - |
| preferences | {{preferredItem:string, comparingItem:string, scale:number}[]\|(string\|number)[]} | Array of Preference. The 'preferredItem' of preference object is the preferred item while 'comparingItem' is the comparing item. The 'scale' is the preferred rank scale. You can pass the 3 objects as an array of 3 objects as well. | true | - |
Return:
| Type | Description |
| ---- | ----------- |
| AHP | The AHP object |
Example:
`javascript
ahpContext.rankCriteriaItem('price', [
{preferredItem:'VendorB', comparingItem:'VendorC', scale:1 / 2},
{preferredItem:'VendorA', comparingItem:'VendorC', scale:1 / 2},
{preferredItem:'VendorA', comparingItem:'VendorB', scale:1}
]);
//or
ahpContext.rankCriteriaItem('price', [
['VendorB', 'VendorC', 1 / 2],
['VendorA', 'VendorC', 1 / 2],
['VendorA', 'VendorB', 1]
]);
`
$3
Description:
Base on specific criterion to rank items by Given Scores. This is suitable for the use case which you want to directly define the criteria perspective item ranking scores.
Parameters:
| Parameter | Type | Description | Mandatory | Default Value |
| --------- | ---- | ----------- | --------- | ------------- |
| criterion | string | The criterion being used as perspective to rank the items | true | - |
| vector | number[] | The array of item ranking scores. The sequence follow the sequence which you define items. | true | - |
Return:
| Type | Description |
| ---- | ----------- |
| AHP | The AHP object |
Example:
`javascript
ahpContext.setCriteriaItemRankByGivenScores('price', [10, 5, 7]);
// is equivalent to
ahpContext.rankCriteriaItem(
'price',
[
['Vendor A', 'Vendor B', 10/5],
['Vendor A', 'Vendor C', 10/7],
['Vendor B', 'Vendor C', 5/7]
]
);
`
$3
Description:
Reset Criteria perspective Item ranking matrix.
Parameters:
| Parameter | Type | Description | Mandatory | Default Value |
| --------- | ---- | ----------- | --------- | ------------- |
| criteria | string[] | The criteria which you want to reset item ranking matrix. | true | - |
Return:
| Type | Description |
| ---- | ----------- |
| AHP | The AHP object |
Example:
`javascript
ahpContext.resetCriteriaItemRank(['price', 'functionality']);
`
$3
Description:
Reset Criteria ranking matrix.
Parameters:
nil
Return:
| Type | Description |
| ---- | ----------- |
| AHP | The AHP object |
Example:
`javascript
ahpContext.resetCriteriaRank();
`
$3
Description:
Auto check whether the existing input context can successfully done the AHP analysis process.
If there are missing information or data inconsistency, this function would return the Error it found.
Parameters:
nil
Return:
| Type | Description |
| ---- | ----------- |
| ContextError | The Context Error object |
Example:
`javascript
let problem = ahpContext.findNextProblem();
`
$3
Description:
Try to run the AHP analysis process.
The result information and the debug log output will be returned.
Parameters:
nil
Return Object properties:
| Property | Type | Description |
| -------- | ---- | ----------- |
| error | ContextError | The Context Error object if found, or null otherwise. |
| rankingMatrix | number[][] | The processed ranking matrix. The row entry represent each item's scores. Each entry in the row represent that item's score on a certain criteria. |
| itemRankMetaMap | object | The metadata(e.g: CI, RI, CR) for each criteria perspective item ranking matrix. |
| criteriaRankMetaMap | object | The metadata(e.g: CI, RI, CR) for criteria ranking matrix. |
| rankedScoreMap | object | The overall computed ranking score for each item |
| log | string | The debug log |
Example:
`javascript
......
let analyticContext = ahpContext.debug();
for(let key in analyticContext){
console.log(${key}: , analyticContext[key], '\n');
}
`
Console output
`
error:
null
rankingMatrix:
[ [ 0.25, 0.7142857142857141, 0.4761904761904761 ],
[ 0.25, 0.14285714285714285, 0.4761904761904761 ],
[ 0.5, 0.14285714285714285, 0.047619047619047616 ] ]
itemRankMetaMap:
{ price: { ci: 0, ri: 0.58, cr: 0 },
functionality: { ci: 0, ri: 0.58, cr: 0 },
UX: { ci: 0, ri: 0.58, cr: 0 } }
criteriaRankMetaMap:
{ ci: 0,
ri: 0.58,
cr: 0,
weightedVector: [ 0.6000000000000001, 0.20000000000000004, 0.20000000000000004 ] }
rankedScoreMap:
{ VendorA: 0.3880952380952381,
VendorB: 0.27380952380952384,
VendorC: 0.33809523809523817 }
log:
==========================================
context:
items:
[ 'VendorA', 'VendorB', 'VendorC' ]
criteria:
[ 'price', 'functionality', 'UX' ]
criteriaItemRank:
{ price: [ [ 1, 1, 0.5 ], [ 1, 1, 0.5 ], [ 2, 2, 1 ] ],
functionality: [ [ 1, 5, 5 ], [ 0.2, 1, 1 ], [ 0.2, 1, 1 ] ],
UX: [ [ 1, 1, 10 ], [ 1, 1, 10 ], [ 0.1, 0.1, 1 ] ] }
criteriaRank:
[ [ 1, 3, 3 ],
[ 0.3333333333333333, 1, 1 ],
[ 0.3333333333333333, 1, 1 ] ]
__________________________________
criteriaItemRank['price']
---------------------------------------------
| | VendorA| VendorB| VendorC|
|----------|----------|----------|----------|
| VendorA| 1.000| 1.000| 0.500|
| VendorB| 1.000| 1.000| 0.500|
| VendorC| 2.000| 2.000| 1.000|
---------------------------------------------
Consistentcy index: 0
Consistentcy ratio: 0
CR<=0.1 => sufficient consistency
__________________________________
criteriaItemRank['functionality']
---------------------------------------------
| | VendorA| VendorB| VendorC|
|----------|----------|----------|----------|
| VendorA| 1.000| 5.000| 5.000|
| VendorB| 0.200| 1.000| 1.000|
| VendorC| 0.200| 1.000| 1.000|
---------------------------------------------
Consistentcy index: 0
Consistentcy ratio: 0
CR<=0.1 => sufficient consistency
__________________________________
criteriaItemRank['UX']
---------------------------------------------
| | VendorA| VendorB| VendorC|
|----------|----------|----------|----------|
| VendorA| 1.000| 1.000| 10.000|
| VendorB| 1.000| 1.000| 10.000|
| VendorC| 0.100| 0.100| 1.000|
---------------------------------------------
Consistentcy index: 0
Consistentcy ratio: 0
CR<=0.1 => sufficient consistency
__________________________________
criteriaRank:
---------------------------------------------------------
| | price|functionality| UX|
|-------------|-------------|-------------|-------------|
| price| 1.000| 3.000| 3.000|
|functionality| 0.333| 1.000| 1.000|
| UX| 0.333| 1.000| 1.000|
---------------------------------------------------------
Consistentcy index: 0
Consistentcy ratio: 0
CR<=0.1 => sufficient consistency
Criteria Weight Vector: 0.6000000000000001,0.20000000000000004,0.20000000000000004
__________________________________
rankingMatrix: (Higher score is better)
---------------------------------------
| |VendorA|VendorB|VendorC|
|-------------|-------|-------|-------|
| price| 0.250| 0.250| 0.500|
|functionality| 0.714| 0.143| 0.143|
| UX| 0.476| 0.476| 0.048|
---------------------------------------
__________________________________
ranked item scores: (Higher score is better)
---------------
| |Score|
|-------|-----|
|VendorA|0.388|
|VendorB|0.274|
|VendorC|0.338|
---------------
==========================================
`
$3
Description:
Try to run the AHP analysis process.
The result information will be returned.
Parameters:
nil
Return Object properties:
| Property | Type | Description |
| -------- | ---- | ----------- |
| error | ContextError | The Context Error object if found, or null otherwise. |
| rankingMatrix | number[][] | The processed ranking matrix. The row entry represent each item's scores. Each entry in the row represent that item's score on a certain criteria. |
| itemRankMetaMap | object | The metadata(e.g: CI, RI, CR) for each criteria perspective item ranking matrix. |
| criteriaRankMetaMap | object | The metadata(e.g: CI, RI, CR) for criteria ranking matrix. |
| rankedScoreMap | object | The overall computed ranking score for each item |
Example:
`javascript
......
let analyticContext = ahpContext.run();
for(let key in analyticContext){
console.log(${key}: , analyticContext[key], '\n');
}
`
Console output
`
error:
null
rankingMatrix:
[ [ 0.25, 0.7142857142857141, 0.4761904761904761 ],
[ 0.25, 0.14285714285714285, 0.4761904761904761 ],
[ 0.5, 0.14285714285714285, 0.047619047619047616 ] ]
itemRankMetaMap:
{ price: { ci: 0, ri: 0.58, cr: 0 },
functionality: { ci: 0, ri: 0.58, cr: 0 },
UX: { ci: 0, ri: 0.58, cr: 0 } }
criteriaRankMetaMap:
{ ci: 0,
ri: 0.58,
cr: 0,
weightedVector: [ 0.6000000000000001, 0.20000000000000004, 0.20000000000000004 ] }
rankedScoreMap:
{ VendorA: 0.3880952380952381,
VendorB: 0.27380952380952384,
VendorC: 0.33809523809523817 }
``