Bergervei/Python-Die Eulersche Zahl

Aus ProgrammingWiki

Wiki-Quelltext dieser Seite.

<language>Python</language>
Es gilt: $e = 2,718~281~828~459~045~235~360~287~471~352~...$

== Die Eulersche Zahl als Grenzwert einer Zahlenfolge ==

Die Zahlenfolge
<blockquote>$e_n=(1+\frac{1}{n})^n\hspace{0.3em},\hspace{0.3em}\mbox{für}\hspace{0.3em}n=1, 2, 3, ...$</blockquote>
hat als Grenzwert die Eulersche Zahl.
<blockquote>$e=\lim\limits_{n \to \infty}(1+\frac{1}{n})^n$</blockquote>

<code id="63ac084b0ae43">
def e_folge(n):
  e = 1
  for i in range(1, n + 1):
    e = (1 + 1 /  i) ** i
  return e
</code>

<run id="63ac084b0aec2">
print(e_folge(1000))
</run>

== Die Eulersche Zahl als Kettenbruch ==
Die Eulersche Zahl lässt sich mit einem Kettenbruch sehr schnell annähern.

<table border="0">
<tr>
<td width="80%">
=== Iterative Implementation ===
<code id="639da9b83896a">
def e_iterativ(n):
  e = 0
  for i in range(n, 1, -1):
    e = i / (e + i)
  return 2 + e
</code>

<run id="639da9b8389d5">
print(e_iterativ(10))
</run>
</td>
<td width="20%">
[[Bild:Euler_Kettenbruch.jpg|miniatur|Kettenbruchdarstellung der Eulerschen Zahl]]
</td>
</tr>
</table>

=== Rekursive Implementation ===
<code id="639dcde7f3bf6">
def e_rekursiv(n):
  def e_tail(i, n):
    if i > n:
      return 0
    else:
      return i / (i + e_tail(i + 1, n))
  return 2 + e_tail(2, n)
</code>

<run id="639dcde7f3c69">
print(e_rekursiv(10))
</run>

== Euler-Zufall 1 ==
Wie oft müssen Zufallszahlen aus dem Intervall [0, 1] gebildet werden, damit die Summe zum ersten Mal 1 überschreitet?
 
=== Simulation ===
<code id="639d9442a5eee">
from random import *
from math import exp

def eulerzufall1(n):
  m = 0
  for i in range(n):
    z = 0; j = 0
    while z < 1:
      z += random()
      j += 1
    m += j
  return m / n

def eulerzahl1(n):
  print("Eulerzahl: %1.8f" % eulerzufall1(n))
  print("Zum Vergleich: e = %1.8f" % exp(1))
</code>

<run id="639d9442a5f88">
eulerzahl1(20000)
</run>

== Euler-Zufall 2 ==
Eine Folge von Zahlen wird zufällig aus dem Intervall [0, 1] erzeugt.<br> 
Der Prozess wird so lange fortgesetzt, wie die Folge monoton steigend ist.<br>
Welche Länge der monotonen Folge wird erwartet? 

=== Simulation ===
<code id="639d9442a5f3d">
from random import *
from math import exp

def eulerzufall2(n):
  m = 0
  for i in range(n):
    z0 = 0; z = random()
    j = 1
    while z0 < z:
      z0 = z
      z = random()
      j += 1
    m += j
  return m / n

def eulerzahl2(n):
  print("Eulerzahl: %1.8f" % eulerzufall2(n))
  print("Zum Vergleich: e = %1.8f" % exp(1))
</code>

<run id="639d97fe62936">
eulerzahl2(200000)
</run>

== Ein Rencontre-Problem (Fixpunktreie Permutationen) ==
Die Stapel zweier gleicher Kartenspiele werden jeweils gemischt und verdeckt nebeneinander gelegt.<br>
Fortlaufend werden die beiden oben liegenden Karten aufgedeckt und nebeneinander gelegt.<br>
Mit welcher Wahrscheinlichkeit kann ein gleiches Paar erwartet werden?

=== Simulation ===
<code id="639df1ca18887">
from random import *
from math import exp

def perm(n):
  p = []
  while len(p) < n:
    a =randint(1, n)
    if not(a in p): p.append(a)
  return(p)

def permdiff(n):
  p1 = perm(n); p2 = perm(n)
  diff =[]
  for i in range(n):
    diff.append(p1[i] - p2[i])
  return diff

def ergebnis(n, anz):
  ges = 0
  for j in range(anz):
    diff = permdiff(n)
    c = 0
    for i in range(n):
      if diff[i] == 0: c = 1; break
    ges += c
  return ges / anz

def rencontre(n, anz):
  print("Relative Häufigkeit: %1.8f" % ergebnis(n, anz)) 
  print("Zum Vergleich: 1 - 1 / e = %1.8f" % (1 - 1 / exp(1)))
</code>

<run id="639df1ca188f1">
rencontre(10, 1000)
</run>

== Das Rosinenproblem ==
In den Teig für 100 Brötchen werden zufällig 100 Rosinen hinengeknetet.<br>
Wie viele Brötchen enthalten mindestens eine Rosine?

=== Simulation ===
<code id="639dfb6f8288e">
from random import *
from math import exp

def rosinen(n):
  r = [randint(0, n - 1) for i in range(n)]
  z = 0
  for j in range(n):
    k = 0
    for i in range(n):
      if r[i] == j: k = 1; break
    z += k
  return z / n

def rosinenproblem(anz):
  z = 0
  for i in range(anz):
    z += rosinen(100)
  mw = z / anz
  print("Mittelwert: %1.8f" % mw)
  ew = 1 - 1 / exp(1)
  print("Zum Vergleich: 1 - 1/e = %1.8f" % ew)
</code>

<run id="639dfb6f82908">
rosinenproblem(1000)
</run>

== Das Münzenproblem ==
Eine Fastfood-Kette verschenkt bei jedem Einkauf eine Münze eines 50-teiligen Satzes von Sondermünzen.<br>
Ziel ist es, den gesamten Münzsatz zu sammeln.<br>
Welchen Bruchteil des kompletten Münzsatzes würde man nach 50 Einkäufen erwarten?

=== Simulation ===
<code id="639d97fe628dc">
from random import *
from math import exp

def auswahl(n):
  muenzen = [i for i in range(n)]
  pos = randint(0, n - 1)
  return muenzen[pos]

def muenzenproblem(n, anz):
  sum = 0
  for j in range(anz):
    set = []
    for i in range(n):
      muenze = auswahl(n)
      if not (muenze in set):
        set.append(muenze)
    sum += len(set) / n
  h = sum / anz
  print("Relative Häufigkeit: %1.8f" % h)
  vw = 1 - 1 / exp(1)
  print("Zum Vergleich: 1 - 1 / e = %1.8f" % vw)
</code>

<run id="639d97fe629c7">
muenzenproblem(50, 100)
</run>

== Das Sekretärinnenproblem ==
Für eine Sekretärinnenstelle gibt es $n$ Bewerberinnen.<br>
Die ersten $k$ Bewerberinnen werden zwar angehört, aber allesamt abgelehnt.<br>
Die Gespräche werden fortgeführt und die Kandidatin eingestellt, die besser als alle Vorgängerinnen ist. Solle es keine bessere geben, muss die letzte Bewerberin eingestellt werden.<br>
Bei welcher Anzahl $k$ ist die Wahrscheinlichkeit am größten, die beste Bewerberin einzustellen?

=== Simulation ===
<code id="639da07322988">
from random import *
from math import exp

def auswahl(n, k):
  bewliste = [random() for i in range(n)]
  bewteilliste = []
  for i in range(k):
    bewteilliste.append(bewliste[i])
  maxwert = max(bewliste)
  bestwert = max(bewteilliste)
  kandidat = 0
  while kandidat < bestwert and k < n:
    kandidat = bewliste[k]
    k += 1
  if kandidat == maxwert:
    return 1
  else:
    return 0

def sekretaerinnenproblem(n, k, anz):
  z = 0
  for i in range(anz):
    z += auswahl(n, k)
  h = z / anz
  print("Relative Häufigkeit: %1.8f" % h)
  vw = 1 / exp(1)
  print("Zum Vergleich: 1/e = %1.8f" % vw)
</code>

<run id="639da073229f9">
sekretaerinnenproblem(100, 37, 2500)
</run>

== Anmerkung ==
Diese Algorithmen wurden anlässlich des 315. Geburtstages Leonhard Eulers gemeinsam mit Dr. Hubert Langlotz (Thüringen) in einem webbasierten Seminar am 06.12.2022 vorgestellt.<br>

Löbau, den 17.12.2023<br>
Veit Berger