• Keine Ergebnisse gefunden

Praktische Informatik I – Der Imperative Kern Suchen, Selektieren und Sortieren

N/A
N/A
Protected

Academic year: 2021

Aktie "Praktische Informatik I – Der Imperative Kern Suchen, Selektieren und Sortieren"

Copied!
23
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Praktische Informatik I – Der Imperative Kern Suchen, Selektieren und Sortieren

Prof. Dr. Stefan Edelkamp

Institut für Künstliche Intelligenz

Technologie-Zentrum für Informatik und Informationstechnik (TZI) Am Fallturm 1, 28359 Bremen

+49-(0)421-218-64007 www.tzi.de/~edelkamp

(2)

Suchen, Selektieren und Sortieren

In diesem Abschnitt werden schnelle Verfahren auf geordneten Mengen besprochen, wobei die Effizienz in der Anzahl der Schlüsselvergleiche gemessen wird.

(3)

Outline

1 Gleichzeitige Suche von Mini- und Maximum

2 Schnelles Suchen

3 Schnelles Sortieren

4 Kryptogramme

5 Nimm

(4)

Zwei auf einen Streich

Dasgleichzeitige Finden vom Minimum und vom Maximumin einem Feld (engl. array) der Größenkann mit wenigen Vergleichen elegant durch Rekursion gelöst werden kann.

Dazu wird das Feld in zwei gleich große Teilegeteiltund das Minimum und Maximum in beiden Teilen bestimmt.

Nach dem rekursiven Aufruf kann man nun dasMaximum beider Maximaund dasMinimum beider Minimaberechnen und an die aufrufende Rekursionsstufeweiterleiten.

DerAbbrucherfolgt, wenn die Aufteilung zu einem Feld mit nur einem Element führt.

Der Einfachheit halber nehmen wir im Programm 1 an, dassneine

(5)

Programm 1:Mini- und Maximum-Berechnung.

importjava.util.Random;

public classMinMax {

int[]a;

public classMM{intmin;intmax; };

publicMinMax(intN) { Random r=newRandom();

a=new int[N];

for(inti=0;i<N;i++) { a[i] =r.nextInt(1000);

System.out.print(a[i]+",");

}

System.out.println();

}

MM search(intx,inty) { MM m=newMM();

if(y<=x+1) {m.min=a[x]<a[y] ?x:y;m.max=a[x]<a[y] ?y:x; } else{// y > x+1, recursive call required

MM l=search(x,(x+y)/2),r=search((x+y)/2+1,y);

m.min=a[l.min] <a[r.min] ?l.min:r.min;

m.max=a[l.max] >a[r.max] ?l.max:r.max;

} returnm;

} }

(6)

Outline

1 Gleichzeitige Suche von Mini- und Maximum

2 Schnelles Suchen

3 Schnelles Sortieren

4 Kryptogramme

5 Nimm

(7)

Partitionierung

Die Partition eines Arrays der Längenbzgl. eines ausgewählten Pivotelementsist eine Aufteilung in zwei Bereiche:

1 eines mit Elementen, die kleiner als das Pivotelement sind

2 eines mit Elementen, die größer als das Pivotelement sind Elemente, die gleich dem Pivotelement sind, können sich beliebig auf die Teillisten verteilen.

(8)

Selektion

DieSelektionsaufgabesucht nach demk.-kleinstenElement (z.B. ist die 3.-kleinste Zahl von 5, 1, 3, 7 die 5).

Dabei rekurriert Programm 7 nach dem Partitionierungsschritt.

Für Permutationen von 1, . . . ,nist dask.-kleinste Element in der aufsteigend sortierten Reihenfolge der Zahlen gleichk, d.h., bei der Eingabe 3 sollte die Ausgabe vergleichbar mit 3,6,1,7,8,4,9,5,2,0,

Quickselect3 = 3 sein.

Das mittlere Element in der sortierten Reihenfolge heißtMedian.

(9)

Programm 2:Selektion mit Quickselect und Sortieren mit Quicksort.

importjava.util.Random;

public classQuick {

private inta[];

/∗∗

Constructor for objects of class Quick

@param n number of array elements

@param k position k for k−th element selection

∗/

publicQuick(intn,intk) { a=new int[n];

Random r=newRandom();

for(inti=0;i<n;i++)a[i] =i;

for(inti=1;i<n;i++)swap(i,r.nextInt(i));

System.out.println("Quickselect "+select(0,n−1,k));

for(inti=1;i<n;i++)swap(i,r.nextInt(i));

sort(0,n−1);

for(inti=0;i<n;i++)System.out.print(a[i]+" ");

System.out.println();

}

voidswap(inti,intj) {intt=a[i];a[i] =a[j];a[j] =t; }

(10)

Programm 3:Selektion mit Quickselect.

public intselect(intleft,intright,intk) { inti,j,v;

i=left;j=right+1;v=a[left];// set pivot do{// partition wrt. pivot

doj−−;while(j>=i&&v<a[j]);

doi++;while(i<=j&&a[i] <v);

if(j>i)swap(i,j);

}while(j>=i);

swap(left,j);// move pivot, end of partitioning if(k==j)returna[k];// element found

returnk<j?select(left,j,k) :select(j+1,right,k);

}

(11)

Outline

1 Gleichzeitige Suche von Mini- und Maximum

2 Schnelles Suchen

3 Schnelles Sortieren

4 Kryptogramme

5 Nimm

(12)

Quicksort

Das ProgrammQuicksortnutzt den gleichen Partionierungsschritt und rekurriert jedoch in beide Arrayhälften, um das Elementarray

letztendlich vollständig anzuordnen.

Quicksort ist noch immer eines derin der Praxis schnellsten Sortierverfahren

Es gibt oft fertige Bibliotheksfunktionen, wieIntrosort

Diese Verfahren wählen für ein (oder zwei) Pivotelement(e) den Median aus mehreren Elementen aus.

Introsortweicht für spezielle Fälle auf andere Sortierverfahren aus.

Die im Erwartungsfallbeste Wahl für das Pivotelementist der Median aus√

nvielen Elementen.

(13)

Programm 4: Sortieren mit Quicksort.

public voidsort(intleft,intright) { inti,j,v;// two indices and one temporary if(right−left> 0) {// interval is non−trivial

i=left;j=right+1;v=a[left];// set pivot do{// partition wrt. pivot

doj−−;while(j>=i&&v<a[j]);

doi++;while(i<=j&&a[i] <v);

if(j>i)swap(i,j);

}while(j>=i);

swap(left,j);// move pivot, end of partitioning

if(j−left<right−i+1) {sort(left,j−1);sort(j+1,right); } else{sort(j+1,right);sort(left,j−1); }

} } }

(14)

QuickXSort

Eine Verallgemeinerung istQuickXSort, bei dem in einem Teil des Arrays ein Sortierverfahren X angewendet wird und im anderen Teil rekuriert wird.

DieAufteilungder Elemente geschiehtumgekehrtzu Quicksort.

Da X nur auf den kleineren der beiden Teile angewendet wird, darf X sich Elemente aus dem größeren Teil und somit aufZusatzspeicher zurückgreifen.

Eine gute Wahl für X mit geringer Vergleichsanzahl istMergesort– einem klassischen Divide-and-Conquer Verfahren, das die zu sortierenden Datenrekursiv in kleinere Teile zerlegt

Die sortierten Teile werden dann imReißverschlussverfahrenzu größeren Teilenzusammengefügt(engl. (to) merge), bis eine sortierte

(15)

Outline

1 Gleichzeitige Suche von Mini- und Maximum

2 Schnelles Suchen

3 Schnelles Sortieren

4 Kryptogramme

5 Nimm

(16)

SEND + MORE = MONEY

EinKryptogramm(engl. Cryptarithm) ist eine mathematische Gleichung, deren Ziffern durch Variablen ersetzt wurden.

AufgabeFinde eine die Gleichung erfüllende Variablenbelegung.

BLAU * ROT VITA * MAX YIN WEG * STADT

--- --- + YANG ---

ANLR WXXX --- DDAET

OINL MWTX TEILT TTGNZ

ALNE WIWG ---

--- WCIG DISTANZ

ANTENNE --- WICHTIG

Das Problem gehört zur Klasse derConstraint-Satisfaction Probleme

(17)

Programm 5:Lösung eines Kryptogramms.

public classArithmetics {

publicArithmetics() {

for(intB=1;B<=9;B++) for(intL=0;L<=9;L++)if(L!=B)

for(intA=1;A<=9;A++)if(A!=L&&A!=B) for(intU=0;U<=9;U++)if(U!=A&&U!=B&&U!=L)

for(intR=1;R<=9;R++)if(R!=U&&R!=A&&R!=B&&R!=L) for(intN=0;N<=9;N++)if(N!=R&&N!=U&&N!=A&&N!=B&&N!=L) for(intT=0;T<=9;T++)if(T!=N&&T!=R&&T!=U&&T!=A&&T!=B&&T!=L)

for(intE=0;E<=9;E++)if(E!=T&&E!=N&&E!=R&&E!=U&&E!=A&&E!=B&&E!=L) for(intO=1;O<=9;O++)

if(O!=E&&O!=T&&O!=N&&O!=R&&O!=U&&O!=A&&O!=B&&O!=L) for(intI=0;I<=9;I++)

if(I!=O&&I!=E&&I!=T&&I!=N&&I!=R&&I!=U&&I!=A&&I!=B&&I!=L) if((B1000 +L100 +A10 +U)(100R+ 10O+T) ==

A1000000 +N100000 +T10000 +E1000 +N∗100 +N10 +E

&& (A1000000 +N100000 +L10000 +R1000 + O10000 +I1000 +N100 +L10 +

A1000 +L100 +N10 +E==

A1000000 +N100000 +T10000 +E1000 +N∗100 +N10 +E)) System.out.println("B="+B+" L="+L+" A="+A+" U="+U+" R="+R+" O="+O+" T="+T);

} }

(18)

Outline

1 Gleichzeitige Suche von Mini- und Maximum

2 Schnelles Suchen

3 Schnelles Sortieren

4 Kryptogramme

5 Nimm

(19)

Zwei Personen: Null Summe?

Viele Löser imZweipersonennullsummenspielwie im Schach beruhen aufMinimax und Alpha-Beta Pruning.

Eingabe istu, Schranken sindα,β. Die Ausgabe ist der ermittelte spieltheoretischer Wert.

Procedure NegmaxAlphaBeta

if(leaf(u))returnEval(u) No successor, static evaluation res←α Initialize valueresfor current frame for eachv ∈Successors(u) Traverse successor list val← −NegmaxAlphaBeta(v,−β,−res) Initialize cut-off value

if(val>res)res←val Updateres

if(res≥β)returnres Perform cut-off

returnres Return final evaluation

Manche Probleme lassen sich aber direkt lösen, z.B.TicTacToeoder Nimm. . .

(20)

Streichholz-Ziehen

Nimmist ein Zweipersonennullsummen-Spiel mit binären Ausgang.

ZustandEs gibtk Zeilen mitai,i =1, . . . ,k, Streichhölzern.

ZugDie Spieler nehmen abwechselndl Streihölzer aus einer Reihe j ∈ {1, . . . ,k}, so dassaj−lHölzer verbleiben.

Verlorenhat derjenige Spieler, der nicht mehr ziehen kann.

Retrograde-KlassifikationZustände lassen sich nach und nach in gewonnenundverloreneinteilen (Annahme: Optimales Spiel) Optimale Strategieberuht auf dem XOR-Wert der Binärzahlen der Streichholzzahl

XOR =bin(a1)⊗. . .⊗bin(ak)

(21)

Programm 6:Spiellogik im Nimm-Spiel.

voidprint() {

for(inti=0;i<size;i++) {

System.out.print(i+". ("+a[i]+"):\t");

for(intj=0;j<a[i];j++) System.out.print("|");

System.out.println();

}

System.out.println("xor :"+xor());

}

public voidtake(inti,intj) { a[i]−=j;

print();

}

public intxor() { intr= 0;

for(inti=0;i<size;i++) r=r^a[i];

returnr;

}

public booleangameover() { intr= 0;

for(inti=0;i<size;i++) r=r+a[i];

return(r==0);

}

(22)

Programm 7:Löser des Nimm-Spiels.

public voidsolve() { intr=xor();

if(r== 0) {

System.out.println("Your move!");

return;

}

System.out.println("My move!");

for(inti=0;i<size;i++) { for(intj=1;j<=a[i];j++) {

if(a[i] >=j) { inttemp=a[i];

a[i]−=j;

if(xor() == 0) {

System.out.println("Taking "+j+" from "+i);

print();

return;

}

a[i] =temp;

} } }

(23)

Merke:

Rekursive Algorithmen verfahren nach dem Prinzip

Teile-und-Herrsche(engl. divide-and-conquer) und lösen das übergeordnete Problem durch die rekursive Lösung der Teilprobleme und das Zusammenführen der rekursiv erzielten Lösungen.

Diskussion (untereinander):

Welche Funktionen (Min/Maximum, Auswählen, Bruchrechnen) braucht man wozu?

Welche Funktionen lassen sich iterativ umsetzen?

Für die automatische Generierung von zufälligen Zahlen wurde die Funktionrandgenommen. Sie liefert bei jedem Programmstart die gleichen Zahlen. Wozu ist das nützlich und wie kann man andere Zahlen generieren?

Referenzen

ÄHNLICHE DOKUMENTE

–  Muss ein Element an einer Stelle dazwischen geschoben werden, dann werden die rechts davon liegenden Elemente jeweils um eine Position nach rechts

Inzwischen gibt es für eine Vielzahl von Problemen randomisierte Algorithmen, die (in dem einen oder anderen Sinne) schneller sind als deterministische Verfahren.. Außerdem

Hauptprogrammiersprache ist Java – Programmierumgebung BlueJ Im imperativen Kern sind die Programmiersprachen oft verwandt: Viele einfache Code-Fragmente lassen sich

Sie sollen das Prinzip Rekursion verstehen und die Mächtigkeit sowie Eleganz der Methode in der Informatik erkennen. Dabei werden die intuitive Problemlösung, deren

Weil das erste Paar schon im ersten Monat Nachwuchs bekommt, kann man es verdoppeln, so dass nach einem Monat 2 Paare da sind.. Von diesen vermehrt sich das erste im zweiten

1 Falls in der i-ten Zeile die Zahl in der i-ten Spalte 0 ist, wird diese Zeile mit einer Zeile unterhalb ausgetauscht, bei der in der i-ten Spalte eine Zahl steht. Falls keine

Die Platten sind in der Größe verschieden und eine kleinere Platte darf niemals unterhalb einer größere Platte liegen!. Das folgende Bild zeigt alle möglichen Zustände mit n =

Eine zufällige Permutation kann dadurch erzeugt werden, dass für alle k aus n − 1,.. ,