rbfuzzymind 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/rbfuzzymind/rbfuzzymind.rb +197 -0
- metadata +65 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 59fde5073fd561cef8896af5c5c68178d385215d10a9a46c4599ad42652cfd1b
|
4
|
+
data.tar.gz: 979636b8e3f11a4b2231d4d0f9eef4c5b9b05667c8523f7598806e9b9d01201a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 927c7a16cda5736b13511be75f093ab848e80265fda3d50325ca43536eaf005bf2fd34fb7f90193e758884d0f844c697e3da3c51cc5dcb0bc79c14025dc98c2d
|
7
|
+
data.tar.gz: 89dec6e8a795a631774035e4ba7436e842aa8ecf492ebfc58b53352d2b6f64171eeebbd60f2d857c3eb9b5a719874cdea449873eb7f60dc900bade75787a12d5
|
@@ -0,0 +1,197 @@
|
|
1
|
+
|
2
|
+
class FuzzySet
|
3
|
+
attr_reader :name, :membership_function
|
4
|
+
|
5
|
+
def initialize(name, &membership_function)
|
6
|
+
@name = name
|
7
|
+
@membership_function = membership_function
|
8
|
+
end
|
9
|
+
|
10
|
+
def membership_degree(x)
|
11
|
+
membership_function.call(x)
|
12
|
+
end
|
13
|
+
|
14
|
+
def union(other_set)
|
15
|
+
FuzzySet.new("Union(#{name}, #{other_set.name})") do |x|
|
16
|
+
[membership_function.call(x), other_set.membership_function.call(x)].max
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def intersection(other_set)
|
21
|
+
FuzzySet.new("Intersection(#{name}, #{other_set.name})") do |x|
|
22
|
+
[membership_function.call(x), other_set.membership_function.call(x)].min
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def complement
|
27
|
+
FuzzySet.new("Complement(#{name})") do |x|
|
28
|
+
1 - membership_function.call(x)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def normalize
|
33
|
+
FuzzySet.new("Normalized(#{name})") do |x|
|
34
|
+
membership_function.call(x) / [1, membership_function.call(x)].max
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def centroid(min_val, max_val, step = 0.01)
|
39
|
+
numerator = 0
|
40
|
+
denominator = 0
|
41
|
+
x = min_val
|
42
|
+
|
43
|
+
while x <= max_val
|
44
|
+
mu = membership_function.call(x)
|
45
|
+
numerator += x * mu
|
46
|
+
denominator += mu
|
47
|
+
x += step
|
48
|
+
end
|
49
|
+
|
50
|
+
denominator == 0 ? 0 : numerator / denominator
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class FuzzyRule
|
55
|
+
attr_reader :condition, :consequence, :weight
|
56
|
+
|
57
|
+
def initialize(condition, consequence, weight = 1)
|
58
|
+
@condition = condition
|
59
|
+
@consequence = consequence
|
60
|
+
@weight = weight
|
61
|
+
end
|
62
|
+
|
63
|
+
def evaluate(inputs)
|
64
|
+
if condition.call(inputs)
|
65
|
+
result = if consequence.is_a?(FuzzySet)
|
66
|
+
consequence
|
67
|
+
elsif consequence.respond_to?(:call)
|
68
|
+
consequence.call(inputs)
|
69
|
+
else
|
70
|
+
consequence
|
71
|
+
end
|
72
|
+
{ "result" => result, "weight" => weight }
|
73
|
+
else
|
74
|
+
nil
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
class InferenceEngine
|
80
|
+
def initialize(rules)
|
81
|
+
@rules = rules
|
82
|
+
end
|
83
|
+
|
84
|
+
def infer(inputs)
|
85
|
+
results = @rules.map do |rule|
|
86
|
+
rule.evaluate(inputs)
|
87
|
+
end.compact
|
88
|
+
|
89
|
+
aggregate_results(results)
|
90
|
+
end
|
91
|
+
|
92
|
+
def aggregate_results(results)
|
93
|
+
return 'Low Priority' if results.empty?
|
94
|
+
|
95
|
+
total_weight = 0
|
96
|
+
weighted_sum = 0
|
97
|
+
|
98
|
+
results.each do |result|
|
99
|
+
weighted_sum += priority_mapping(result['result']) * result['weight']
|
100
|
+
total_weight += result['weight']
|
101
|
+
end
|
102
|
+
|
103
|
+
if total_weight > 0
|
104
|
+
reverse_priority_mapping(weighted_sum / total_weight)
|
105
|
+
else
|
106
|
+
'Low Priority'
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def priority_mapping(priority)
|
111
|
+
{ 'Urgent' => 3, 'High Priority' => 2, 'Medium Priority' => 1 }.fetch(priority, 0)
|
112
|
+
end
|
113
|
+
|
114
|
+
def reverse_priority_mapping(score)
|
115
|
+
case score
|
116
|
+
when 2.5..Float::INFINITY
|
117
|
+
'Urgent'
|
118
|
+
when 1.5...2.5
|
119
|
+
'High Priority'
|
120
|
+
when 0.5...1.5
|
121
|
+
'Medium Priority'
|
122
|
+
else
|
123
|
+
'Low Priority'
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def get_fuzzy_set_consequences
|
128
|
+
@rules.select { |rule| rule.consequence.is_a?(FuzzySet) }.map(&:consequence)
|
129
|
+
end
|
130
|
+
|
131
|
+
def defuzzify_centroid(min_val, max_val, step = 0.01)
|
132
|
+
numerator = 0
|
133
|
+
denominator = 0
|
134
|
+
fuzzy_sets = get_fuzzy_set_consequences
|
135
|
+
x = min_val
|
136
|
+
|
137
|
+
while x <= max_val
|
138
|
+
mu = fuzzy_sets.map { |fs| fs.membership_degree(x) || 0 }.max || 0
|
139
|
+
numerator += x * mu
|
140
|
+
denominator += mu
|
141
|
+
x += step
|
142
|
+
end
|
143
|
+
|
144
|
+
denominator == 0 ? 0 : numerator / denominator
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
def defuzzify_mom(min_val, max_val, step = 0.01)
|
149
|
+
max_mu = 0
|
150
|
+
sum_x = 0
|
151
|
+
count = 0
|
152
|
+
fuzzy_sets = get_fuzzy_set_consequences
|
153
|
+
x = min_val
|
154
|
+
|
155
|
+
while x <= max_val
|
156
|
+
mu = fuzzy_sets.map { |fs| fs.membership_degree(x) }.max
|
157
|
+
if mu > max_mu
|
158
|
+
max_mu = mu
|
159
|
+
sum_x = x
|
160
|
+
count = 1
|
161
|
+
elsif mu == max_mu
|
162
|
+
sum_x += x
|
163
|
+
count += 1
|
164
|
+
end
|
165
|
+
x += step
|
166
|
+
end
|
167
|
+
|
168
|
+
count == 0 ? 0 : sum_x / count
|
169
|
+
end
|
170
|
+
|
171
|
+
def defuzzify_bisector(min_val, max_val, step = 0.01)
|
172
|
+
total_area = 0
|
173
|
+
left_area = 0
|
174
|
+
bisector = min_val
|
175
|
+
fuzzy_sets = get_fuzzy_set_consequences
|
176
|
+
x = min_val
|
177
|
+
|
178
|
+
while x <= max_val
|
179
|
+
mu = fuzzy_sets.map { |fs| fs.membership_degree(x) }.max
|
180
|
+
total_area += mu * step
|
181
|
+
x += step
|
182
|
+
end
|
183
|
+
|
184
|
+
x = min_val
|
185
|
+
while x <= max_val
|
186
|
+
mu = fuzzy_sets.map { |fs| fs.membership_degree(x) }.max
|
187
|
+
left_area += mu * step
|
188
|
+
if left_area >= total_area / 2
|
189
|
+
bisector = x
|
190
|
+
break
|
191
|
+
end
|
192
|
+
x += step
|
193
|
+
end
|
194
|
+
|
195
|
+
bisector
|
196
|
+
end
|
197
|
+
end
|
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rbfuzzymind
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- fadedreams7
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-08-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '13.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '13.0'
|
27
|
+
description: rbfuzzymind is a Ruby gem that provides a comprehensive suite for implementing
|
28
|
+
fuzzy logic systems. It includes classes for fuzzy sets, fuzzy rules, and inference
|
29
|
+
engines, enabling the development of complex decision-making systems based on fuzzy
|
30
|
+
logic principles. Key features include membership function operations (union, intersection,
|
31
|
+
complement, normalization), rule evaluation, and defuzzification methods (centroid,
|
32
|
+
mean of maxima, and bisector). Designed for flexibility and extensibility, rbfuzzymind
|
33
|
+
helps developers build robust and adaptable systems for handling uncertainty and
|
34
|
+
imprecision in various applications.
|
35
|
+
email:
|
36
|
+
- fadedreams7@gmail.com
|
37
|
+
executables: []
|
38
|
+
extensions: []
|
39
|
+
extra_rdoc_files: []
|
40
|
+
files:
|
41
|
+
- lib/rbfuzzymind/rbfuzzymind.rb
|
42
|
+
homepage: https://github.com/fadedreams/rbfuzzymind
|
43
|
+
licenses:
|
44
|
+
- MIT
|
45
|
+
metadata: {}
|
46
|
+
post_install_message:
|
47
|
+
rdoc_options: []
|
48
|
+
require_paths:
|
49
|
+
- lib
|
50
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 2.5.0
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0'
|
60
|
+
requirements: []
|
61
|
+
rubygems_version: 3.5.17
|
62
|
+
signing_key:
|
63
|
+
specification_version: 4
|
64
|
+
summary: A Ruby gem for fuzzy logic systems and inference engines.
|
65
|
+
test_files: []
|