In [1]:
import pandas as pd
import numpy as np
import os.path as ospath

In [2]:
excelfile = ospath.join('..','Serious games','Games','БД4_Лёгкая.xlsm')

Alldata = pd.read_excel(excelfile,sheet_name='Данные')
Games = pd.read_excel(excelfile,sheet_name='Игры')
print(Alldata.columns)
Games.columns


Index(['Game', 'Time', 'Subject', 'Group', 'GrSubject', 'Type', 'Gain',
       'Penalty', 'x', 's1', 's2', 's3', 'AcceptAdvice', 'CalcCount',
       'CalcAdviceCount', 'UseHelp'],
      dtype='object')
Out[2]:
Index(['Session', 'Game', 'Date', 'Place', 'GamersCount', 'R',
       'Parametr1_alfa', 'Parametr2_beta', 'Mechname', 'GameMech',
       'Cooperation', 'talks', 'Name', 'Datafile', 'Sbjfile', 'стимул',
       'Group', 'Курс балла'],
      dtype='object')

In [3]:
YHGames=Games[(Games.Mechname=='yh') & (Games.GameMech=='agree')]
YHExpGames=Games[(Games.Mechname=='yh') & (Games.GameMech=='exp')]

YHData=Alldata[Alldata.Game.isin(YHGames.Game)]
YHEData=Alldata[Alldata.Game.isin(YHExpGames.Game)]

In [4]:
print(YHData.shape,YHEData.shape)


(1035, 16) (75, 16)

In [85]:
GLGames=Games[(Games.Mechname=='gl') & (Games.GameMech=='agree')]
GLData=Alldata[Alldata.Game.isin(GLGames.Game)]

GLEGames=Games[(Games.Mechname=='gl') & (Games.GameMech=='exp')]
GLEData=Alldata[Alldata.Game.isin(GLEGames.Game)]

In [86]:
GLData.shape


Out[86]:
(2847, 16)

Нэш-торги


In [5]:
YHg=YHData.groupby(['Game','Time'])

In [53]:
YHg.sum();

Функции расчёта выигрышей в игре


In [6]:
class Game:
    import numpy as np
    def __init__(self,R,s0,types):
        self.R = R
        self.s0 = np.array(s0)
        self.n = len(s0)
        self.types = np.array(types)
    def u(self,x):
        return self.np.sqrt(self.types+x)
game = Game( 115,(115/3,115/3,115/3), (1,9,25))

class Mechanism:
    def __init__(self,game,params,xfunc,tfunc):
        self.game = game
        for k,v in params.items():
            setattr(self,k,v)
        self.xfunc = xfunc
        self.tfunc = tfunc
        
    def x(self,s):
        return self.xfunc(s,self.game)
    def t(self,s):
        return self.tfunc(s,self.game,self)
    def f(self,s):
        return game.u(self.x(s))-self.t(s)

YHMechanism = Mechanism(game,
                        {'beta':0.0005}, 
                        lambda s,g: s*g.R/s.sum(),
                        lambda s,g,m: m.beta*s*(np.repeat(s.sum(),3)-s))

class GLClass:
    from scipy.spatial import distance
    def __init__(self):
        self.glx = lambda s,g: s.sum(axis=0) / g.n
    def glt(self,s,g,m):
        p = m.beta * self.distance.cdist([self.glx(s,g)],s,'sqeuclidean')
        pmean = m.alfa * p.mean()
        return p - pmean
GL = GLClass()
    
GLMechanism = Mechanism(game,{'beta':0.0005,'alfa':1},
                        GL.glx,
                        GL.glt
                        )
def Unash(f,f0):
    df = f-f0
    return (np.fabs(df)).prod() * np.min(np.sign(df))

In [7]:
print(YHMechanism.beta)
s = np.array([1.2,40,80])
print(YHMechanism.t(s))
YHMechanism.f(s)


0.0005
[0.072 1.624 1.648]
Out[7]:
array([1.39040003, 5.22828395, 8.39727704])

In [8]:
print(YHMechanism.game.s0)

f0 = YHMechanism.game.u([0,0,0])
print(f0)

Unash(f0,s)


[38.33333333 38.33333333 38.33333333]
[1. 3. 5.]
Out[8]:
-1056.000000000001

Цикл получения исходных данных для Нэш-торгов


In [9]:
import itertools
res = []
for name,group in YHg:
    group = group.sort_values(by='GrSubject')
    if name[1] == 1 :
        curname = name[0]
        prevg = group
        continue
    
    fprev = prevg['Gain'].values
    sprev = prevg['s2'].values
    s = group['s2'].values
    s1, s2, s3 = sprev.copy(), sprev.copy(), sprev.copy()
    s1[0] = s[0]
    s2[1] = s[1]
    s3[2] = s[2]
    f1 = YHMechanism.f(s1)
    f2 = YHMechanism.f(s2)
    f3 = YHMechanism.f(s3)
    U = Unash(fprev,f0)
    U1 = Unash(f1,f0)
    U2 = Unash(f2,f0)
    U3 = Unash(f3,f0)
    Unew = Unash(YHMechanism.f(s),f0)
    res.append( [a for a in itertools.chain(name,[U1>U,U2>U,U3>U,Unew>U,U,U1,U2,U3,Unew],s)] )
    prevg = group
    #print(name,prev['Gain'])

In [10]:
a = np.vstack(res)
data_a = pd.DataFrame(a)
data_a.columns = ['Game','Step','U1>U','U2>U','U3>U','Unew>U','U','U1','U2','U3','Unew','s1','s2','s3']
data_a.head()


Out[10]:
Game Step U1>U U2>U U3>U Unew>U U U1 U2 U3 Unew s1 s2 s3
0 40.0 2.0 0.0 1.0 1.0 0.0 -0.166445 -0.182068 -0.166445 -0.166445 -0.182068 1.1 99.0 115.0
1 40.0 3.0 1.0 0.0 0.0 1.0 -0.182068 -0.166445 -0.182068 -0.182068 -0.166445 1.0 99.0 115.0
2 40.0 4.0 0.0 1.0 1.0 1.0 -0.166445 -0.182068 0.663205 0.141136 4.637448 1.1 40.0 61.5
3 40.0 5.0 0.0 0.0 1.0 0.0 4.637448 -2.334728 4.523720 4.758127 -2.365943 115.0 41.0 60.5
4 40.0 6.0 1.0 0.0 1.0 1.0 -2.365943 4.312664 -42.795611 -2.119715 0.061842 1.0 91.0 80.0

In [12]:
pda = data_a[['U1>U','U2>U','U3>U','Unew>U']]
pdaPar = data_a[data_a['U']>0][['U1>U','U2>U','U3>U','Unew>U']]

In [41]:
pda.head()


Out[41]:
U1>U U2>U U3>U Unew>U
0 0.0 1.0 1.0 0.0
1 1.0 0.0 0.0 1.0
2 0.0 1.0 1.0 1.0
3 0.0 0.0 1.0 0.0
4 1.0 0.0 1.0 1.0

YH

Игры с механизмом YH и механизмом остановки "по договорённости" - никто не поменял заявок. Всего шагов 345, если брать для каждого игрока в отдельности, то 1035 = 345 * 3

Функция Нэша: $ U(f,f^0)=\prod_{i} (f_i -f_i^0)') $

Базовые выигрыши: $ f^0 = u(0,0,0) $

Определения для текущего шага $t>1$: $$ U_{prev} = U(f(s^{t-1}),f^0)') $$ $$ U_i =U(f(s_i^t,s_{-i}^{t-1}),f^0) $$ $$ U_{new}=U(f(s^t),f^0) $$


In [13]:
def Nash_stat(data):
    a = (data[data>0].count()).values
    return [a[0],a[1],a[2],data[(data['U1>U']*data['U2>U']*data['U3>U']==1)].shape[0],
                data[data['U1>U']*data['U2>U']*data['U3>U']*data['Unew>U']==1].shape[0],
                data[data['Unew>U']==1].shape[0],
                data[(data['Unew>U']==1) & (data['U1>U']*data['U2>U']*data['U3>U']==0)].shape[0],
                data[(data['Unew>U']==1) & (data['U1>U']+data['U2>U']+data['U3>U']==0)].shape[0]
            ]

In [14]:
pd.DataFrame({'Критерии':['U1 > Uprev','U2 > Uprev','U3 > Uprev','U1>Uprev & U2>Uprev & U3>Uprev',
                          'U1>Uprev & U2>Uprev & U3>Uprev & Unew > Uprev','Unew > Uprev',
                          'Unew > Uprev & Exist Ui < Uprev','Unew > Uprev & All Ui < Uprev'],
              'Число подходящих ходов':Nash_stat(pda),
              'Число подх. ходов Uprev>0':Nash_stat(pdaPar)
             })


Out[14]:
Критерии Число подходящих ходов Число подх. ходов Uprev>0
0 U1 > Uprev 172 148
1 U2 > Uprev 181 155
2 U3 > Uprev 189 162
3 U1>Uprev & U2>Uprev & U3>Uprev 64 58
4 U1>Uprev & U2>Uprev & U3>Uprev & Unew > Uprev 64 58
5 Unew > Uprev 167 127
6 Unew > Uprev & Exist Ui < Uprev 103 69
7 Unew > Uprev & All Ui < Uprev 1 0

In [11]:
datafile = ospath.join('..','Serious games','data.csv')

brdata = pd.read_csv(datafile,header=None)

brdata.columns=['game','time','g1','g2','g3','br1','br2','br3']

jdata=pd.concat([data_a, brdata], axis=1, join='inner')

In [16]:
def BR_stat(data):
    return [data[(data['g1']>0)&(data['g1']<=1)].shape[0],
            data[(data['g2']>0)&(data['g2']<=1)].shape[0],
            data[(data['g3']>0)&(data['g3']<=1)].shape[0],
            data[(data['g1']>0)&(data['g1']<=1)&(data['g3']>0)&(data['g3']<=1)|
                 (data['g1']>0)&(data['g1']<=1)&(data['g2']>0)&(data['g2']<=1)|
                 (data['g2']>0)&(data['g2']<=1)&(data['g3']>0)&(data['g3']<=1)].shape[0],
            data[(data['g1']>0)&(data['g1']<=1)& (data['g2']>0)&(data['g2']<=1)& (data['g3']>0)&(data['g3']<=1)].shape[0],
            data[(data['g1']>0)].shape[0],
            data[(data['g2']>0)].shape[0],
            data[(data['g3']>0)].shape[0],
            data[(data['g1']>0)&(data['g2']>0)|
                 (data['g1']>0)&(data['g3']>0)|
                 (data['g2']>0)&(data['g3']>0)].shape[0],
            data[(data['g1']>0)& (data['g2']>0)& (data['g3']>0)].shape[0],

            data[data['g1']==1].shape[0],
            data[data['g2']==1].shape[0],
            data[data['g3']==1].shape[0],
            data[(data['g1']>=0.9)&(data['g1']<=1.1)].shape[0],
            data[(data['g2']>=0.9)&(data['g2']<=1.1)].shape[0],
            data[(data['g3']>=0.9)&(data['g3']<=1.1)].shape[0],
            data[(data['g1']>=0.8)&(data['g1']<=1.2)].shape[0],
            data[(data['g2']>=0.8)&(data['g2']<=1.2)].shape[0],
            data[(data['g3']>=0.8)&(data['g3']<=1.2)].shape[0],
                                       ]

In [24]:
pd.DataFrame({'Критерии':['IB1','IB2','IB3','IB1&IB2|IB1&IB3|IB2&IB3','IB1&IB2&IB3','IB1+','IB2+','IB3+',
                          'IB1+&IB2+|IB1+&IB3+|IB2+&IB3+','IB1+&IB2+&IB3+',
                          'BR1(0)','BR2(0)','BR3(0)',
                          'BR1(0.1)','BR2(0.1)','BR3(0.1)','BR1(0.2)','BR2(0.2)','BR3(0.2)'],
              'Число подходящих ходов':BR_stat(jdata),
             })


Out[24]:
Критерии Число подходящих ходов
0 IB1 117
1 IB2 103
2 IB3 76
3 IB1&IB2|IB1&IB3|IB2&IB3 71
4 IB1&IB2&IB3 9
5 IB1+ 176
6 IB2+ 150
7 IB3+ 116
8 IB1+&IB2+|IB1+&IB3+|IB2+&IB3+ 133
9 IB1+&IB2+&IB3+ 29
10 BR1(0) 0
11 BR2(0) 0
12 BR3(0) 0
13 BR1(0.1) 11
14 BR2(0.1) 16
15 BR3(0.1) 9
16 BR1(0.2) 16
17 BR2(0.2) 31
18 BR3(0.2) 12

In [65]:
pd.DataFrame([['Шагов одного игрока',len(YHg.groups)],['Всего шагов',YHData.shape[0]]])


Out[65]:
0 1
0 Шагов одного игрока 345
1 Всего шагов 1035

In [17]:
jdata.head()


Out[17]:
Game Step U1>U U2>U U3>U Unew>U U U1 U2 U3 ... s2 s3 game time g1 g2 g3 br1 br2 br3
0 40.0 2.0 0.0 1.0 1.0 0.0 -0.166445 -0.182068 -0.166445 -0.166445 ... 99.0 115.0 40.0 2.0 0.013325 0.000000 0.000000 8.504692 27.598804 27.605742
1 40.0 3.0 1.0 0.0 0.0 1.0 -0.182068 -0.166445 -0.182068 -0.182068 ... 99.0 115.0 40.0 3.0 -0.013505 0.000000 0.000000 8.504692 27.551742 27.545459
2 40.0 4.0 0.0 1.0 1.0 1.0 -0.166445 -0.182068 0.663205 0.141136 ... 40.0 61.5 40.0 4.0 0.013325 0.826317 0.612168 8.504692 27.598804 27.605742
3 40.0 5.0 0.0 0.0 1.0 0.0 4.637448 -2.334728 4.523720 4.758127 ... 41.0 60.5 40.0 5.0 2.953944 0.057762 -0.177184 39.658624 57.312411 67.143850
4 40.0 6.0 1.0 0.0 1.0 1.0 -2.365943 4.312664 -42.795611 -2.119715 ... 91.0 80.0 40.0 6.0 1.513113 -1.400802 -0.322314 39.658624 5.306160 0.000000

5 rows × 22 columns


In [12]:
def BRNash_stat(data):
    return pd.DataFrame.from_dict(dict([
        ("BR1(0.1) & U1<=Uprev", data[(data['U']>0) & (data['g1']>=0.9)&(data['g1']<=1.1) & (data['U1>U']==0)].shape[0]),
        ("BR2(0.1) & U2<=Uprev", data[(data['U']>0) & (data['g2']>=0.9)&(data['g2']<=1.1) & (data['U2>U']==0)].shape[0]),
        ("BR3(0.1) & U3<=Uprev", data[(data['U']>0) & (data['g3']>=0.9)&(data['g3']<=1.1) & (data['U3>U']==0)].shape[0]),
        ("BR1(0.2) & U1<=Uprev", data[(data['U']>0) & (data['g1']>=0.8)&(data['g1']<=1.2) & (data['U1>U']==0)].shape[0]),
        ("BR2(0.2) & U2<=Uprev", data[(data['U']>0) & (data['g2']>=0.8)&(data['g2']<=1.2) & (data['U2>U']==0)].shape[0]),
        ("BR3(0.2) & U3<=Uprev", data[(data['U']>0) & (data['g3']>=0.8)&(data['g3']<=1.2) & (data['U3>U']==0)].shape[0]),
        ("IB1 & U1<=Uprev", data[(data['U']>0) & (data['g1']>0)&(data['g1']<=1) & (data['U1>U']==0)].shape[0]),
        ("IB2 & U2<=Uprev", data[(data['U']>0) & (data['g2']>0)&(data['g2']<=1) & (data['U2>U']==0)].shape[0]),
        ("IB3 & U3<=Uprev", data[(data['U']>0) & (data['g3']>0)&(data['g3']<=1) & (data['U3>U']==0)].shape[0]),
        ("IB1+ & U1<=Uprev", data[(data['U']>0) & (data['g1']>0) & (data['U1>U']==0)].shape[0]),
        ("IB2+ & U2<=Uprev", data[(data['U']>0) & (data['g2']>0) & (data['U2>U']==0)].shape[0]),
        ("IB3+ & U3<=Uprev", data[(data['U']>0) & (data['g3']>0) & (data['U3>U']==0)].shape[0]),
        ("not BR1(0.1) & U1>Uprev", data[(data['U']>0) & ((data['g1']<0.9)|(data['g1']>1.1)) & (data['U1>U']==1)].shape[0]),
        ("not BR2(0.1) & U2>Uprev", data[(data['U']>0) & ((data['g2']<0.9)|(data['g2']>1.1)) & (data['U2>U']==1)].shape[0]),
        ("not BR3(0.1) & U3>Uprev", data[(data['U']>0) & ((data['g3']<0.9)|(data['g3']>1.1)) & (data['U3>U']==1)].shape[0]),
        ("not IB1 & U1>Uprev", data[(data['U']>0) & ((data['g1']<=0)|(data['g1']>1)) & (data['U1>U']==1)].shape[0]),
        ("not IB2 & U2>Uprev", data[(data['U']>0) & ((data['g2']<=0)|(data['g2']>1)) & (data['U2>U']==1)].shape[0]),
        ("not IB3 & U3>Uprev", data[(data['U']>0) & ((data['g3']<=0)|(data['g3']>1)) & (data['U3>U']==1)].shape[0]),
        ("not IB1+ & U1>Uprev", data[(data['U']>0) & (data['g1']<=0) & (data['U1>U']==1)].shape[0]),
        ("not IB2+ & U2>Uprev", data[(data['U']>0) & (data['g2']<=0) & (data['U2>U']==1)].shape[0]),
        ("not IB3+ & U3>Uprev", data[(data['U']>0) & (data['g3']<=0) & (data['U3>U']==1)].shape[0]),
    ]),orient='index',columns=['Число подходящих'])

In [13]:
BRNash_stat(jdata)


Out[13]:
Число подходящих
BR1(0.1) & U1<=Uprev 3
BR2(0.1) & U2<=Uprev 10
BR3(0.1) & U3<=Uprev 1
BR1(0.2) & U1<=Uprev 4
BR2(0.2) & U2<=Uprev 13
BR3(0.2) & U3<=Uprev 2
IB1 & U1<=Uprev 59
IB2 & U2<=Uprev 48
IB3 & U3<=Uprev 37
IB1+ & U1<=Uprev 83
IB2+ & U2<=Uprev 70
IB3+ & U3<=Uprev 56
not BR1(0.1) & U1>Uprev 143
not BR2(0.1) & U2>Uprev 154
not BR3(0.1) & U3>Uprev 156
not IB1 & U1>Uprev 107
not IB2 & U2>Uprev 123
not IB3 & U3>Uprev 138
not IB1+ & U1>Uprev 89
not IB2+ & U2>Uprev 108
not IB3+ & U3>Uprev 121

In [ ]: