-
Notifications
You must be signed in to change notification settings - Fork 0
/
anchoring-reference-points.go
75 lines (69 loc) · 2.26 KB
/
anchoring-reference-points.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package anchoring
import (
"fmt"
"github.com/Azbesciak/RealDecisionMaker/lib/model"
)
//go:generate easytags $GOFILE json:camel
type ReferencePointsEvaluator interface {
FunctionBase
Evaluate(
params FunctionParams,
alternatives *[]AnchoringAlternativeWithCriteria,
criteria *model.Criteria,
) []model.AlternativeWithCriteria
}
type ReferencePointDifference struct {
ReferencePoint model.Alternative `json:"referencePoint"`
Coefficients model.Weights `json:"coefficients"`
}
type ReferencePointsDifference struct {
Alternative model.AlternativeWithCriteria `json:"alternative"`
ReferencePointsDifference []ReferencePointDifference `json:"referencePointsDifference"`
}
func calculateDiffsPerReferencePoint(
alternatives []model.AlternativeWithCriteria,
referencePoints []model.AlternativeWithCriteria,
criteria *model.Criteria,
scaleRatios CriteriaScaling,
loss, gain AnchoringWithParams,
) []ReferencePointsDifference {
referencePointsDiffs := make([]ReferencePointsDifference, len(alternatives))
for ia, a := range alternatives {
refPointDiffs := make([]ReferencePointDifference, len(referencePoints))
for ir, r := range referencePoints {
refPointDiffs[ir] = calculateReferencePointDiffs(criteria, a, r, scaleRatios, loss, gain)
}
referencePointsDiffs[ia] = ReferencePointsDifference{
Alternative: a,
ReferencePointsDifference: refPointDiffs,
}
}
return referencePointsDiffs
}
func calculateReferencePointDiffs(
criteria *model.Criteria,
a, r model.AlternativeWithCriteria,
scaleRatios CriteriaScaling,
loss, gain AnchoringWithParams,
) ReferencePointDifference {
referencePointsDiffs := make(model.Weights, len(*criteria))
for _, c := range *criteria {
difference := a.CriterionValue(&c) - r.CriterionValue(&c)
if scaleRatio, ok := scaleRatios[c.Id]; ok {
scaledDif := difference * scaleRatio.Scale
var value float64
if scaledDif > 0 {
value = gain.fun.Evaluate(gain.params, scaledDif)
} else {
value = -loss.fun.Evaluate(loss.params, -scaledDif)
}
referencePointsDiffs[c.Id] = value
} else {
panic(fmt.Errorf("unknown criterion '%s' in alternative '%s': %v", c.Id, a.Id, a))
}
}
return ReferencePointDifference{
ReferencePoint: r.Id,
Coefficients: referencePointsDiffs,
}
}