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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/rbfuzzymind/rbfuzzymind.rb +197 -0
  3. 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: []