Skip to content

Commit b5dad67

Browse files
Shreya123714pre-commit-ci[bot]cclauss
authored andcommitted
Add FuzzySet Class for Triangular Fuzzy Sets (TheAlgorithms#11036)
* Added Opertation for triangular fuzzy sets * Added Sources * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix the bug , for which test were failing * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Add type hints and improve parameter names * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Add Test For fuzzy_operations.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix the bug in fuzzy_operations.py * Add test_fuzzy_logic.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix the bug in fuzzy_operations.py & deleted test * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fixed the typo error * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Again done * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * corrected wrong intendation due to which test fail * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * bug fixed * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Add test_fuzzy_logic * Modified fuzzy_operations.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fixed the bug, made a FuzzySet dataclass * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Replaced assertEqual of unittest to assert python * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * lets see * Changed test * orderd the import statements * Add docstring and dataclass the FuzzySet * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update fuzzy_operations.py * Delete fuzzy_logic/test_fuzzy_logic.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * https://en.wikipedia.org/wiki/Fuzzy_set --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Christian Clauss <cclauss@me.com>
1 parent 348a036 commit b5dad67

File tree

1 file changed

+195
-0
lines changed

1 file changed

+195
-0
lines changed

fuzzy_logic/fuzzy_operations.py

+195
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
"""
2+
By @Shreya123714
3+
4+
https://en.wikipedia.org/wiki/Fuzzy_set
5+
"""
6+
7+
from __future__ import annotations
8+
9+
from dataclasses import dataclass
10+
11+
import matplotlib.pyplot as plt
12+
import numpy as np
13+
14+
15+
@dataclass
16+
class FuzzySet:
17+
"""
18+
A class for representing and manipulating triangular fuzzy sets.
19+
Attributes:
20+
name: The name or label of the fuzzy set.
21+
left_boundary: The left boundary of the fuzzy set.
22+
peak: The peak (central) value of the fuzzy set.
23+
right_boundary: The right boundary of the fuzzy set.
24+
Methods:
25+
membership(x): Calculate the membership value of an input 'x' in the fuzzy set.
26+
union(other): Calculate the union of this fuzzy set with another fuzzy set.
27+
intersection(other): Calculate the intersection of this fuzzy set with another.
28+
complement(): Calculate the complement (negation) of this fuzzy set.
29+
plot(): Plot the membership function of the fuzzy set.
30+
31+
>>> sheru = FuzzySet("Sheru", 0.4, 1, 0.6)
32+
>>> sheru
33+
FuzzySet(name='Sheru', left_boundary=0.4, peak=1, right_boundary=0.6)
34+
>>> str(sheru)
35+
'Sheru: [0.4, 1, 0.6]'
36+
37+
>>> siya = FuzzySet("Siya", 0.5, 1, 0.7)
38+
>>> siya
39+
FuzzySet(name='Siya', left_boundary=0.5, peak=1, right_boundary=0.7)
40+
41+
# Complement Operation
42+
>>> sheru.complement()
43+
FuzzySet(name='¬Sheru', left_boundary=0.4, peak=0.6, right_boundary=0)
44+
>>> siya.complement() # doctest: +NORMALIZE_WHITESPACE
45+
FuzzySet(name='¬Siya', left_boundary=0.30000000000000004, peak=0.5,
46+
right_boundary=0)
47+
48+
# Intersection Operation
49+
>>> siya.intersection(sheru)
50+
FuzzySet(name='Siya ∩ Sheru', left_boundary=0.5, peak=0.6, right_boundary=1.0)
51+
52+
# Membership Operation
53+
>>> sheru.membership(0.5)
54+
0.16666666666666663
55+
>>> sheru.membership(0.6)
56+
0.0
57+
58+
# Union Operations
59+
>>> siya.union(sheru)
60+
FuzzySet(name='Siya ∪ Sheru', left_boundary=0.4, peak=0.7, right_boundary=1.0)
61+
"""
62+
63+
name: str
64+
left_boundary: float
65+
peak: float
66+
right_boundary: float
67+
68+
def __str__(self) -> str:
69+
"""
70+
>>> FuzzySet("fuzzy_set", 0.1, 0.2, 0.3)
71+
FuzzySet(name='fuzzy_set', left_boundary=0.1, peak=0.2, right_boundary=0.3)
72+
"""
73+
return (
74+
f"{self.name}: [{self.left_boundary}, {self.peak}, {self.right_boundary}]"
75+
)
76+
77+
def complement(self) -> FuzzySet:
78+
"""
79+
Calculate the complement (negation) of this fuzzy set.
80+
Returns:
81+
FuzzySet: A new fuzzy set representing the complement.
82+
83+
>>> FuzzySet("fuzzy_set", 0.1, 0.2, 0.3).complement()
84+
FuzzySet(name='¬fuzzy_set', left_boundary=0.7, peak=0.9, right_boundary=0.8)
85+
"""
86+
return FuzzySet(
87+
f"¬{self.name}",
88+
1 - self.right_boundary,
89+
1 - self.left_boundary,
90+
1 - self.peak,
91+
)
92+
93+
def intersection(self, other) -> FuzzySet:
94+
"""
95+
Calculate the intersection of this fuzzy set
96+
with another fuzzy set.
97+
Args:
98+
other: Another fuzzy set to intersect with.
99+
Returns:
100+
A new fuzzy set representing the intersection.
101+
102+
>>> FuzzySet("a", 0.1, 0.2, 0.3).intersection(FuzzySet("b", 0.4, 0.5, 0.6))
103+
FuzzySet(name='a ∩ b', left_boundary=0.4, peak=0.3, right_boundary=0.35)
104+
"""
105+
return FuzzySet(
106+
f"{self.name}{other.name}",
107+
max(self.left_boundary, other.left_boundary),
108+
min(self.right_boundary, other.right_boundary),
109+
(self.peak + other.peak) / 2,
110+
)
111+
112+
def membership(self, x: float) -> float:
113+
"""
114+
Calculate the membership value of an input 'x' in the fuzzy set.
115+
Returns:
116+
The membership value of 'x' in the fuzzy set.
117+
118+
>>> a = FuzzySet("a", 0.1, 0.2, 0.3)
119+
>>> a.membership(0.09)
120+
0.0
121+
>>> a.membership(0.1)
122+
0.0
123+
>>> a.membership(0.11)
124+
0.09999999999999995
125+
>>> a.membership(0.4)
126+
0.0
127+
>>> FuzzySet("A", 0, 0.5, 1).membership(0.1)
128+
0.2
129+
>>> FuzzySet("B", 0.2, 0.7, 1).membership(0.6)
130+
0.8
131+
"""
132+
if x <= self.left_boundary or x >= self.right_boundary:
133+
return 0.0
134+
elif self.left_boundary < x <= self.peak:
135+
return (x - self.left_boundary) / (self.peak - self.left_boundary)
136+
elif self.peak < x < self.right_boundary:
137+
return (self.right_boundary - x) / (self.right_boundary - self.peak)
138+
msg = f"Invalid value {x} for fuzzy set {self}"
139+
raise ValueError(msg)
140+
141+
def union(self, other) -> FuzzySet:
142+
"""
143+
Calculate the union of this fuzzy set with another fuzzy set.
144+
Args:
145+
other (FuzzySet): Another fuzzy set to union with.
146+
Returns:
147+
FuzzySet: A new fuzzy set representing the union.
148+
149+
>>> FuzzySet("a", 0.1, 0.2, 0.3).union(FuzzySet("b", 0.4, 0.5, 0.6))
150+
FuzzySet(name='a ∪ b', left_boundary=0.1, peak=0.6, right_boundary=0.35)
151+
"""
152+
return FuzzySet(
153+
f"{self.name}{other.name}",
154+
min(self.left_boundary, other.left_boundary),
155+
max(self.right_boundary, other.right_boundary),
156+
(self.peak + other.peak) / 2,
157+
)
158+
159+
def plot(self):
160+
"""
161+
Plot the membership function of the fuzzy set.
162+
"""
163+
x = np.linspace(0, 1, 1000)
164+
y = [self.membership(xi) for xi in x]
165+
166+
plt.plot(x, y, label=self.name)
167+
168+
169+
if __name__ == "__main__":
170+
from doctest import testmod
171+
172+
testmod()
173+
a = FuzzySet("A", 0, 0.5, 1)
174+
b = FuzzySet("B", 0.2, 0.7, 1)
175+
176+
a.plot()
177+
b.plot()
178+
179+
plt.xlabel("x")
180+
plt.ylabel("Membership")
181+
plt.legend()
182+
plt.show()
183+
184+
union_ab = a.union(b)
185+
intersection_ab = a.intersection(b)
186+
complement_a = a.complement()
187+
188+
union_ab.plot()
189+
intersection_ab.plot()
190+
complement_a.plot()
191+
192+
plt.xlabel("x")
193+
plt.ylabel("Membership")
194+
plt.legend()
195+
plt.show()

0 commit comments

Comments
 (0)