文章目录
算法简介
调用示例
例题
主函数
代码
def main():
array = [
[290, 'A', 'A', 'B', 'B'],
[288, 'A', 'B', 'A', 'C'],
[288, 'B', 'A', 'D', 'C'],
[285, 'A', 'B', 'B', 'B'],
[283, 'B', 'A', 'B', 'C'],
[283, 'B', 'D', 'A', 'B'],
[280, 'A', 'B', 'C', 'B'],
[280, 'B', 'A', 'A', 'C'],
[280, 'B', 'B', 'A', 'B'],
[280, 'D', 'B', 'A', 'C'],
[278, 'D', 'C', 'B', 'A'],
[277, 'A', 'B', 'C', 'A'],
[275, 'B', 'C', 'D', 'A'],
[275, 'D', 'B', 'A', 'B'],
[274, 'A', 'B', 'C', 'B'],
[273, 'B', 'A', 'B', 'C']
]
targetMap = {
'A': (85, 90, 100), 'B': (75, 80, 85), 'C': (60, 70, 75), 'D': (50, 55, 60)
}
F = toTriangle(array, targetMap)
print("F:", F)
R = normalization(F, 1)
print("R:", R)
weightArray = [
[0.5, 0.125, 0.125, 0.125, 0.125]
]
W = toTriangle(weightArray, {})
D = construction(R, W)
Wp, Wl = ideal(D)
dp, dl = distance(D, Wp, Wl)
miu = choose(dp, dl)
print("miu", miu)
结果
F: [[(290, 290, 290), (85, 90, 100), (85, 90, 100), (75, 80, 85), (75, 80, 85)], [(288, 288, 288), (85, 90, 100), (75, 80, 85), (85, 90, 100), (60, 70, 75)], [(288, 288, 288), (75, 80, 85), (85, 90, 100), (50, 55, 60), (60, 70, 75)], [(285, 285, 285), (85, 90, 100), (75, 80, 85), (75, 80, 85), (75, 80, 85)], [(283, 283, 283), (75, 80, 85), (85, 90, 100), (75, 80, 85), (60, 70, 75)], [(283, 283, 283), (75, 80, 85), (50, 55, 60), (85, 90, 100), (75, 80, 85)], [(280, 280, 280), (85, 90, 100), (75, 80, 85), (60, 70, 75), (75, 80, 85)], [(280, 280, 280), (75, 80, 85), (85, 90, 100), (85, 90, 100), (60, 70, 75)], [(280, 280, 280), (75, 80, 85), (75, 80, 85), (85, 90, 100), (75, 80, 85)], [(280, 280, 280), (50, 55, 60), (75, 80, 85), (85, 90, 100), (60, 70, 75)], [(278, 278, 278), (50, 55, 60), (60, 70, 75), (75, 80, 85), (85, 90, 100)], [(277, 277, 277), (85, 90, 100), (75, 80, 85), (60, 70, 75), (85, 90, 100)], [(275, 275, 275), (75, 80, 85), (60, 70, 75), (50, 55, 60), (85, 90, 100)], [(275, 275, 275), (50, 55, 60), (75, 80, 85), (85, 90, 100), (75, 80, 85)], [(274, 274, 274), (85, 90, 100), (75, 80, 85), (60, 70, 75), (75, 80, 85)], [(273, 273, 273), (75, 80, 85), (85, 90, 100), (75, 80, 85), (60, 70, 75)]]
R: [[(1.0, 1.0, 1.0), (0.85, 1.0, 1.0), (0.85, 1.0, 1.0), (0.75, 0.8888888888888888, 1.0), (0.75, 0.8888888888888888, 1.0)], [(0.993103448275862, 0.993103448275862, 0.993103448275862), (0.85, 1.0, 1.0), (0.75, 0.8888888888888888, 1.0), (0.85, 1.0, 1.0), (0.6, 0.7777777777777778, 0.8823529411764706)], [(0.993103448275862, 0.993103448275862, 0.993103448275862), (0.75, 0.8888888888888888, 1.0), (0.85, 1.0, 1.0), (0.5, 0.6111111111111112, 0.7058823529411765), (0.6, 0.7777777777777778, 0.8823529411764706)], [(0.9827586206896551, 0.9827586206896551, 0.9827586206896551), (0.85, 1.0, 1.0), (0.75, 0.8888888888888888, 1.0), (0.75, 0.8888888888888888, 1.0), (0.75, 0.8888888888888888, 1.0)], [(0.9758620689655172, 0.9758620689655172, 0.9758620689655172), (0.75, 0.8888888888888888, 1.0), (0.85, 1.0, 1.0), (0.75, 0.8888888888888888, 1.0), (0.6, 0.7777777777777778, 0.8823529411764706)], [(0.9758620689655172, 0.9758620689655172, 0.9758620689655172), (0.75, 0.8888888888888888, 1.0), (0.5, 0.6111111111111112, 0.7058823529411765), (0.85, 1.0, 1.0), (0.75, 0.8888888888888888, 1.0)], [(0.9655172413793104, 0.9655172413793104, 0.9655172413793104), (0.85, 1.0, 1.0), (0.75, 0.8888888888888888, 1.0), (0.6, 0.7777777777777778, 0.8823529411764706), (0.75, 0.8888888888888888, 1.0)], [(0.9655172413793104, 0.9655172413793104, 0.9655172413793104), (0.75, 0.8888888888888888, 1.0), (0.85, 1.0, 1.0), (0.85, 1.0, 1.0), (0.6, 0.7777777777777778, 0.8823529411764706)], [(0.9655172413793104, 0.9655172413793104, 0.9655172413793104), (0.75, 0.8888888888888888, 1.0), (0.75, 0.8888888888888888, 1.0), (0.85, 1.0, 1.0), (0.75, 0.8888888888888888, 1.0)], [(0.9655172413793104, 0.9655172413793104, 0.9655172413793104), (0.5, 0.6111111111111112, 0.7058823529411765), (0.75, 0.8888888888888888, 1.0), (0.85, 1.0, 1.0), (0.6, 0.7777777777777778, 0.8823529411764706)], [(0.9586206896551724, 0.9586206896551724, 0.9586206896551724), (0.5, 0.6111111111111112, 0.7058823529411765), (0.6, 0.7777777777777778, 0.8823529411764706), (0.75, 0.8888888888888888, 1.0), (0.85, 1.0, 1.0)], [(0.9551724137931035, 0.9551724137931035, 0.9551724137931035), (0.85, 1.0, 1.0), (0.75, 0.8888888888888888, 1.0), (0.6, 0.7777777777777778, 0.8823529411764706), (0.85, 1.0, 1.0)], [(0.9482758620689655, 0.9482758620689655, 0.9482758620689655), (0.75, 0.8888888888888888, 1.0), (0.6, 0.7777777777777778, 0.8823529411764706), (0.5, 0.6111111111111112, 0.7058823529411765), (0.85, 1.0, 1.0)], [(0.9482758620689655, 0.9482758620689655, 0.9482758620689655), (0.5, 0.6111111111111112, 0.7058823529411765), (0.75, 0.8888888888888888, 1.0), (0.85, 1.0, 1.0), (0.75, 0.8888888888888888, 1.0)], [(0.9448275862068966, 0.9448275862068966, 0.9448275862068966), (0.85, 1.0, 1.0), (0.75, 0.8888888888888888, 1.0), (0.6, 0.7777777777777778, 0.8823529411764706), (0.75, 0.8888888888888888, 1.0)], [(0.9413793103448276, 0.9413793103448276, 0.9413793103448276), (0.75, 0.8888888888888888, 1.0), (0.85, 1.0, 1.0), (0.75, 0.8888888888888888, 1.0), (0.6, 0.7777777777777778, 0.8823529411764706)]]
D: [[(0.5, 0.5, 0.5), (0.10625, 0.125, 0.125), (0.10625, 0.125, 0.125), (0.09375, 0.1111111111111111, 0.125), (0.09375, 0.1111111111111111, 0.125)], [(0.496551724137931, 0.496551724137931, 0.496551724137931), (0.10625, 0.125, 0.125), (0.09375, 0.1111111111111111, 0.125), (0.10625, 0.125, 0.125), (0.075, 0.09722222222222222, 0.11029411764705882)], [(0.496551724137931, 0.496551724137931, 0.496551724137931), (0.09375, 0.1111111111111111, 0.125), (0.10625, 0.125, 0.125), (0.0625, 0.0763888888888889, 0.08823529411764706), (0.075, 0.09722222222222222, 0.11029411764705882)], [(0.49137931034482757, 0.49137931034482757, 0.49137931034482757), (0.10625, 0.125, 0.125), (0.09375, 0.1111111111111111, 0.125), (0.09375, 0.1111111111111111, 0.125), (0.09375, 0.1111111111111111, 0.125)], [(0.4879310344827586, 0.4879310344827586, 0.4879310344827586), (0.09375, 0.1111111111111111, 0.125), (0.10625, 0.125, 0.125), (0.09375, 0.1111111111111111, 0.125), (0.075, 0.09722222222222222, 0.11029411764705882)], [(0.4879310344827586, 0.4879310344827586, 0.4879310344827586), (0.09375, 0.1111111111111111, 0.125), (0.0625, 0.0763888888888889, 0.08823529411764706), (0.10625, 0.125, 0.125), (0.09375, 0.1111111111111111, 0.125)], [(0.4827586206896552, 0.4827586206896552, 0.4827586206896552), (0.10625, 0.125, 0.125), (0.09375, 0.1111111111111111, 0.125), (0.075, 0.09722222222222222, 0.11029411764705882), (0.09375, 0.1111111111111111, 0.125)], [(0.4827586206896552, 0.4827586206896552, 0.4827586206896552), (0.09375, 0.1111111111111111, 0.125), (0.10625, 0.125, 0.125), (0.10625, 0.125, 0.125), (0.075, 0.09722222222222222, 0.11029411764705882)], [(0.4827586206896552, 0.4827586206896552, 0.4827586206896552), (0.09375, 0.1111111111111111, 0.125), (0.09375, 0.1111111111111111, 0.125), (0.10625, 0.125, 0.125), (0.09375, 0.1111111111111111, 0.125)], [(0.4827586206896552, 0.4827586206896552, 0.4827586206896552), (0.0625, 0.0763888888888889, 0.08823529411764706), (0.09375, 0.1111111111111111, 0.125), (0.10625, 0.125, 0.125), (0.075, 0.09722222222222222, 0.11029411764705882)], [(0.4793103448275862, 0.4793103448275862, 0.4793103448275862), (0.0625, 0.0763888888888889, 0.08823529411764706), (0.075, 0.09722222222222222, 0.11029411764705882), (0.09375, 0.1111111111111111, 0.125), (0.10625, 0.125, 0.125)], [(0.47758620689655173, 0.47758620689655173, 0.47758620689655173), (0.10625, 0.125, 0.125), (0.09375, 0.1111111111111111, 0.125), (0.075, 0.09722222222222222, 0.11029411764705882), (0.10625, 0.125, 0.125)], [(0.47413793103448276, 0.47413793103448276, 0.47413793103448276), (0.09375, 0.1111111111111111, 0.125), (0.075, 0.09722222222222222, 0.11029411764705882), (0.0625, 0.0763888888888889, 0.08823529411764706), (0.10625, 0.125, 0.125)], [(0.47413793103448276, 0.47413793103448276, 0.47413793103448276), (0.0625, 0.0763888888888889, 0.08823529411764706), (0.09375, 0.1111111111111111, 0.125), (0.10625, 0.125, 0.125), (0.09375, 0.1111111111111111, 0.125)], [(0.4724137931034483, 0.4724137931034483, 0.4724137931034483), (0.10625, 0.125, 0.125), (0.09375, 0.1111111111111111, 0.125), (0.075, 0.09722222222222222, 0.11029411764705882), (0.09375, 0.1111111111111111, 0.125)], [(0.4706896551724138, 0.4706896551724138, 0.4706896551724138), (0.09375, 0.1111111111111111, 0.125), (0.10625, 0.125, 0.125), (0.09375, 0.1111111111111111, 0.125), (0.075, 0.09722222222222222, 0.11029411764705882)]]
Mp [0.5, 0.5, 0.5, 0.10625, 0.125, 0.125, 0.10625, 0.125, 0.125, 0.10625, 0.125, 0.125, 0.10625, 0.125, 0.125]
Ml [0.4706896551724138, 0.4706896551724138, 0.4706896551724138, 0.0625, 0.0763888888888889, 0.08823529411764706, 0.0625, 0.0763888888888889, 0.08823529411764706, 0.0625, 0.0763888888888889, 0.08823529411764706, 0.075, 0.09722222222222222, 0.11029411764705882]
dp: [0.02642541332005618, 0.04846909807166661, 0.08931964895784993, 0.035642707165647436, 0.055675063261347454, 0.08224371390676369, 0.05961986552111227, 0.05661605011114437, 0.044036907081143446, 0.09399001730109596, 0.09605474149749675, 0.06181194069490626, 0.09974401086893522, 0.09128849064772634, 0.07032587941863243, 0.0723879950331682]
dl [0.13464526323229192, 0.12960660126838533, 0.1056840804959267, 0.12141390387929181, 0.11656851776089829, 0.10399570774149292, 0.10694466329056837, 0.12340304309367657, 0.11787336572660864, 0.09797736893133582, 0.08245051590128073, 0.11111513038789449, 0.08130689098260824, 0.09979470710587426, 0.10492425446568421, 0.1126784089850549]
miu [('1号对象', 0.8359390182888572), ('4号对象', 0.7730582181258907), ('9号对象', 0.7280165963685844), ('2号对象', 0.7278174492572936), ('8号对象', 0.6854997483698679), ('5号对象', 0.6767655262917643), ('12号对象', 0.6425548625332956), ('7号对象', 0.6420614524205268), ('16号对象', 0.6088539385784991), ('15号对象', 0.5987114083173548), ('6号对象', 0.5583979311206502), ('3号对象', 0.5419592783787137), ('14号对象', 0.5222578870307493), ('10号对象', 0.5103854923185025), ('11号对象', 0.46189404784357574), ('13号对象', 0.44908304875099464)]
具体实现
由于numpy矩阵运算不支持这种特殊的三角模糊数计算,所以我这里主要用二维列表嵌套元组实现。
准备函数
由于后面不少地方需要找到矩阵每列的最值,所以我封装了两个方法。
def findMin(F):
'''
:param F:
:return: 返回矩阵每列的最小值
'''
columnMin = []
for column in range(0, F.shape[1]):
amin = F[0, column][0]
bmin = F[0, column][1]
cmin = F[0, column][2]
for row in range(0, F.shape[0]):
target = F[row, column]
if amin > target[0]:
amin = target[0]
if bmin > target[1]:
bmin = target[1]
if cmin > target[2]:
cmin = target[2]
columnMin.append([amin, bmin, cmin])
return columnMin
def findMax(F):
'''
:param F:
:return: 返回矩阵每列的最大值
'''
columnMax = []
for column in range(0, F.shape[1]):
amax = F[0, column][0]
bmax = F[0, column][1]
cmax = F[0, column][2]
for row in range(0, F.shape[0]):
target = F[row, column]
if amax < target[0]:
amax = target[0]
if bmax < target[1]:
bmax = target[1]
if cmax < target[2]:
cmax = target[2]
columnMax.append([amax, bmax, cmax])
return columnMax
Step1:指标数据的三角形模糊数表达
def toTriangle(array, targetMap):
'''
:param array: 存储原始数据的二维数组,行为每个比较对象,列为不同指标
:param targetMap: 一个定性指标到三角模糊数的映射关系
:return: 返回未归一化的模糊指标矩阵
'''
F = []
for targetList in array:
row = []
for target in targetList:
## 对于小数,需要截取
if str(target).split('.')[0].isdigit():
item = (target, target, target)
else:
item = targetMap[target]
row.append(item)
F.append(row)
return F
Step2: 模糊指标矩阵 F 归一化处理
def normalization(F, type):
'''
:param F: 原模糊指标矩阵
:param type: 0表示成本型,1表示收益型
:return: 归一化后的模糊指标矩阵,二维列表套元组形式
'''
R = []
for i in range(0, len(F)):
row = []
## 找最小值
if type == 0:
columnM = findMin(np.array(F))
## 找最大值
elif type == 1:
columnM = findMax(np.array(F))
for j in range(0, len(F[i])):
x = F[i][j]
## 无论最大最小均取出相应位置的最值
xM = columnM[j]
aM = xM[0]
bM = xM[1]
cM = xM[2]
if type == 0:
y = (aM/x[2], bM/x[1], min(cM/x[0], 1.0))
elif type == 1:
y = (x[0]/cM, x[1]/bM, min(x[2]/aM, 1.0))
row.append(y)
R.append(row)
return R
Step3: 构造模糊决策矩阵
def construction(R, W):
'''
:param R: 归一化的模糊指标矩阵
:param W: 三角模糊数的权重向量
:return: 模糊决策矩阵
'''
D = []
for i in range(0, len(R)):
for j in range(0, len(R[i])):
R[i][j] = (R[i][j][0] * W[0][j][0], R[i][j][1]*W[0][j][1], R[i][j][2]*W[0][j][2])
D = R
print("D:", D)
return D
Step4: 确定模糊正理想 M + 与模糊负理想 M −
def ideal(D):
'''
:param D: 模糊决策矩阵
:return: 模糊理想
'''
columnMin = findMin(np.array(D))
columnMax = findMax(np.array(D))
Mp = []
Ml = []
for i in range(0, len(columnMin)):
for j in range(0, len(columnMin[i])):
Mp.append(columnMax[i][j])
Ml.append(columnMin[i][j])
print("Mp", Mp)
print("Ml", Ml)
return Mp, Ml
Step5:确定评价对象i 与 M +、M- 之间的距离 di+、di-
def distance(D, Mp, Ml):
dp = []
dl = []
for i in range(0, len(D)):
sump = 0
suml = 0
for j in range(0, len(D[i])):
for k in range(0, 3):
residualp = D[i][j][k] - Mp[j*3+k]
residuall = D[i][j][k] - Ml[j*3+k]
sump = sump + residualp*residualp
suml = suml + residuall*residuall
dp.append(sqrt(sump))
dl.append(sqrt(suml))
print("dp:", dp)
print("dl", dl)
return dp, dl
Step6:模糊优选决策
def choose(dp, dl):
miu = {}
for i in range(0, len(dp)):
miu[str(i+1)+"号对象"] = dl[i] / (dp[i] + dl[i])
return sorted(miu.items(), key=lambda term: term[1], reverse=True)