一篇 2021 年徐泽水老师《 The two-person and zero-sum matrix game with probabilistic linguistic information 》的一区论文的独立重复实验。
基本思想是将概率语言标准化,之后解模糊为三角模糊数的形式,最后带入线性规划进行纳什均衡的求解。代码如下,关键步骤有注释。
'''
想到一个好方法,如果对矩阵转置,就可以很方便的获得按列的切片,而不用大费周折了。
drop 函数删除多行,使用的是 label 标签而不是直接 [].
reset_values 函数中的 drop 参数代表的是是否丢弃原标签。
而如何用新列替换旧列呢,不需要额外的 replace 函数,就是简单的新增列 remp 存储数据,然后 temp 赋值给指定的列,然后删掉 temp 即可,
这就是之前三步交换元素的方法,放在这里交换数列完全可行。
'''
from scipy import optimize as op
import numpy as np#scipy 包实现线性规划
np.set_printoptions(suppress=True)
import pandas as pd
def getdef(n):# 导入矩阵
df = pd.read_excel('D:\study\\test\data\\t14.xlsx',sheet_name=n)# 地址中包含 t 会被转义,加双斜杠即可
return df
def getmatrix(df,n):# 按照每个属性对矩阵进行分组
df= df.loc[:, n:n + 3]
return df.T.reset_index(drop=True).T# 使用转置消除列元素的索引成一个新的矩阵,不然切片形式会对后面的引用造成很大的困扰。
def getdivied(df,n):# 按照相通属性的方案进行分组
df= df[n::3]
# print(df)
return df.reset_index(drop=True).T
def nornal_index(df):# 矩阵下标的标准化
df=df.reset_index(drop=True)
return df.T.reset_index(drop=True).T
def getnormal(df):# 补全概率
df[4]=df[1]+(1-df[1]-df[3])/2# 补全概率,可以直接作用在整个一列,因为如果加起来已经等于一,就不会在变大了。
df[5]=df[3]+(1-df[1]-df[3])/2
df[1]=df[4]
df[3]=df[5]
return df.drop(labels=[4,5],axis=1)
def gettrangle(df):# 解模糊方法
df1=pd.Series(1.25*(df[0]-1)*df[1])
df2=pd.Series(1.25*(df[0])*df[1])
df3=pd.Series(1.25*(df[0]+1)*df[1])
df4 = pd.Series(1.25 * (df[2] - 1) * df[3])
df5 = pd.Series(1.25 * (df[2]) * df[3])
df6 = pd.Series(1.25 * (df[2] + 1) * df[3])
d1=df1+df4
d2=df2+df5
d3=df3+df6
return pd.concat((d1,d2,d3),axis=1)
def getnashy(df):# 对 y 求解纳什均衡
c=np.array([0,0,0,0,1,0,0])
A_ub=np.array(df)
B_ub=np.array([0,0,0,0,0,0,0,0,0])
A_eq=np.array([[1,1,1,1,0,0,0]])
B_eq=np.array([1])
x1=(0,1)
x2=(0,1)
x3=(0,1)
x4=(0,1)
x5=(None,None)
x6=(0,None)
x7=(0,None)
res=op.linprog(c,A_ub,B_ub,A_eq,B_eq,bounds=(x1,x2,x3,x4,x5,x6,x7))
return res.x
def getnashx(df):# 对 x 求解纳什均衡
c = np.array([0, 0, 0, 1, 0, 0])
A_ub = np.array(df)
B_ub = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
A_eq = np.array([[1, 1, 1, 0, 0, 0]])
B_eq = np.array([1])
x1 = (0, 1)
x2 = (0, 1)
x3 = (0, 1)
x5 = (None, None)
x6 = (0, None)
x7 = (0, None)
res = op.linprog(-c, A_ub, B_ub, A_eq, B_eq, bounds=(x1, x2, x3, x5, x6, x7))
return res.x
if __name__ == '__main__':
df = getdef(0)
print(' 总方案矩阵为 \n',df)
df4=getmatrix(df,13)
df3=getmatrix(df,9)
df2=getmatrix(df,5)
df1=getmatrix(df,1)
df5=getnormal(df4)# 对需要更新数据的分组调用更新函数
dfsum=pd.concat((gettrangle(df1),gettrangle(df2),gettrangle(df3),gettrangle(df5)),axis=1)# 再将分组的拼接起来。
print(' 解模糊矩阵为 \n',dfsum)
dfliner_valuesy=nornal_index(getdivied(dfsum.T,0).append(getdivied(dfsum.T,1)).append(getdivied(dfsum.T,2)))
# y 因为线性规划等式右边的不能从姐模糊矩阵获得 ,外汇跟单gendan5.com 因此单独列出来再做拼接
df_valuesy=pd.DataFrame([[-1,1,0],[-1,1,0],[-1,1,0],[-1,0,0],[-1,0,0],[-1,0,0],[-1,0,-1],[-1,0,-1],[-1,0,-1]])
dfy=nornal_index(pd.concat((dfliner_valuesy,df_valuesy),axis=1))# 每次对拼接好的新矩阵使用索引重置方法。
print(' 供线性规划使用的矩阵为 \n',dfy)
print('y 的纳什均衡解为 ',getnashy(dfy))
tempx=nornal_index((getdivied(dfsum.T,0).T).append(getdivied(dfsum.T,1).T).append(getdivied(dfsum.T,2).T))
dfliner_valuesx=tempx.applymap(lambda x:-x)# 匿名函数将矩阵每一个元素变号,因为大于零的约束需要化为小于零的形式。
print(dfliner_valuesx)
df_valuesx=pd.DataFrame([[1,-1,0],[1,-1,0],[1,-1,0],[1,-1,0],[1,0,0],[1,0,0],[1,0,0],[1,0,0],[1,0,1],[1,0,1],[1,0,1],[1,0,1]])
dfx=nornal_index(pd.concat((dfliner_valuesx,df_valuesx),axis=1))# 每次对拼接好的新矩阵使用索引重置方法。
print(' 供线性规划使用的矩阵为 \n',dfx)
print('x 的纳什均衡解为 ',getnashx(dfx))```





最后的三角模糊数还原概率语言术语没有实现,这个地方没看太懂算出来不对,回头再补充。
github 仓库在
https://github.com/rivendelltom/decision-making-study