模糊控制中有一個(gè)隸屬度函數(shù)的概念宴偿。
是模糊集合中會用到的函數(shù)祖灰,是一般集合中指示函數(shù)的一般化[1]含长。指示函數(shù)可以說明一個(gè)集合中的元素是否屬于特定子集合券腔。一元素的指示函數(shù)的值可能是0或是1,而一元素的隸屬函數(shù)會是0到1之間的數(shù)值拘泞,表示元素屬于某模糊集合的“真實(shí)程度”(degree of truth)纷纫。
這次我們編寫6種常見隸屬度函數(shù)(來源:百度文庫)的計(jì)算程序。
按這個(gè)文件命名哦陪腌!
membership_function.py
'''
六種常見的隸屬度函數(shù)
矩陣
梯形
拋物線
高斯
柯西
伽馬
'''
from math import exp
import numpy as np
import matplotlib.pyplot as plt
class MembershipDegree(object):
def no_mold(self,mold):
# 選擇模式是否存在
print('no this mold: {0} ???\n we have 0/1/2 represent small/medium/large'.format(mold))
exit(1)
def y_array(self,f,x):
y=[]
for xx in x:
y.append(f(xx))
y=np.array(y)
return y
def huahua(self,x,y):
plt.plot(x, y)
plt.ylim(-0.2, 1.2)
plt.xlim(x[0] - (max(x) - min(x)) * 0.1, x[-1] + (max(x) - min(x)) * 0.1)
# plt.axes([x[0]-(max(x)-min(x))*0.1,x[-1]+(max(x)-min(x))*0.1,-0.2,1.2])
plt.grid()
class Matrix(MembershipDegree):
def __init__(self,a,b=None,mold=0):
super().__init__()
if (mold == 1):
assert b != None
self.a=a
self.b=b
self.mold=mold
def matrix(self,x):
a,b,mold=self.a,self.b,self.mold
# 矩陣型
if(mold==1):
# 中間型
if (a<=x<=b):
u = 1
else:
u = 0
elif(mold==0):
# 偏小型
if (x<=a):
u=1
else:
u=0
elif(mold==2):
# 偏大型
if (x<a):
u=0
else:
u=1
else:
super().no_mold(mold)
return
return u
class Trapezoid(MembershipDegree):
def __init__(self,a,b,c=None,d=None,mold=0):
super().__init__()
if (mold == 1):
assert c != None and d != None
self.a,self.b,self.c,self.d,self.mold=a,b,c,d,mold
def trapezoid(self,x):
a, b, c, d, mold=self.a,self.b,self.c,self.d,self.mold
# 梯形
if(mold==1):
assert c!=None and d!=None
# 中間型
if(a<=x<=b):
u=(x-a)/(b-a)
elif(b<=x<=c):
u=1
elif(c<=x<=d):
u=(d-x)/(d-c)
else:
u=0
elif(mold==0):
# 小
if(x<=a):
u=1
elif(x>b):
u=0
else:
u=(b-x)/(b-a)
elif(mold==2):
# 大
if (x <= a):
u = 0
elif (x > b):
u = 1
else:
u = 1-(b - x) / (b - a)
else:
super().no_mold(mold)
return
return u
class Paracurve(MembershipDegree):
def __init__(self,a,b,c=None,d=None,mold=0,k=3):
super().__init__()
self.a, self.b, self.c, self.d, self.mold,self.k= a, b, c, d, mold,k
self.temp = Trapezoid(a, b, c, d, mold)
def paracurve(self,x):
# k次拋物線 哈哈-->>就是在梯形型基礎(chǔ)上對每一個(gè)結(jié)果k次方
a, b, c, d, mold, k=self.a, self.b, self.c, self.d, self.mold, self.k
u=self.temp.trapezoid(x)**k
return u
class Gauss(MembershipDegree):
def __init__(self,a=0,mold=0,theta=1):
self.a,self.mold,self.theta=a,mold,theta
def gauss(self,x):
a, mold, theta=self.a,self.mold,self.theta
# theta:方差
# a:均值
# 高斯型
f=lambda :exp(-((x-a)/theta)**2)
if(mold==1):
u=f()
elif(mold==0):
if(x<=a):
u=1
else:
u=f()
elif(mold==2):
if(x<=a):
u=0
else:
u=1-f()
else:
super().no_mold(mold)
return
return u
class Cauchy(MembershipDegree):
def __init__(self,a,mold=0,alpha=1,beta=2):
assert alpha > 0 and beta > 0
if (mold == 1):
assert beta % 2 == 0
self.a,self.mold,self.alpha,self.beta=a,mold,alpha,beta
def cauchy(self,x):
'''
柯西型
:param x:
:param a: 絕對值開始/結(jié)束
:param mold:
:param alpha: 可以選1/sqrt(a)
:param beta: 變化速度 越大越快 1為線性
:return:
'''
a, mold, alpha, beta=self.a,self.mold,self.alpha,self.beta
f=lambda b:1/(1+alpha*(x-alpha)**b)
if(mold==1):
u=f(beta)
elif(mold==0):
if(x<=a):
u=1
else:
u=f(beta)
elif(mold==2):
if(x<=a):
u=0
else:
u=f(-beta)
else:
super().no_mold(mold)
return
return u
class Gamma(MembershipDegree):
def __init__(self,a,b=None,mold=0,k=2):
if (mold == 1):
assert b != None
self.a,self.b,self.mold,self.k=a,b,mold,k
def gamma(self,x):
'''
伽馬型
:param x:
:param a:
:param b:
:param mold:
:param k:
:return:
'''
a, b, mold, k= self.a, self.b, self.mold, self.k
f=lambda :exp(-k*(x-a))
if(mold==1):
if(x<a):
u=exp(k*(x-a))
elif(x>b):
u=exp(-k*(x-b))
else:
u=1
elif(mold==0):
if(x<=a):
u=1
else:
u=f()
elif(mold==2):
if(x<=a):
u=0
else:
u=1-f()
else:
super().no_mold(mold)
return
return u
if __name__ == '__main__':
# 畫圖測試
x=np.arange(0,10,0.01)
# 實(shí)例化一個(gè)伽馬
g=Gauss(a=3,mold=1)
# 用父類函數(shù)運(yùn)算哈哈哈
y=g.y_array(g.gauss,x)
g.huahua(x,y)
# plt.savefig('test')
plt.show()
pass
科學(xué)的隸屬度函數(shù)確定方法
因?yàn)檫€有期末考試辱魁,所以我做了個(gè)demo
隸屬度函數(shù)的建立
——關(guān)于年老,年輕诗鸭,不大不小的設(shè)計(jì)說明
隸屬度函數(shù)是模糊控制的應(yīng)用基礎(chǔ),正確構(gòu)造隸屬度函數(shù)是能否用好模糊控制的關(guān)鍵之一染簇。隸屬度函數(shù)的確定過程,本質(zhì)上說應(yīng)該是客觀的,但每個(gè)人對于同一個(gè)模糊概念的認(rèn)識理解又有差異,因此,隸屬度函數(shù)的確定又帶有主觀性。
由于時(shí)間强岸、精力所限锻弓,結(jié)合題目情況,是一個(gè)生活觀念的判斷蝌箍,我選擇了例證法青灼。即預(yù)選了幾個(gè)年齡1~100歲,設(shè)置了幾個(gè)有確定值的選項(xiàng)妓盲,如年輕杂拨,比較年輕,不年輕悯衬。讓朋友圈的人幫忙打分弹沽。因?yàn)楦嬖V大家我在做大作業(yè),所以親朋好友比較配合,很有默契地選擇了有規(guī)律答案贷币,方便我做擬合击胜。
基于獲得的少量數(shù)據(jù),加上我主觀判斷役纹,我選擇了高斯偶摔、柯西型函數(shù)等,調(diào)整了一下參數(shù)促脉,比較粗糙辰斋,還望多多包涵。
old_or_young.py
'''
設(shè)計(jì)一個(gè)年老瘸味,很年輕宫仗,不老也不年輕模糊集的隸屬度函數(shù)
'''
from matplotlib import pyplot as plt
import numpy as np
# 從上一個(gè)包中導(dǎo)入
import membership_function as mf
x=np.arange(0,100,0.05)
young=mf.Paracurve(a=25,b=35,k=5)
y=young.y_array(young.paracurve,x)
young.huahua(x,y)
plt.vlines(25,0,1,linestyles='-')
plt.annotate('<-sure young\n 25 years old',xy=(25,0),xytext=(16,-0.15),arrowprops = dict(facecolor = 'black', shrink = 0.1))
plt.annotate('no young->\n 35 years old',xy=(35,0),arrowprops = dict(facecolor = 'black', shrink = 0.1))
plt.savefig('young')
plt.show()
strong=mf.Gamma(35,55,1,k=2)
y=strong.y_array(strong.gamma,x)
strong.huahua(x,y)
plt.vlines(35,0,1,linestyles='-')
plt.vlines(55,0,1,linestyles='-')
plt.annotate('stronger',xy=(40,0.3))
plt.savefig('strong')
plt.show()
young=mf.Paracurve(a=50,b=65,mold=2,k=5)
y=young.y_array(young.paracurve,x)
young.huahua(x,y)
plt.vlines(65,0,1,linestyles='-')
plt.annotate('big age->\n 65 years old',xy=(65,0),arrowprops = dict(facecolor = 'black', shrink = 0.1))
plt.savefig('bigage')
plt.show()