modul: programmierung b-prg softwaretechnik grundlagen der

12
Modul: Programmierung B-PRG Grundlagen der Programmierung 1 – Teil 2 Softwaretechnik Prof. Dr. O. Drobnik Professur Architektur und Betrieb verteilter Systeme Institut für Informatik Fachbereich Informatik und Mathematik Softwaretechnik Kapitel 2 – Entwurf von Algorithmen Grundlagen der Programmierung 1 2.1 Greedy-Methode 2.2 Divide and Conquer – Methode 2.3 Backtracking-Methode 2.4 Schrittweise Verfeinerung © J.W.G-Universität Frankfurt a.M. Praktikum Grundlagen der Programmierung Folie 3 Übersicht - 2. Entwurf und Implementierung 2.1 Greedy-Methode 2.1.1 Methode 2.1.2 Konvexe Hülle 2.2 Divide and Conquer – Methode 2.2.1 Methode 2.2.2 Maximum-Contiguous-Subvector Problem 2.2.3 Naiver Ansatz 2.2.4 Divide and Conquer Ansatz für MCS-Problem 2.2.5 Scanning-Algorithmus 2.2.6 Türme von Hanoi 2.3 Backtracking-Methode 2.3.1 Methode 2.3.2 Konvexe Hülle: Graham Scan 2.4 Schrittweise Verfeinerung © J.W.G-Universität Frankfurt a.M. Praktikum Grundlagen der Programmierung Folie 4 2.1 Greedy-Methode 2.1.1 Methode Stufenweises Vorgehen Sukzessives Betrachten der Eingabewerte Auswahlfunktion: Reihenfolge für die Betrachtung der Eingabewerte Entscheidung: gehört Eingabewert zur Lösung oder nicht Einfache Entwurfsmethode, auf vielfältige Problemstellungen anwendbar

Upload: others

Post on 24-Mar-2022

4 views

Category:

Documents


0 download

TRANSCRIPT

Modul: Programmierung B-PRG Grundlagen der Programmierung 1 – Teil 2

Softwaretechnik

Prof. Dr. O. DrobnikProfessur Architektur und Betrieb verteilter SystemeInstitut für InformatikFachbereich Informatik und Mathematik

Softwaretechnik

Kapitel 2 – Entwurf von Algorithmen

Grundlagen der Programmierung 1

2.1 Greedy-Methode2.2 Divide and Conquer – Methode2.3 Backtracking-Methode2.4 Schrittweise Verfeinerung

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 3

Übersicht - 2. Entwurf und Implementierung

2.1 Greedy-Methode2.1.1 Methode2.1.2 Konvexe Hülle

2.2 Divide and Conquer – Methode2.2.1 Methode2.2.2 Maximum-Contiguous-Subvector Problem2.2.3 Naiver Ansatz2.2.4 Divide and Conquer Ansatz für MCS-Problem2.2.5 Scanning-Algorithmus2.2.6 Türme von Hanoi

2.3 Backtracking-Methode2.3.1 Methode2.3.2 Konvexe Hülle: Graham Scan

2.4 Schrittweise Verfeinerung© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 4

2.1 Greedy-Methode

2.1.1 MethodeStufenweises VorgehenSukzessives Betrachten der EingabewerteAuswahlfunktion: Reihenfolge für die Betrachtung der EingabewerteEntscheidung: gehört Eingabewert zur Lösung oder nichtEinfache Entwurfsmethode, auf vielfältige Problemstellungen anwendbar

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 5

Basisalgorithmus (Greedy)

def Greedy(input):result = []while len(input) != 0:

s = selectfrominput() # Auswahlif solution(s):

result.append(s)input.remove(s)

return result

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 6

2.1.2 Konvexe Hülle

Gegeben ist eine Punktmenge von N Punkten in der Ebene. Gesucht sei die konvexe Hülle der Punktemenge, d. h. das kleinste konvexe Polygon, das alle Punkte der Menge enthält.Konvexe Hülle: Jede Strecke, die zwei Punkte innerhalb des Polygons verbindet, muss vollständig innerhalb des Polygons liegen.

Konvex nicht konvex

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 7

Package Wrapping (Paket einhüllen)

Package Wrapping ist der “natürlichste” Algorithmus: er ähnelt der Vorgehensweise des Menschen, eine konvexe Hülle zu zeichnen:

Man wähle einen geeigneten Startpunkt, der garantiert auf der Hülle liegt,nehme einen horizontalen Strahl und bewege ihn solange im Gegenuhrzeigersinn, bis ein weiterer Punkt getroffen wird; dieser Punkt muss auf der Hülle sein;wiederhole die Prozedur von diesem neuen Punkt aus usw. bis letztlich der Startpunkt wieder erreicht wird, d. h. die Punktemenge vollständig “eingehüllt”ist.

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 8

Erzeugen der Punktemenge: Liste p

class Point:def __init__(self, x, y):

self.x = xself.y = y

def test(n):from rand import randp = []for i in range(n):

p.append(Point(rand() % 1000, rand() % 1000))

h = convex_hull(p) # Aufruf des Hauptalg.print h

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 9

Algorithmus convex_hull

Startpunkt: Punkt mit der kleinsten y-Koordinate: pmin

Zwischenergebnis: hull = [pmin]

def convex_hull(pset):# Punkt mit kleinster y-Koordinate suchen,# dieser liegt in jedem Fall auf der# Hülle.pmin = pset[0]for p in pset:

if p.y < pmin.y:pmin = p

hull = [pmin]

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 10

Algorithmus convex_hull

Bestimme den nächsten Punkt: hull = [pmin, p]

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 11

Algorithmus convex_hull

Seien i-Punkte bis einschließlich Pi in “hull”Suche den nächsten Punkt für die Hülle: Pi+1

Es gilt für Өi+1:Өi+1 ≥ Өi(Drehung im Gegenuhrzeigersinn)Өi+1 ist minimalunter allen Ө ≥ Өi(Hüllenforderung)

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 12

Berechnung des Winkels Ө

Vorbetrachtung

Ө wird nur zum Sortieren benötigt.Es genügt daher eine leicht zu berechnende Funktion, deren Anordnungseigenschaft der einer Winkelfunktion äquivalent ist.

dxdyΘtan =

dydxdyt+

=

dxdytanΘ 1−=

dy

dxӨ

Pi

Pi+1

..

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 13

Berechnung des Winkels Ө

def theta(p1, p2):dx = float(p2.x - p1.x)dy = float(p2.y - p1.y)ax = abs(dx)ay = abs(dy)if dx == 0 and dy == 0:

t = 0else:

t = dy/(ax + ay)if dx < 0:

t = 2.0 - telif dy < 0:

t = 4.0 + treturn t * 90.0

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 14

Convex_hull: Hauptteil

def convex_hull(pset):thetaold = 0while True:

thetamin = 360.0p1 = hull[-1]for p2 in pset:

if not p2 == p1:thetanew = theta(p1, p2)if thetanew >= thetaold:

if thetanew < thetamin:thetamin = thetanewpnext = p2

thetaold = thetaminif pnext == hull[0]:

breakhull.append(pnext)

return hull

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 15

Demonstration

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 16

2.2 Divide and Conquer – Methode

2.2.1 MethodeTeile (Divide)

Teile das Problem der Größe N in (wenigstens) zwei annähernd gleichgroße Teilprobleme, wenn N > 1 ist.Ist ein Teilproblem hinreichend klein (z.B. N = 1), so löse es direkt und breche so die Rekursion im Lösungsschema ab.

Herrsche (Conquer)Löse die Teilprobleme auf dieselbe Art.

Vereinige (Merge)Füge die Lösungen für die Teilprobleme zur Gesamtlösung zusammen.

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 17

2.2.2 Maximum-Contiguous-SubvectorProblem

Gegeben:Folge v von N ganzen Zahlen in einer Liste;die Folge muss mindestens ein Element enthalten.

Gesucht:maximale Summe aller Elemente in einer zusammenhängenden Teilfolge, maximaler Teilsumme: maximale Teilfolge.

Sind alle Elemente negativ, so sei die maximale Teilfolge die leere Folge, deren Summe gleich 0 ist.

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 18

Maximum-Contiguous-Subvector Problem

Maximale Teilsumme:

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 19

Formalisierung des Problems

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 20

2.2.3 Naiver Ansatz

Ansatz: Betrachte für jeden Index der Folge die von diesem ausgehenden Teilfolgen

MaxSoFar: bisher gefundene maximale Teilsumme

def mcsv_simple(v):MaxSoFar = 0for i in range(len(v)):

sum = 0for s in v[i:]:

sum = sum + sMaxSoFar = max(MaxSoFar, sum)

return MaxSoFar

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 21

Naiver Ansatz

Die Anweisungen innerhalb der äußeren Schleifewerden N-mal, die innerhalb der zweiten Schleife jeweilshöchstens N-mal bei jeder Ausführung der äußerenSchleife durchlaufen, dh. die Laufzeit ist in derGrößenordnung von N2.

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 22

2.2.4 Divide and Conquer Ansatz für MCS-Problem

Teilt man eine gegebene Folge in der Mitte, so liegt die maximale Teilfolge

entweder ganz in einem der beiden Teilstücke

oder sie umfasst die Trennstelle, liegt also teils im linken undteils im rechten Teil.

Für das in einem Teil liegende Stück der maximalen Teilfolge gilt: Die Summe der Elemente ist maximal unter allen zusammenhängenden Teilfolgen in diesem Teil, die das Randelement an der Trennstelle enthalten.

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 23

Divide and Conquer Ansatz für MCS-Problem

def mcsv_dv(v):if len(v) == 1:

return max(0, v[0])left = v[:len(v)/2]right = v[len(v)/2:]MaxInLeft = mcsv_dv(left)MaxInRight = mcsv_dv(right)sum = 0MaxCrossing = 0left.reverse()for s in left:

sum = sum + sMaxCrossing = max(MaxCrossing, sum)

sum = MaxCrossingfor s in right:

sum = sum + sMaxCrossing = max(MaxCrossing, sum)

return max(MaxInRight, MaxInLeft, MaxCrossing)

Div.

Conq.

Merge

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 24

Beispiel

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 25

Beispiel

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 26

Aufwandsabschätzung (grobe Betrachtung)

Anzahl der Schritte (mit der Annahme N = 2k − 1d. h. k = log2(N + 1)):

Teilung ≈ log2 Nin jeder Teilung maximal N weitere Schritte C

C wird log2 N mal durchlaufen (C : max. N Schritte)

ungefähr N · log2 N Schritte nötig

ist besser als N2

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 27

2.2.5 Scanning-Algorithmus

Scanning-PrinzipProbleme auf Folgen (arrays) können oft dadurch gelöst werden, daß man – ausgehend von einer Lösung für v[0 · · · i − 1] – untersucht, wie man diese für v[0 · · · i] erweitern kann.

AnsatzSpeicherung des bereits gefundenen Ergebnisses Hinzunahme von Hilfsdaten zur Berechnung des neuen Resultats

Aufwand ≈ N

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 28

Bezug zum MCS-Problem

Wir durchlaufen sequentiell die Positionen von v in der Ordnung der Positionen, d. h. 0, 1, · · · , len(v) − 1 MaxSoFar: bereits gefundene maximale TeilsummeWir führen eine neue Variable ein (“Hilfsdaten”): MaxEndingHere

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 29

Formalisierung von MaxEndingHere

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 30

Algorithmus

def mcsv_lin(v):MaxSoFar = 0MaxEndingHere = 0# {0 ≤ MaxEndingHere ≤ MaxSoFar}for s in v:

# {0 ≤ MaxEndingHere ≤ MaxSoFar}# Vorbedingung:# {Pindex(s−1) = MaxSoFar = # MaxSoFar[0 · · · index(s) − 1] ^ # MaxEndingHere = MaxEndingHereindex(s)−1}MaxEndingHere = max(MaxEndingHere + s, 0)MaxSoFar = max(MaxSoFar, MaxEndingHere)# Nachbedingung:# {MaxSoFar = MaxSoFar[0 · · · index(s)] ^# MaxEndingHere = MaxEndingHereindex(s)}

return MaxSoFar

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 31

2.2.6 Türme von Hanoi

n Steine unterschiedlichen Durchmessers sollen von einem Stapel auf einen anderen gebracht werden, wobei ein Hilfsstapel benutztwerden darf (Problem der Größe n). Dabei sind folgende Bedingungen einzuhalten:

es darf stets nur ein Stein, und zwar der oberste eines Stapels,bewegt werden,zu keiner Zeit darf ein Stein auf einem kleineren liegen.

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 32

Lösungsansatz

Vorbedingung: alle Steine mit Nummer x, x + 1, · · · , n auf Stapel i.Nachbedingung: alle Steine mit Nummer x, x + 1, · · · , n auf Stapel j.Umsetzen eines Steines von Stapel i auf j:

Auf Stapel i und j dürfen sich nur größere Steine als der zu bewegende Stein befinden.Alle kleineren Steine müssen deshalb zu diesem Zeitpunkt auf dem dritten Stapel k liegen.

Formal:Wenn für i, j {1, 2, 3} Stein x von Stapel i auf Stapel j gebracht wird, müssen alle kleineren Steine auf dem Stapel mit der Nummer k = 6 − (i + j) liegen.

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 33

Divide and Conquer

Aufspaltung des Gesamtproblems:alle Steine x + 1, · · · , n auf Stapel k = 6 − (i + j)Stein x von i auf jalle Steine x + 1, · · · , n von k = 6 − (i + j) auf Stapel j

Aufspaltung führt zur Rekursion: die zu lösenden Teilprobleme sind identisch mit der ursprünglichen Aufgabe, werden aber für eine kleinere Eingabe gelöst.

Das Türme-von-Hanoi Problem demonstriert die Eleganz und Kürze rekursiver Lösungsansätze.

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 34

Python Programm

# n Anzahl Steine# slice Stein mit Nummer slice# help Hilfsstapel# source Ausgangsstapel# dest Zielstapeldef hanoi(n, slice, source, dest):

print "hanoi(%s,%s,%s,%s)" % (n, slice, source, dest)help = 6 - source - destif slice < n:

hanoi(n, slice + 1, source, help)print "Scheibe %s von %s auf %s" % (slice, source,

dest)if slice < n:

hanoi(n, slice + 1, help, dest)

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 35

hanoi(3,1,1,2)#Ausgabe:# hanoi(3,1,1,2)# hanoi(3,2,1,3)# hanoi(3,3,1,2)# Scheibe 3 von 1 auf 2# Scheibe 2 von 1 auf 3# hanoi(3,3,2,3)# Scheibe 3 von 2 auf 3# Scheibe 1 von 1 auf 2# hanoi(3,2,3,2)# hanoi(3,3,3,1)# Scheibe 3 von 3 auf 1# Scheibe 2 von 3 auf 2# hanoi(3,3,1,2)# Scheibe 3 von 1 auf 2

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 36

Aufwandsabschätzung

Anzahl Schritte:Größenordnug: 2n - 1

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 37

2.3 Backtracking-Methode

2.3.1 MethodeVersuch-und-Irrtum-Prinzip (trial and error):

Auswahl eines möglichen LösungswegsVerfolgen dieses Lösungswegs soweit wie möglichFalls Lösungsweg nicht fortgesetzt werden kann, ersetzen der letzten Entscheidung durch eine AlternativeGgf. iteriertes Rücksetzen der Entscheidungen

Unterschied zu Greedy:Greedy: exhaustives Verfahren – untersucht alle LösungswegeBacktracking: versucht, offensichtlich falsche Lösungswege frühzeitig zu vermeiden (nicht weiter zu verfolgen)

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 38

2.3.2 Konvexe Hülle: Graham Scan

Sortiere Punkte so, dass die Hüllenpunkte in derReihenfolge vorliegen, die man beim Durchlaufen derkonvexen Hülle im Gegenuhrzeigersinn erhält.

Ankerpunkt: kleinste y-Koordinate, größte x-KoordinateSortierung: theta-Funktion (siehe 2.1.2)Man erhält durch die Sortierung der Punkte einenPolygonzug, der alle Punkte umfasst und sich selbstnicht schneidet

Die ersten beiden Punkte liegen auf der Hülle. sukzessive hinzufügen aller Punkte:Bei jedem Punkt prüfen, ob seine Vorgänger tatsächlich auf der konvexen Hülle liegen.

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 39

ccw-Funktion

Dann gelten folgendeGeradensteigungen:

Es sei:

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 40

ccw-Funktion

Reise von P0 zu P1 zu P2:

Drehung im Gegenuhrzeigersinn

Drehung im UhrzeigersinnProblem: dx1 oder dx2 = 0daher ProduktbildungProblem: Kollinearität der Punkte, d.h. Steigungen sind gleich.Lösung: Funktion ccw wird dreiwertig definiert. Sind P0, P1, P2 kollinear, dann:

ccw = -1 : P0 ist zwischen P2 und P1

ccw = 0 : P2 ist zwischen P0 und P1

ccw = 1 : P1 ist zwischen P0 und P2

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 41

Graham Scan

def grahamscan(p):global lowestlowest = Nonefor q in p:

if lowest == None or q.y < lowest.y:lowest = q

for q in p:if q.y == lowest.y and q.x > lowest.x:

lowest = qp.sort(lambda p1, p2: cmp(theta(lowest, p1),

theta(lowest, p2)))hull = p[0:3]for trypos in range(3, len(p)):

while ccw(hull[-2],hull[-1],p[trypos]) < 0:del hull[-1]

hull.append(p[trypos])return hull

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 42

Graham Scan

def grahamscan(p):global lowestlowest = Nonefor q in p:

if lowest == None or q.y < lowest.y:lowest = q

for q in p:if q.y == lowest.y and q.x > lowest.x:

lowest = qp.sort(lambda p1, p2: cmp(theta(lowest, p1),

theta(lowest, p2)))hull = p[0:3]for trypos in range(3, len(p)):

while ccw(hull[-2],hull[-1],p[trypos]) < 0:del hull[-1]

hull.append(p[trypos])return hull

Punkte mit kleinster y-Koordinate und unter diesen den mit maximaler x-Koordinate suchen

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 43

Graham Scan

def grahamscan(p):global lowestlowest = Nonefor q in p:

if lowest == None or q.y < lowest.y:lowest = q

for q in p:if q.y == lowest.y and q.x > lowest.x:

lowest = qp.sort(lambda p1, p2: cmp(theta(lowest, p1),

theta(lowest, p2)))hull = p[0:3]for trypos in range(3, len(p)):

while ccw(hull[-2],hull[-1],p[trypos]) < 0:del hull[-1]

hull.append(p[trypos])return hull

Die restlichen Punkte nach dem Winkel zwischen der Horizontalen und Geraden, die sie mit ‘lowest’ verbindet sortieren.

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 44

Graham Scan

def grahamscan(p):global lowestlowest = Nonefor q in p:

if lowest == None or q.y < lowest.y:lowest = q

for q in p:if q.y == lowest.y and q.x > lowest.x:

lowest = qp.sort(lambda p1, p2: cmp(theta(lowest, p1),

theta(lowest, p2)))hull = p[0:3]for trypos in range(3, len(p)):

while ccw(hull[-2],hull[-1],p[trypos]) < 0:del hull[-1]

hull.append(p[trypos])return hull

Die ersten beiden Punkte liegen in jedem Fall auf der konvexen Hülle, der dritte Punkt wird zunächst hinzugenommen.

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 45

Graham Scan

def grahamscan(p):global lowestlowest = Nonefor q in p:

if lowest == None or q.y < lowest.y:lowest = q

for q in p:if q.y == lowest.y and q.x > lowest.x:

lowest = qp.sort(lambda p1, p2: cmp(theta(lowest, p1),

theta(lowest, p2)))hull = p[0:3]for trypos in range(3, len(p)):

while ccw(hull[-2],hull[-1],p[trypos]) < 0:del hull[-1]

hull.append(p[trypos])return hull

Die Variable ‘trypos’ enthält den Index des Punktes in ‘p’, den wir der Hülle hinzufügen.

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 46

Beispiel

© J.W.G-Universität Frankfurt a.M.Praktikum Grundlagen der Programmierung Folie 47

2.4 Schrittweise Verfeinerung

Problem (maschinell lösbar)Analyse, Abstraktion, Spezifizieren

Spezifikation (Eingabe, Ausgabe)

Zerlegung in Unterprobleme- Identifizieren von Unterproblemen- Analysieren, Spezifizieren von

Unterproblemen (Eingabe/Ausgabe)

Zusammensetzung der Gesamtlösungaus den Lösungen der Unterprobleme- Algorithmus, der Unteralgorithmen "aufruft"

- Sichere KorrektheitSchätze Aufwand

ggf. weitere Zerlegungevtl. Neuentwurf

Für nichtelementare Unter-algorithmen: Entwurf durchweitere ZerlegungKorrektheit, Aufwand

Maschine, die Elementaralgorithmenausführen kann