Physik der sozio-ökonomischen Systeme mit dem Computer

(Physics of Socio-Economic Systems with the Computer)

Vorlesung gehalten an der J.W.Goethe-Universität in Frankfurt am Main

(Wintersemester 2020/21)

von Dr.phil.nat. Dr.rer.pol. Matthias Hanauske

Frankfurt am Main 02.11.2020

Erster Vorlesungsteil:

Klassifizierung evolutionärer Bi-Matrix Spiele ( unsymmetrische ($2\times2$)-Spiele )

Einführung

In diesem Unterkapitel werden die unterschiedlichen Spieltypen evolutionärer Bi-Matrix Spiele ( unsymmetrische ($2\times2$)-Spiele ) klassifiziert. Ausgangspunkt sind die folgenden allgemeinen Auszahlunsmatrizen der Spielergruppen A und B. Da es sich um unsymmetrische Auszahlungmatrizen nehmen wir das folgende an: $\hat{\bf {\cal \$}}^B \neq \left( \hat{\bf {\cal \$}}^A \right)^{\!T}$.

$$ \begin{equation} \hat{\bf {\cal \$}}^A = \left( \begin{array}{rrr} \$^A_{11} & \$^A_{12} \\ \$^A_{21} & \$^A_{22} \\ \end{array} \right) \quad , \quad \hat{\bf {\cal \$}}^B = \left( \begin{array}{rrr} \$^B_{11} & \$^B_{12} \\ \$^B_{21} & \$^B_{22} \\ \end{array} \right) \end{equation} $$

Unsymmetrische ($2 \times 2$) Spiele lassen sich in die folgenden Spielklassen gliedern:

Die Klasse der Eckenspiele (engl.: corner class games )

Ein Eckenspiel liegt vor, falls eine der Auszahlungmatrizen der Spielergruppen eine dominante Struktur hat; falls ${\cal \$}^A$ oder ${\cal \$}^B$ ein dominantes Spiel ist.

Die Klasse der Sattelpunktspiele (engl.: saddle class games )

Ein Sattelpunktspiel liegt vor, falls beide Spielergruppen gleichzeitig ein Koordinationsspiel oder Anti-Koordinationsspiel spielen.

Die Klasse der Zentrumsspiele (engl.: center class games )

Ein Zentrumsspiel liegt vor, falls Spielergruppe A ein Koordinationsspiel und Spielergruppe B ein Anti-Koordinationsspiel spielen; falls Spielergruppe A ein Anti-Koordinationsspiel und Spielergruppe B ein Koordinationsspiel spielen.

Die beiden Komponenten der zweidimensionalen gruppenspezifischen Populationsvektoren lassen sich, aufgrund ihrer Normalisierungsbedingung, auf eine Komponente reduzieren ($x^A_2=1-x^A_1$ und $x^B_2=1-x^B_1$). Das zeitliche Verhalten der Komponenten der Populationsvektoren (Gruppe A: $x(t):=x^A_1(t)$ und Gruppe B: $y(t):=x^B_1(t)$) wird in der Reproduktionsdynamik mittels des folgenden Systems von Differentialgleichungen beschrieben:

$$ \begin{eqnarray} \frac{d x(t)}{dt} &=& \left[ \left( \$^A_{11} + \$^A_{22} - \$^A_{12} - \$^A_{21} \right) \,y(t) + \left( \$^A_{12} - \$^A_{22}\right) \right] \,\left( x(t) - \left( x(t) \right)^2 \right) \, =: \, g_A(x,y) \qquad \hbox{(2)}\\ \frac{d y(t)}{dt} &=& \left[ \left( \$^B_{11} + \$^B_{22} - \$^B_{12} - \$^B_{21} \right) \,x(t) + \left( \$^B_{12} - \$^B_{22}\right) \right] \,\left( y(t) - \left( y(t) \right)^2 \right) \, =: \, g_B(x,y) \end{eqnarray} $$
In [1]:
import numpy as np
import matplotlib.pyplot as plt 
import matplotlib
from scipy import integrate

Definition der Funktion $g_A(x,y)$ und $g_B(x,y)$.

In [2]:
def gA(x,y,Aa,Ab,Ac,Ad):
  g=((Aa+Ad-Ac-Ab)*y + (Ab-Ad))*(x-x*x)
  return g
def gB(x,y,Ba,Bb,Bc,Bd):
  g=((Ba+Bd-Bc-Bb)*x + (Bb-Bd))*(y-y*y)
  return g

Definition des Systems der gekoppelten Differentialgleichung des evolutionären Bi-Matrix Spiels.

In [3]:
def DGLsys(vx,t):
  x, y = vx
  dxdt = gA(x,y,Aa,Ab,Ac,Ad)
  dydt = gB(x,y,Ba,Bb,Bc,Bd)
  return np.array([dxdt,dydt])

Beispiel I eines Eckenspiels

Wir betrachten die zeitliche Entwicklung eines Eckenspiels mit den folgenden Auszahlungswerten der beiden Spielergruppen:

$$ \begin{equation} \hat{\bf {\cal \$}}^A = \left( \begin{array}{rr} 10 & 4 \\ 12 & 5 \\ \end{array} \right) \quad , \quad \hat{\bf {\cal \$}}^B = \left( \begin{array}{rr} 10 & 7 \\ 12 & 5 \\ \end{array} \right) \end{equation} $$

Es handelt sich hierbei um eine Kombination von einem dominanten Spiel (Spielergruppe A: dominante Strategie 2 (x=0)) mit einem Anti-Koordinationsspiel (Spielergruppe B: zwei unsymmetrische Nash-Gleichgewichte).

Im folgenden wir das evolutionäre Eckenspiel für die Anfangsbedingung $(x_0,y_0)=(0.9,0.2)$ berechnet:

In [4]:
Aa,Ab,Ac,Ad = 10,4,12,5
Ba,Bb,Bc,Bd = 10,7,12,5
tval = np.linspace(0, 7, 1001)
x0 = 0.9
y0 = 0.2
initialval = np.array([x0,y0])
Loes = integrate.odeint(DGLsys, initialval, tval)
In [5]:
params = {
    'figure.figsize'    : [8,5],
    'text.usetex'       : True,
    'axes.titlesize' : 14,
    'axes.labelsize' : 16,  
    'xtick.labelsize' : 14 ,
    'ytick.labelsize' : 14 
}
matplotlib.rcParams.update(params) 
In [6]:
plt.xlabel(r"$\rm t$")
plt.ylabel(r"$\rm x,y(t)$")
plt.plot(tval, Loes[:, 0],c="red", label=r"$\rm x(t)$");
plt.plot(tval, Loes[:, 1],c="blue", label=r"$\rm y(t)$");
plt.legend(loc='upper center',fontsize=16);

Die obere Grafik zeigt, dass sich die Population nach einiger Zeit zu einem Zustand entwickelt in dem die Spielergruppe A ausschließlich die Strategie 2 (x=0) und die Spielergruppe B ausschließlich die Strategie 1 (y=1) spielt.

Man kann zeigen, dass unabhängig von der gewählten Anfangszusammensetzung $(x_0,y_0)$ der Population entwickelt sich die Entscheidungswahl der Population in einem evolutionären Eckenspiel stehts zu einem stabilen Zustand einer reinen Strategienwahl.

Im folgenden werden wir die zeitliche Entwicklung des evolutionären Eckenspiels für zwei weiter Anfangsbedingungen ($(x_0,y_0)=(0.95,0.8)$ und $(x_0,y_0)=(0.7,0.9)$) berechnet und die simulierten Trajektorien der Populationen in einem x-y Diagramm verdeutlichen. Zusätzlich wird im Hintergrund der Abbildung das zugrundeliegende Feldlinienbild der Populationsdynamik veranschaulicht.

In [7]:
x0a = 0.95
y0a = 0.8
initialval = np.array([x0a,y0a])
Loesa = integrate.odeint(DGLsys, initialval, tval)
x0b = 0.7
y0b = 0.9
initialval = np.array([x0b,y0b])
Loesb = integrate.odeint(DGLsys, initialval, tval)

Das Feldlinienbild der Populationsdynamik eines Bi-Matrix Spiels beschreibt die Richtung und Stärke der zeitlichen Entwicklung einer Population die aus zwei Spielergruppen besteht. Sie ordnet jeder möglichen Strategienwahl der Population (jedem (x,y)-Wert) einen Vektor $\vec{v}(x,y)$ zu. Die Richtung und Länge dieses Vektors sind wie folgt definiert:

$$ \begin{equation} \vec{v}(x,y) = \left( \begin{array}{r} \frac{d x(t)}{dt} \\ \frac{d y(t)}{dt} \\ \end{array} \right) = \left( \begin{array}{r} g_A(x,y) \\ g_B(x,y) \\ \end{array} \right) \,\, , \quad \left| \vec{v} \right| = \sqrt{g_A^2 + g_B^2} \end{equation} $$

$\vec{v}(x,y)$ beschreibt somit in welche Richtung und wie schnell sich die Strategienwahl der Population im Laufe der Zeit verändert.

In [8]:
SY,SX=np.mgrid[0:1:100j,0:1:100j]
SgA=gA(SX,SY,Aa,Ab,Ac,Ad)
SgB=gB(SX,SY,Ba,Bb,Bc,Bd)
speed=np.sqrt(SgA*SgA + SgB*SgB)
colorspeed = speed/speed.max()
In [9]:
plt.cla()
plt.xlabel(r"$\rm x$")
plt.ylabel(r"$\rm y$")
figure=plt.streamplot(SX,SY,SgA,SgB,density=[2, 2], linewidth=1,color=colorspeed, cmap=plt.cm.cool)
plt.plot(Loes[:, 0], Loes[:, 1],c="black")
plt.scatter(x0, y0, s=40, marker='o', c="black")
plt.plot(Loesa[:, 0], Loesa[:, 1],c="green")
plt.scatter(x0a, y0a, s=40, marker='o', c="green")
plt.plot(Loesb[:, 0], Loesb[:, 1],c="blue")
plt.scatter(x0b, y0b, s=40, marker='o', c="blue")
cbar=plt.colorbar(figure.lines, aspect=20)
cbar.set_label(r'$\left| \vec{v} \right| =\sqrt{{g_A}^2 + {g_B}^2}$',size=20)

Aufgrund der Dominanz der Strategie x=0 für Spielergruppe A verlaufen die Richtungspfeile der Feldlinien nie in positive x-Richtung. Die y-Komponente der Feldlinien kann dagegen in positive oder negative y-Richtung zeigen (Anti-Koordinationsspiel für Spielergruppe B). Unabhangig von der Anfangsbedingen landet die Population stehts in der "unsymmetrischen Ecke" (x=0,y=1).

Eine weitere Darstellungsmöglichkeit in einem (x,y,t)-Diagramm:

In [10]:
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot(Loes[:, 0], Loes[:, 1], zs=tval, c="black")
ax.scatter(x0, y0, zs=0, s=40, marker='o', c="black")
ax.plot(Loesa[:, 0], Loesa[:, 1], zs=tval, c="green")
ax.scatter(x0a, y0a, zs=0, s=40, marker='o', c="green")
ax.plot(Loesb[:, 0], Loesb[:, 1], zs=tval, c="blue")
ax.scatter(x0b, y0b, zs=0, s=40, marker='o', c="blue")
#ax.view_init(azim=-65, elev=35)
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
ax.set_xlabel(r"$\rm x$")
ax.set_ylabel(r"$\rm y$")
ax.set_zlabel(r"$\rm t$");

Die zeitliche Entwickling kann auch wie folgt in einer Animation verdeutlicht werden:

In [11]:
import matplotlib.animation as animation
from IPython.display import HTML

fig = plt.figure()
ax = fig.gca(projection='3d')

def init():   
    ax.plot(Loes[:, 0], Loes[:, 1], zs=tval, c="black")
    ax.scatter(x0, y0, zs=0, s=40, marker='o', c="black")
    ax.plot(Loesa[:, 0], Loesa[:, 1], zs=tval, c="green")
    ax.scatter(x0a, y0a, zs=0, s=40, marker='o', c="green")
    ax.plot(Loesb[:, 0], Loesb[:, 1], zs=tval, c="blue")
    ax.scatter(x0b, y0b, zs=0, s=40, marker='o', c="blue")
    return fig,

def animate(i):
    ax.scatter(Loes[50*i, 0], Loes[50*i, 1], zs=tval[50*i], s=20, marker='o', c="black")
    ax.scatter(Loesa[50*i, 0], Loesa[50*i, 1], zs=tval[50*i], s=20, marker='o', c="green")
    ax.scatter(Loesb[50*i, 0], Loesb[50*i, 1], zs=tval[50*i], s=20, marker='o', c="blue")
    return fig,

ani = animation.FuncAnimation(fig,animate,init_func=init,frames=20,interval=400)

ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
ax.set_xlabel(r"$\rm x$")
ax.set_ylabel(r"$\rm y$")
ax.set_zlabel(r"$\rm t$")

plt.close(ani._fig)

HTML(ani.to_html5_video())
Out[11]:

Beispiel II eines Eckenspiels

Wir betrachten die zeitliche Entwicklung eines weiteren Eckenspiels mit den folgenden Auszahlungswerten der beiden Spielergruppen:

$$ \begin{equation} \hat{\bf {\cal \$}}^A = \left( \begin{array}{rr} 10 & 4 \\ 12 & 5 \\ \end{array} \right) \quad , \quad \hat{\bf {\cal \$}}^B = \left( \begin{array}{rr} 10 & 2 \\ 7 & 5 \\ \end{array} \right) \end{equation} $$

Es handelt sich hierbei um eine Kombination von einem dominanten Spiel (Spielergruppe A: dominante Strategie 2 (x=0)) mit einem Koordinationsspiel (Spielergruppe B: zwei symmetrische Nash-Gleichgewichte).

Im folgenden wir das evolutionäre Eckenspiel (Beispiel II) für die Anfangsbedingungen $(x_0,y_0)=(0.9,0.2)$, $(x_0,y_0)=(0.95,0.8)$ und $(x_0,y_0)=(0.7,0.9)$ dargestellt.

In [12]:
Aa,Ab,Ac,Ad = 10,4,12,5
Ba,Bb,Bc,Bd = 10,2,7,5
x0 = 0.9
y0 = 0.2
initialval = np.array([x0,y0])
Loes = integrate.odeint(DGLsys, initialval, tval)
x0a = 0.95
y0a = 0.8
initialval = np.array([x0a,y0a])
Loesa = integrate.odeint(DGLsys, initialval, tval)
x0b = 0.7
y0b = 0.9
initialval = np.array([x0b,y0b])
Loesb = integrate.odeint(DGLsys, initialval, tval)
In [13]:
SgA=gA(SX,SY,Aa,Ab,Ac,Ad)
SgB=gB(SX,SY,Ba,Bb,Bc,Bd)
speed=np.sqrt(SgA*SgA + SgB*SgB)
colorspeed = speed/speed.max()
In [14]:
plt.cla()
plt.xlabel(r"$\rm x$")
plt.ylabel(r"$\rm y$")
figure=plt.streamplot(SX,SY,SgA,SgB,density=[2, 2], linewidth=1,color=colorspeed, cmap=plt.cm.cool)
plt.plot(Loes[:, 0], Loes[:, 1],c="black")
plt.scatter(x0, y0, s=40, marker='o', c="black")
plt.plot(Loesa[:, 0], Loesa[:, 1],c="green")
plt.scatter(x0a, y0a, s=40, marker='o', c="green")
plt.plot(Loesb[:, 0], Loesb[:, 1],c="blue")
plt.scatter(x0b, y0b, s=40, marker='o', c="blue")
cbar=plt.colorbar(figure.lines, aspect=20)
cbar.set_label(r'$\left| \vec{v} \right| =\sqrt{{g_A}^2 + {g_B}^2}$',size=20)

Aufgrund der Dominanz der Strategie x=0 für Spielergruppe A verlaufen die Richtungspfeile der Feldlinien nie in positive x-Richtung. Die y-Komponente der Feldlinien kann dagegen in positive oder negative y-Richtung zeigen (Koordinationsspiel für Spielergruppe B). Unabhangig von der Anfangsbedingung landet die Population stehts in der "symmetrischen Ecke" (x=0,y=0).

In [15]:
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot(Loes[:, 0], Loes[:, 1], zs=tval, c="black")
ax.scatter(x0, y0, zs=0, s=40, marker='o', c="black")
ax.plot(Loesa[:, 0], Loesa[:, 1], zs=tval, c="green")
ax.scatter(x0a, y0a, zs=0, s=40, marker='o', c="green")
ax.plot(Loesb[:, 0], Loesb[:, 1], zs=tval, c="blue")
ax.scatter(x0b, y0b, zs=0, s=40, marker='o', c="blue")
#ax.view_init(azim=-65, elev=35)
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
ax.set_xlabel(r"$\rm x$")
ax.set_ylabel(r"$\rm y$")
ax.set_zlabel(r"$\rm t$");

Beispiel eines Sattelpunktspiels

Wir betrachten die zeitliche Entwicklung eines Sattelpunktspiels mit den folgenden Auszahlungswerten der beiden Spielergruppen:

$$ \begin{equation} \hat{\bf {\cal \$}}^A = \left( \begin{array}{rr} 8 & 6 \\ 12 & 5 \\ \end{array} \right) \quad , \quad \hat{\bf {\cal \$}}^B = \left( \begin{array}{rr} 10 & 9 \\ 12 & 5 \\ \end{array} \right) \end{equation} $$

Es handelt sich hierbei um eine Kombination von einem Anti-Koordinationspiel (Spielergruppe A: zwei unsymmetrische Nash-Gleichgewichte) mit einem Anti-Koordinationsspiel (Spielergruppe B: zwei unsymmetrische Nash-Gleichgewichte).

Im folgenden wir das evolutionäre Eckenspiel für die Anfangsbedingungen $(x_0,y_0)=(0.99,0.85)$, $(x_0,y_0)=(0.96,0.75)$ und $(x_0,y_0)=(0.3,0.02)$ berechnet:

In [16]:
Aa,Ab,Ac,Ad = 8,6,12,5
Ba,Bb,Bc,Bd = 10,9,12,5
x0 = 0.99
y0 = 0.85
initialval = np.array([x0,y0])
Loes = integrate.odeint(DGLsys, initialval, tval)
x0a = 0.96
y0a = 0.75
initialval = np.array([x0a,y0a])
Loesa = integrate.odeint(DGLsys, initialval, tval)
x0b = 0.3
y0b = 0.02
initialval = np.array([x0b,y0b])
Loesb = integrate.odeint(DGLsys, initialval, tval)

SgA=gA(SX,SY,Aa,Ab,Ac,Ad)
SgB=gB(SX,SY,Ba,Bb,Bc,Bd)
speed=np.sqrt(SgA*SgA + SgB*SgB)
colorspeed = speed/speed.max()
In [17]:
plt.cla()
plt.xlabel(r"$\rm x$")
plt.ylabel(r"$\rm y$")
figure=plt.streamplot(SX,SY,SgA,SgB,density=[2, 2], linewidth=1,color=colorspeed, cmap=plt.cm.cool)
plt.plot(Loes[:, 0], Loes[:, 1],c="black")
plt.scatter(x0, y0, s=40, marker='o', c="black")
plt.plot(Loesa[:, 0], Loesa[:, 1],c="green")
plt.scatter(x0a, y0a, s=40, marker='o', c="green")
plt.plot(Loesb[:, 0], Loesb[:, 1],c="blue")
plt.scatter(x0b, y0b, s=40, marker='o', c="blue")
plt.scatter(2/3, 1/5, s=100, marker='^', c="red")
cbar=plt.colorbar(figure.lines, aspect=20)
cbar.set_label(r'$\left| \vec{v} \right| =\sqrt{{g_A}^2 + {g_B}^2}$',size=20)
plt.xlim(0, 1)
plt.ylim(0, 1);

Bei einem Sattelpunktsspiel das aus zwei Anti-Koordinationsspielen besteht, existieren zwei evolutionär stabile Strategien ((x=0,y=1) oder (x=1,y=0)) zu denen sich die Population im Laufe der Zeit entwickeln wird. Welche dieser evolutionär stabilen Strategien erreicht wird, hängt von der Anfangsstrategienwahl der Population ab. Auch bei sehr ähnlichen Werten der Anfangsstrategienwahl kann es geschehen, dass sich die Population im Laufe der Zeit zu unterschiedlichen Ecken entwickeln wird (siehe grüne und schwarze Trajektorien). Eine besondere Bedeutung hat der Sattelpunkt des Spiels (siehe rotes Dreieck in der oberen Abbildung). Die Position des Sattelpunktes im x-y Diagramm entspricht dem Wert des gemischten Nash-Gleichgewichtes bzw. läßt sich durch die Nullstellen der Funktionen $g_A(x,y)$ und $g_B(x,y)$ bestimmen.

Berechnung des gemischten Nash-Gleichgewichtes $(x^{\star},y^{\star})=(\frac{2}{3},\frac{1}{5})$ (partielle Ableitung der gemischten Auszahlungsflächen verschwindet):

$$ \left. \frac{ \partial {\bf \tilde{\cal \$}}^A(x,y)}{\partial x} \right|_{y=y^{\star}} \stackrel{!}{=}0 \,\, , \quad \left. \frac{ \partial {\bf \tilde{\cal \$}}^B(x,y)}{\partial y} \right|_{x=x^{\star}} \stackrel{!}{=}0 $$
In [18]:
import sympy as sym
sym.init_printing()

def DollarA(x,y):
  GemischteAuszahlung=Aa*x*y+Ab*x*(1-y)+Ac*(1-x)*y+Ad*(1-x)*(1-y)
  return GemischteAuszahlung
def DollarB(x,y):
  GemischteAuszahlung=Ba*x*y+Bc*x*(1-y)+Bb*(1-x)*y+Bd*(1-x)*(1-y)
  return GemischteAuszahlung
In [19]:
x,y = sym.symbols('x, y')
xGemNash = sym.symbols('x^\star')
yGemNash = sym.symbols('y^\star')
GlGemNashA=sym.Eq(DollarA(x, yGemNash).diff(x), 0)
GlGemNashB=sym.Eq(DollarB(xGemNash, y).diff(y), 0)
(GlGemNashB,GlGemNashA)
Out[19]:
$$\left ( - 6 x^\star + 4 = 0, \quad - 5 y^\star + 1 = 0\right )$$
In [20]:
(sym.solve(GlGemNashB)[0],sym.solve(GlGemNashA)[0])
Out[20]:
$$\left ( \frac{2}{3}, \quad \frac{1}{5}\right )$$

Berechnung der Nullstellen der Funktionen $g_A(x,y)$ und $g_B(x,y)$: Jede der beiden Bedingungen $g_A(x,y)\stackrel{!}{=}0$ und $g_A(x,y)\stackrel{!}{=}0$ liefert eine Kurve $y^\star(x^\star)$ die den Nulldurchgang der Flächen $g_A(x,y)$ und $g_B(x,y)$ beschreibt. Das gemischte Nash-Gleichgewicht befindet sich beim Schnittpunkt der beiden Kurven.

In [21]:
NullgA=sym.Eq(gA(xGemNash,yGemNash,Aa,Ab,Ac,Ad), 0)
NullgB=sym.Eq(gB(xGemNash,yGemNash,Ba,Bb,Bc,Bd), 0)
(NullgA,NullgB)
Out[21]:
$$\left ( \left(- \left(x^\star\right)^{2} + x^\star\right) \left(- 5 y^\star + 1\right) = 0, \quad \left(- 6 x^\star + 4\right) \left(- \left(y^\star\right)^{2} + y^\star\right) = 0\right )$$
In [22]:
sym.solve([NullgA,NullgB])
Out[22]:
$$\left [ \left \{ x^\star : 0, \quad y^\star : 0\right \}, \quad \left \{ x^\star : 0, \quad y^\star : 1\right \}, \quad \left \{ x^\star : \frac{2}{3}, \quad y^\star : \frac{1}{5}\right \}, \quad \left \{ x^\star : 1, \quad y^\star : 0\right \}, \quad \left \{ x^\star : 1, \quad y^\star : 1\right \}\right ]$$

Eine weitere Darstellungsmöglichkeit in einem (x,y,t)-Diagramm:

In [23]:
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot(Loes[:, 0], Loes[:, 1], zs=tval, c="black")
ax.scatter(x0, y0, zs=0, s=40, marker='o', c="black")
ax.plot(Loesa[:, 0], Loesa[:, 1], zs=tval, c="green")
ax.scatter(x0a, y0a, zs=0, s=40, marker='o', c="green")
ax.plot(Loesb[:, 0], Loesb[:, 1], zs=tval, c="blue")
ax.scatter(x0b, y0b, zs=0, s=40, marker='o', c="blue")
ax.view_init(azim=40, elev=25)
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
ax.set_xlabel(r"$\rm x$")
ax.set_ylabel(r"$\rm y$")
ax.set_zlabel(r"$\rm t$");

Beispiel eines Zentrumspiels

Wir betrachten die zeitliche Entwicklung eines Zentrumspiels mit den folgenden Auszahlungswerten der beiden Spielergruppen:

$$ \begin{equation} \hat{\bf {\cal \$}}^A = \left( \begin{array}{rr} 8 & 6 \\ 12 & 5 \\ \end{array} \right) \quad , \quad \hat{\bf {\cal \$}}^B = \left( \begin{array}{rr} 10 & 5 \\ 8 & 12 \\ \end{array} \right) \end{equation} $$

Es handelt sich hierbei um eine Kombination von einem Anti-Koordinationspiel (Spielergruppe A: zwei unsymmetrische Nash-Gleichgewichte) mit einem Koordinationsspiel (Spielergruppe B: zwei symmetrische Nash-Gleichgewichte).

Im folgenden wir das evolutionäre Eckenspiel für die Anfangsbedingungen $(x_0,y_0)=(0.5,0.5)$, $(x_0,y_0)=(0.96,0.85)$ und $(x_0,y_0)=(0.7,0.4)$ berechnet:

In [24]:
Aa,Ab,Ac,Ad = 8,6,12,5
Ba,Bb,Bc,Bd = 10,5,8,12
tval = np.linspace(0, 21.3, 1001)
x0 = 0.5
y0 = 0.5
initialval = np.array([x0,y0])
Loes = integrate.odeint(DGLsys, initialval, tval)
x0a = 0.96
y0a = 0.85
initialval = np.array([x0a,y0a])
Loesa = integrate.odeint(DGLsys, initialval, tval)
x0b = 0.7
y0b = 0.4
initialval = np.array([x0b,y0b])
Loesb = integrate.odeint(DGLsys, initialval, tval)

SgA=gA(SX,SY,Aa,Ab,Ac,Ad)
SgB=gB(SX,SY,Ba,Bb,Bc,Bd)
speed=np.sqrt(SgA*SgA + SgB*SgB)
colorspeed = speed/speed.max()
In [25]:
plt.cla()
plt.xlabel(r"$\rm x$")
plt.ylabel(r"$\rm y$")
figure=plt.streamplot(SX,SY,SgA,SgB,density=[2, 2], linewidth=1,color=colorspeed, cmap=plt.cm.cool)
plt.plot(Loes[:, 0], Loes[:, 1],c="black")
plt.scatter(x0, y0, s=40, marker='o', c="black")
plt.plot(Loesa[:, 0], Loesa[:, 1],c="green")
plt.scatter(x0a, y0a, s=40, marker='o', c="green")
plt.plot(Loesb[:, 0], Loesb[:, 1],c="blue")
plt.scatter(x0b, y0b, s=40, marker='o', c="blue")
plt.scatter(7/9, 1/5, s=100, marker='^', c="red")
cbar=plt.colorbar(figure.lines, aspect=20)
cbar.set_label(r'$\left| \vec{v} \right| =\sqrt{{g_A}^2 + {g_B}^2}$',size=20)
plt.xlim(0, 1)
plt.ylim(0, 1);

Bei einem Zentrumsspiel existiert keine evolutionär stabile Strategie da die Strategienwahl der Population sich im Laufe der Zeit ständig verändert und um ein Zentrum (siehe rotes Dreieck in der oberen Abbildung) kreist. Die Position dieses Zentrums im x-y Diagramm (hier speziell $(x^{\star},y^{\star})=(\frac{7}{9},\frac{1}{5})$) entspricht dem Wert des gemischten Nash-Gleichgewichtes bzw. läßt sich durch die Nullstellen der Funktionen $g_A(x,y)$ und $g_B(x,y)$ bestimmen.

In [26]:
GlGemNashA=sym.Eq(DollarA(x, yGemNash).diff(x), 0)
GlGemNashB=sym.Eq(DollarB(xGemNash, y).diff(y), 0)
(GlGemNashB,GlGemNashA)
Out[26]:
$$\left ( 9 x^\star - 7 = 0, \quad - 5 y^\star + 1 = 0\right )$$
In [27]:
(sym.solve(GlGemNashB)[0],sym.solve(GlGemNashA)[0])
Out[27]:
$$\left ( \frac{7}{9}, \quad \frac{1}{5}\right )$$

Die zeitliche Entwicklung läßt sich auch gut in einem (x,y,t)-Diagramm darstellen:

In [28]:
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot(Loes[:, 0], Loes[:, 1], zs=tval, c="black")
ax.scatter(x0, y0, zs=0, s=40, marker='o', c="black")
ax.plot(Loesa[:, 0], Loesa[:, 1], zs=tval, c="green")
ax.scatter(x0a, y0a, zs=0, s=40, marker='o', c="green")
ax.plot(Loesb[:, 0], Loesb[:, 1], zs=tval, c="blue")
ax.scatter(x0b, y0b, zs=0, s=40, marker='o', c="blue")
#ax.view_init(azim=40, elev=25)
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
ax.set_xlabel(r"$\rm x$")
ax.set_ylabel(r"$\rm y$")
ax.set_zlabel(r"$\rm t$");

bzw. in einer Animation darstellen, wobei die einzelnen Punkte der evolutionären Entwicklung äquidistanten Zeitabschnitten entsprechen.

In [29]:
fig = plt.figure()
ax = fig.gca(projection='3d')

def init():   
#    ax.plot(Loes[:, 0], Loes[:, 1], zs=tval, c="black")
#    ax.scatter(x0, y0, zs=0, s=40, marker='o', c="black")
    ax.plot(Loesa[:, 0], Loesa[:, 1], zs=tval, c="green")
    ax.scatter(x0a, y0a, zs=0, s=40, marker='o', c="green")
    ax.plot(Loesb[:, 0], Loesb[:, 1], zs=tval, c="blue")
    ax.scatter(x0b, y0b, zs=0, s=40, marker='o', c="blue")
    return fig,

def animate(i):
#    ax.scatter(Loes[15*i, 0], Loes[15*i, 1], zs=tval[15*i], s=20, marker='o', c="black")
    ax.scatter(Loesa[15*i, 0], Loesa[15*i, 1], zs=tval[15*i], s=20, marker='o', c="green")
    ax.scatter(Loesb[15*i, 0], Loesb[15*i, 1], zs=tval[15*i], s=20, marker='o', c="blue")
    return fig,

ani = animation.FuncAnimation(fig,animate,init_func=init,frames=65,interval=500)

ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
ax.set_xlabel(r"$\rm x$")
ax.set_ylabel(r"$\rm y$")
ax.set_zlabel(r"$\rm t$")

plt.close(ani._fig)

HTML(ani.to_html5_video())
Out[29]: