-
-
Notifications
You must be signed in to change notification settings - Fork 46.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add FuzzySet Class for Triangular Fuzzy Sets #11036
Changes from all commits
bb8f7f7
48f246d
5e1dfe6
6d751f8
e778cb3
abe9361
c51022b
cb77a2a
5486668
231b33e
798e78f
a7b7a91
c6022c2
1183dd9
ee0a7c0
de13593
cacc1d1
472e739
5565063
d2cdcb8
d091358
0db5402
70c3787
81340cd
26cf8e7
54a3a42
f0f581a
8a01993
14410df
10bc341
3ff4ec9
06db239
4e9ded8
8ccf12a
a357f85
d961a50
050debb
ae179fa
f3ae7ed
d9a8c65
faed044
2b1cef8
2dd8521
c343a09
16a712a
005f852
dc849bd
8c8b200
cec6c1d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,195 @@ | ||||||||||
""" | ||||||||||
By @Shreya123714 | ||||||||||
|
||||||||||
https://en.wikipedia.org/wiki/Fuzzy_set | ||||||||||
""" | ||||||||||
|
||||||||||
from __future__ import annotations | ||||||||||
|
||||||||||
from dataclasses import dataclass | ||||||||||
|
||||||||||
import matplotlib.pyplot as plt | ||||||||||
import numpy as np | ||||||||||
|
||||||||||
|
||||||||||
@dataclass | ||||||||||
class FuzzySet: | ||||||||||
""" | ||||||||||
A class for representing and manipulating triangular fuzzy sets. | ||||||||||
Attributes: | ||||||||||
name: The name or label of the fuzzy set. | ||||||||||
left_boundary: The left boundary of the fuzzy set. | ||||||||||
peak: The peak (central) value of the fuzzy set. | ||||||||||
right_boundary: The right boundary of the fuzzy set. | ||||||||||
Methods: | ||||||||||
membership(x): Calculate the membership value of an input 'x' in the fuzzy set. | ||||||||||
union(other): Calculate the union of this fuzzy set with another fuzzy set. | ||||||||||
intersection(other): Calculate the intersection of this fuzzy set with another. | ||||||||||
complement(): Calculate the complement (negation) of this fuzzy set. | ||||||||||
plot(): Plot the membership function of the fuzzy set. | ||||||||||
|
||||||||||
>>> sheru = FuzzySet("Sheru", 0.4, 1, 0.6) | ||||||||||
>>> sheru | ||||||||||
FuzzySet(name='Sheru', left_boundary=0.4, peak=1, right_boundary=0.6) | ||||||||||
>>> str(sheru) | ||||||||||
'Sheru: [0.4, 1, 0.6]' | ||||||||||
|
||||||||||
>>> siya = FuzzySet("Siya", 0.5, 1, 0.7) | ||||||||||
>>> siya | ||||||||||
FuzzySet(name='Siya', left_boundary=0.5, peak=1, right_boundary=0.7) | ||||||||||
|
||||||||||
# Complement Operation | ||||||||||
>>> sheru.complement() | ||||||||||
FuzzySet(name='¬Sheru', left_boundary=0.4, peak=0.6, right_boundary=0) | ||||||||||
>>> siya.complement() # doctest: +NORMALIZE_WHITESPACE | ||||||||||
FuzzySet(name='¬Siya', left_boundary=0.30000000000000004, peak=0.5, | ||||||||||
right_boundary=0) | ||||||||||
|
||||||||||
# Intersection Operation | ||||||||||
>>> siya.intersection(sheru) | ||||||||||
FuzzySet(name='Siya ∩ Sheru', left_boundary=0.5, peak=0.6, right_boundary=1.0) | ||||||||||
|
||||||||||
# Membership Operation | ||||||||||
>>> sheru.membership(0.5) | ||||||||||
0.16666666666666663 | ||||||||||
>>> sheru.membership(0.6) | ||||||||||
0.0 | ||||||||||
|
||||||||||
# Union Operations | ||||||||||
>>> siya.union(sheru) | ||||||||||
FuzzySet(name='Siya ∪ Sheru', left_boundary=0.4, peak=0.7, right_boundary=1.0) | ||||||||||
""" | ||||||||||
|
||||||||||
name: str | ||||||||||
left_boundary: float | ||||||||||
peak: float | ||||||||||
right_boundary: float | ||||||||||
|
||||||||||
def __str__(self) -> str: | ||||||||||
""" | ||||||||||
>>> FuzzySet("fuzzy_set", 0.1, 0.2, 0.3) | ||||||||||
FuzzySet(name='fuzzy_set', left_boundary=0.1, peak=0.2, right_boundary=0.3) | ||||||||||
""" | ||||||||||
return ( | ||||||||||
f"{self.name}: [{self.left_boundary}, {self.peak}, {self.right_boundary}]" | ||||||||||
) | ||||||||||
|
||||||||||
def complement(self) -> FuzzySet: | ||||||||||
""" | ||||||||||
Calculate the complement (negation) of this fuzzy set. | ||||||||||
Returns: | ||||||||||
FuzzySet: A new fuzzy set representing the complement. | ||||||||||
|
||||||||||
>>> FuzzySet("fuzzy_set", 0.1, 0.2, 0.3).complement() | ||||||||||
FuzzySet(name='¬fuzzy_set', left_boundary=0.7, peak=0.9, right_boundary=0.8) | ||||||||||
""" | ||||||||||
return FuzzySet( | ||||||||||
f"¬{self.name}", | ||||||||||
1 - self.right_boundary, | ||||||||||
1 - self.left_boundary, | ||||||||||
1 - self.peak, | ||||||||||
) | ||||||||||
|
||||||||||
def intersection(self, other) -> FuzzySet: | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide type hint for the parameter: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide type hint for the parameter:
cclauss marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
""" | ||||||||||
Calculate the intersection of this fuzzy set | ||||||||||
with another fuzzy set. | ||||||||||
Args: | ||||||||||
other: Another fuzzy set to intersect with. | ||||||||||
Returns: | ||||||||||
A new fuzzy set representing the intersection. | ||||||||||
|
||||||||||
>>> FuzzySet("a", 0.1, 0.2, 0.3).intersection(FuzzySet("b", 0.4, 0.5, 0.6)) | ||||||||||
FuzzySet(name='a ∩ b', left_boundary=0.4, peak=0.3, right_boundary=0.35) | ||||||||||
""" | ||||||||||
return FuzzySet( | ||||||||||
f"{self.name} ∩ {other.name}", | ||||||||||
max(self.left_boundary, other.left_boundary), | ||||||||||
min(self.right_boundary, other.right_boundary), | ||||||||||
(self.peak + other.peak) / 2, | ||||||||||
) | ||||||||||
|
||||||||||
def membership(self, x: float) -> float: | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide descriptive name for the parameter: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide descriptive name for the parameter:
cclauss marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
""" | ||||||||||
Calculate the membership value of an input 'x' in the fuzzy set. | ||||||||||
Returns: | ||||||||||
The membership value of 'x' in the fuzzy set. | ||||||||||
|
||||||||||
>>> a = FuzzySet("a", 0.1, 0.2, 0.3) | ||||||||||
>>> a.membership(0.09) | ||||||||||
0.0 | ||||||||||
>>> a.membership(0.1) | ||||||||||
0.0 | ||||||||||
>>> a.membership(0.11) | ||||||||||
0.09999999999999995 | ||||||||||
>>> a.membership(0.4) | ||||||||||
0.0 | ||||||||||
>>> FuzzySet("A", 0, 0.5, 1).membership(0.1) | ||||||||||
0.2 | ||||||||||
>>> FuzzySet("B", 0.2, 0.7, 1).membership(0.6) | ||||||||||
0.8 | ||||||||||
""" | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All methods should have at least one doctest.
Suggested change
|
||||||||||
if x <= self.left_boundary or x >= self.right_boundary: | ||||||||||
return 0.0 | ||||||||||
elif self.left_boundary < x <= self.peak: | ||||||||||
return (x - self.left_boundary) / (self.peak - self.left_boundary) | ||||||||||
elif self.peak < x < self.right_boundary: | ||||||||||
return (self.right_boundary - x) / (self.right_boundary - self.peak) | ||||||||||
msg = f"Invalid value {x} for fuzzy set {self}" | ||||||||||
raise ValueError(msg) | ||||||||||
|
||||||||||
def union(self, other) -> FuzzySet: | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide type hint for the parameter: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide type hint for the parameter:
cclauss marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
""" | ||||||||||
Calculate the union of this fuzzy set with another fuzzy set. | ||||||||||
Args: | ||||||||||
other (FuzzySet): Another fuzzy set to union with. | ||||||||||
Returns: | ||||||||||
FuzzySet: A new fuzzy set representing the union. | ||||||||||
|
||||||||||
>>> FuzzySet("a", 0.1, 0.2, 0.3).union(FuzzySet("b", 0.4, 0.5, 0.6)) | ||||||||||
FuzzySet(name='a ∪ b', left_boundary=0.1, peak=0.6, right_boundary=0.35) | ||||||||||
""" | ||||||||||
return FuzzySet( | ||||||||||
f"{self.name} ∪ {other.name}", | ||||||||||
min(self.left_boundary, other.left_boundary), | ||||||||||
max(self.right_boundary, other.right_boundary), | ||||||||||
(self.peak + other.peak) / 2, | ||||||||||
) | ||||||||||
|
||||||||||
def plot(self): | ||||||||||
cclauss marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As there is no test file in this pull request nor any test function or class in the file Please provide return type hint for the function: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide return type hint for the function: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide return type hint for the function: As there is no test file in this pull request nor any test function or class in the file There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide return type hint for the function: As there is no test file in this pull request nor any test function or class in the file There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide return type hint for the function: As there is no test file in this pull request nor any test function or class in the file There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide return type hint for the function: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide return type hint for the function: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide return type hint for the function: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide return type hint for the function: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide return type hint for the function: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide return type hint for the function: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide return type hint for the function: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide return type hint for the function:
cclauss marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
""" | ||||||||||
Plot the membership function of the fuzzy set. | ||||||||||
""" | ||||||||||
x = np.linspace(0, 1, 1000) | ||||||||||
y = [self.membership(xi) for xi in x] | ||||||||||
|
||||||||||
plt.plot(x, y, label=self.name) | ||||||||||
|
||||||||||
|
||||||||||
if __name__ == "__main__": | ||||||||||
from doctest import testmod | ||||||||||
|
||||||||||
testmod() | ||||||||||
a = FuzzySet("A", 0, 0.5, 1) | ||||||||||
b = FuzzySet("B", 0.2, 0.7, 1) | ||||||||||
|
||||||||||
a.plot() | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An error occurred while parsing the file: Traceback (most recent call last):
File "/opt/render/project/src/algorithms_keeper/parser/python_parser.py", line 146, in parse
reports = lint_file(
^^^^^^^^^^
libcst._exceptions.ParserSyntaxError: Syntax Error @ 142:3.
parser error: error at 141:2: expected one of (, *, +, -, ..., AWAIT, EOF, False, NAME, NUMBER, None, True, [, break, continue, elif, else, lambda, match, not, pass, ~
a.plot()
^ |
||||||||||
b.plot() | ||||||||||
|
||||||||||
plt.xlabel("x") | ||||||||||
plt.ylabel("Membership") | ||||||||||
plt.legend() | ||||||||||
plt.show() | ||||||||||
|
||||||||||
union_ab = a.union(b) | ||||||||||
intersection_ab = a.intersection(b) | ||||||||||
complement_a = a.complement() | ||||||||||
|
||||||||||
union_ab.plot() | ||||||||||
intersection_ab.plot() | ||||||||||
complement_a.plot() | ||||||||||
|
||||||||||
plt.xlabel("x") | ||||||||||
plt.ylabel("Membership") | ||||||||||
plt.legend() | ||||||||||
plt.show() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make this a https://docs.python.org/3/library/dataclasses.html