-
Notifications
You must be signed in to change notification settings - Fork 0
/
fuzzy.go
164 lines (133 loc) · 5.4 KB
/
fuzzy.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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// Package fuzzy is a package that implement fuzzy logic to BLT decider.
package fuzzy
import "math"
const(
MustBeLowIncome = 500
MustNotBeLowIncome = 1000
MustNotBeMiddleLowIncome = 400
MustBeMiddleLowIncome = 900
MustBeMiddleHighIncome = 1200
MustNotBeMiddleHighIncome = 1750
MustNotBeHighIncome = 1100
MustBeHighIncome = 1650
)
const(
MustBeLowDebt = 15000
MustNotBeLowDebt = 35000
MustNotBeMiddleLowDebt = 10000
MustBeMiddleLowDebt = 40000
MustBeMiddleHighDebt = 50000
MustNotBeMiddleHighDebt = 75000
MustNotBeHighDebt = 45000
MustBeHighDebt = 70000
)
const(
AcceptedValue = 100
ConsideredValue = 70
RejectedValue = 50
)
// Fuzzy is the main interface of a fuzzy logic algorithm
type Fuzzy interface {
Fuzzification(number *FuzzyNumber) error
Defuzzification(number *FuzzyNumber) error
Inference(number *FuzzyNumber) error
}
// Family is the data needed for this programe.
type Family struct {
Number string
Income float64
Debt float64
}
// FuzzyNumber is the struct thatwill continually holds any fuzzy data.
type FuzzyNumber struct {
Family Family
IncomeMembership []float64
DebtMembership []float64
AccepetedInference float64
ConsideredInference float64
RejectedInference float64
CrispValue float64
}
type BLT struct {
}
// Inference is a function that change from raw linguistic into fuzzy linguistic.
func (b *BLT) Inference(number *FuzzyNumber) error {
number.AccepetedInference = math.Max(math.Min(number.IncomeMembership[0], number.DebtMembership[2]), math.Min(number.IncomeMembership[0], number.DebtMembership[1]))
number.AccepetedInference = math.Max(number.AccepetedInference, math.Min(number.IncomeMembership[0], number.DebtMembership[0]))
number.ConsideredInference = math.Max(math.Min(number.IncomeMembership[1], number.DebtMembership[1]), math.Min(number.IncomeMembership[1], number.DebtMembership[2]))
number.ConsideredInference = math.Max(number.ConsideredInference, math.Min(number.IncomeMembership[2], number.DebtMembership[2]))
number.RejectedInference = math.Max(math.Min(number.IncomeMembership[2], number.DebtMembership[0]), math.Min(number.IncomeMembership[2], number.DebtMembership[1]))
number.RejectedInference = math.Max(number.RejectedInference, math.Min(number.IncomeMembership[1], number.DebtMembership[0]))
return nil
}
// Defuzzification is a function that will transfer fuzzy linguistic to crisp data.
func (b *BLT) Defuzzification(number *FuzzyNumber) error {
number.CrispValue = 0
number.CrispValue += number.AccepetedInference*AcceptedValue
number.CrispValue += number.ConsideredInference* ConsideredValue
number.CrispValue += number.RejectedInference* RejectedValue
number.CrispValue /= (number.AccepetedInference+number.ConsideredInference+number.RejectedInference)
return nil
}
// Fuzzification is a function that will transfer crisp data into linguistic.
func (b *BLT) Fuzzification(number *FuzzyNumber) error {
number.DebtMembership = append(number.DebtMembership, b.DebtLow(number.Family.Debt))
number.DebtMembership = append(number.DebtMembership, b.DebtMiddle(number.Family.Debt))
number.DebtMembership = append(number.DebtMembership, b.DebtHigh(number.Family.Debt))
number.IncomeMembership = append(number.IncomeMembership, b.IncomeLow(number.Family.Income))
number.IncomeMembership = append(number.IncomeMembership, b.IncomeMiddle(number.Family.Income))
number.IncomeMembership = append(number.IncomeMembership, b.IncomeHigh(number.Family.Income))
return nil
}
func (b *BLT) IncomeLow(income float64) float64 {
if income <= MustBeLowIncome {
return 1
} else if income > MustNotBeLowIncome {
return 0
}
return 1 - (float64(income - MustBeLowIncome) / float64(MustNotBeLowIncome - MustBeLowIncome))
}
func (b *BLT) IncomeMiddle(income float64) float64 {
if income > MustBeMiddleLowIncome && income <= MustBeMiddleHighIncome {
return 1
} else if income < MustNotBeMiddleLowIncome || income > MustNotBeMiddleHighIncome {
return 0
} else if income < MustBeMiddleLowIncome && income >= MustNotBeMiddleLowIncome {
return float64(income - MustNotBeMiddleLowIncome) / float64(MustBeMiddleLowIncome - MustNotBeMiddleLowIncome)
}
return 1 - float64(income - MustBeMiddleHighIncome) / float64(MustNotBeMiddleHighIncome - MustBeMiddleHighIncome)
}
func (b *BLT) IncomeHigh(income float64) float64 {
if income <= MustNotBeHighIncome {
return 0
} else if income > MustBeHighIncome {
return 1
}
return float64(income - MustNotBeHighIncome) / float64(MustBeHighIncome - MustNotBeHighIncome)
}
func (b *BLT) DebtLow(income float64) float64 {
if income <= MustBeLowDebt {
return 1
} else if income > MustNotBeLowDebt {
return 0
}
return 1-(float64(income - MustBeLowDebt) / float64(MustNotBeLowDebt - MustBeLowDebt))
}
func (b *BLT) DebtMiddle(income float64) float64 {
if income > MustBeMiddleLowDebt && income <= MustBeMiddleHighDebt {
return 1
} else if income < MustNotBeMiddleLowDebt || income > MustNotBeMiddleHighDebt {
return 0
} else if income < MustBeMiddleLowDebt && income >= MustNotBeMiddleLowDebt {
return float64(income - MustNotBeMiddleLowDebt) / float64(MustBeMiddleLowDebt - MustNotBeMiddleLowDebt)
}
return 1 - (float64(income - MustBeMiddleHighDebt) / float64(MustNotBeMiddleHighDebt - MustBeMiddleHighDebt))
}
func (b *BLT) DebtHigh(income float64) float64 {
if income <= MustNotBeHighDebt {
return 0
} else if income > MustBeHighDebt {
return 1
}
return float64(income - MustNotBeHighDebt) / float64(MustBeHighDebt - MustNotBeHighDebt)
}