1.) Zusammenfassung: Aussagenlogik, Mengen, Abbildungen Wiederhole die Themen Aussagenlogik, Mengen und Abbildungen. Wir stellen Fragen im Testat! 2.) Partitionen Aufbauend auf: "Grundbegriffe: Elemente und Teilmengen ", "Cartesische Produkte und Abbildungen" Aufgaben: 4 > restart; Definition Partitionen, also Aufteilungen von Mengen in Teilmengen, gehören zu wichtigen Objekten in der Mathematik und auch in den Anwendungen. MATH: Sei eine Menge. Eine Menge von Teilmengen von die folgenden drei Eigenschaften erfüllt: 1) heißt Partition von , falls sie , ( ist die Vereinigung aller Elemente aus (Beachte: Die Elemente von P sind Mengen!) oder jedes Element von kommt mindestens einmal als Element einer Klasse von vor.) 2) (Je zwei verschiedene Mengen aus haben einen leeren Durchschnitt, sie sind (paarweise) disjunkt, wie man sagt; oder: Jedes Element von kommt höchstens einmal als Element einer Klasse von vor.) 3) Die leere Menge ist kein Element von .) Die Bedingungen 1) und 2) zusammen schreibt man manchmal auch so: , Man beachte, dass die Elemente von Teilmengen von sind. Wir wollen sie als Klassen bezeichnen: Die definierende Eigenschaft ist also: Jedes Element von gehört zu genau einer Klasse aus , keine Klasse ist leer. Zunächst zwei triviale Beispiele von Partitionen einer Menge M: > M:={$1..10}; (2.1.1) > P:={M}; # nur eine Klasse (2.1.2) > P:=map(i->{i},M); # jedes Element bildest eine eigene Klasse (2.1.3) Wir wollen die drei definierenden Bedingungen für das letzte Beispiel überprüfen: Test 1: > evalb( `union`(op(P))=M ); true (2.1.4) Test 2: > DISJUNKT:=proc(P::set(set)) local i,k; for i from 2 to nops(P) do for k from 1 to i-1 do if nops(P[i] intersect P[k])>0 then return false; end if; end do; end do; return true; end proc: > DISJUNKT(P); true (2.1.5) Wer es versteht, kann den Test auch wie folgt durchführen: > evalb(map(a->op(map(b->a intersect b,P minus {a})),P) = {{}}) ; true (2.1.6) Test 3: > not({} in P); true (2.1.7) MATH: Was man sich bei einer Partition vorstellt, ist eine Aufteilung der Menge nach bestimmten Gesichtspunkten: z. B. welchen Rest ein Element von beim Teilen durch drei lässt: > Part3:=proc(M::set(integer)) # Unser Programm lässt nur (endliche) Mengen von ganzen Zahlen als Eingabe zu. local P,i; for i from 0 to 2 do P[i]:={} end do; for i in M do P[i mod 3]:=P[i mod 3] union {i} end do; return {seq(P[i],i=0..2)} minus {{}} end proc: > Part3({3,6,8,10,11,13,17}); (2.1.8) ÜBUNG [01]: 1.) Schreibe ein Programm, welches zu einer endlichen Menge ganzer Zahlen eine Partition nach positiven und negativen Zahlen und der Null herstellt. 2.) Teste das Programm an mindestens zwei verschiedenen Beispielen. MATH: Man kann aus zwei Partitionen und derselben Menge eine weitere bilden, indem man die Durchschnitte jeder Klasse von mit jeder von bildet und die leere Menge entfernt. Kommt wieder die Partition heraus, so sagt man, ist feiner als . Hier ist ein Programm, welches diese Operation durchführt: > Schni:=proc(P1::set(set), P2::set(set)) return map(K1->op(map(K2->K1 intersect K2,P1)),P2) minus { {}}; end proc: > M; (2.1.9) > Schni(Part3(M),{{1},{$2..5},{$6..10}}); (2.1.10) ÜBUNG [02]: Vervollständige das obige Programm Schni durch zwei Ergänzungen: 1) Am Anfang soll überprüft werden, ob und (a) Partitionen (b) derselben Menge sind. 2) Verstehe das Programm und füge Kommentare ein. Beachte: Ein Programm ist mit einem mathematischen Satz zu vergleichen: Der Kommentar entspricht der Formulierung des Satzes und der Programmtext dem Beweis. Anzahl der Partitionen einer Menge MATH: Der Begriff der Partition ist schon recht kompliziert. Trotzdem ist es nicht so schwierig, eine sogenannte Rekursionsformel ähnlich zu den Binomialkoeffizienten aufzustellen, welche angibt, wie viele Partitionen von es in Klassen gibt: Sei diese Anzahl . Dann gilt: Dies sieht man sehr einfach so: Man konstruiert aus jeder Partition von in Klassen auf genau Arten eine Partition von in Klassen, indem man das Element der Reihe nach einer der Klassen der Partition von hinzufügt. Es fehlen dann noch die Partitionen von in Klassen, die als eigene Klasse enthalten. Diese sind aber offenbar genau so viele, wie man Partitionen von in Klassen hat. Man muss nur noch und berechnen, wie wir es jetzt tun wollen: > part:=proc(n::posint,k::posint) if k>n then return 0; end if; if k=1 or k=n then return 1; setzen und kann dann rekursiv die Funktion end if; part(n-1,k)*k + part(n-1,k-1); end proc: Ein Beispiel: > part(3,2); 3 > part(10,4); 34105 (2.2.1) (2.2.2) Randbemerkung zur Effizienz von p a r t (freiwillig) Im Begleitpraktikum sind wir selten an der Effizient von Algorithmen oder Implementierungen interessiert. Wir wollen hier aber einmal andeuten, wie man schnellere Programme implementieren kann. Schon die Berechnung von > part(25,10); 1203163392175387500 (2.2.1.1) dauert unnötig lange. Dies liegt daran, dass jeder Funktionswert von p a r t immer neu berechnet wird. Mit Hilfe von option remember werden diese Werte gespeichert. > part:=proc(n::posint,k::posint) option remember; if k>n then return 0; end if; if k=1 or k=n then return 1; end if; part(n-1,k)*k + part(n-1,k-1); end proc: Nun kann man auch größere Werte berechnen. > part(1000,42); 12636074623374848595768501024558865629205667599325656585398456471428\ (2.2.1.2) 2710320518404752779420547189098878536010236309407243310674820199\ 4995187570367480639366251000098490907965498592665586164181569355\ 2698611892238800735176170746351108759879149590118221977573293887\ 5545906650019136602267300103437816955428131610056863626174303586\ 9758298223094896699913125911521875328919730797497618946108051015\ 4791325453226337343317777354921937179812861751975724221347532754\ 4899010729878413883497268380470225775826105660426170073028303332\ 8630797649295515755598879411170112299160191783492710987945088068\ 9709817725974280491312830488234667162091202563539616071404939435\ 2708969000868475632371167266026347106193102427414215274107629226\ 5562735290782669908218321437119311588325847272188458522608707269\ 6835896768814869485247686995553135646865787807555544568552742036\ 7565443733975422397224904750071532363519708997759577432166966010\ 9059660627509180316993076266133031762702211679405722985375691772\ 9496287053592411818648422337900849938179390916948035253940247469\ 8006699478355394893955600562130390209346795245872514910408865640\ 8968404493661318287979216167263590327110518586868856594060759867\ 4306153081317263890939054783616842068755600902303577644313187875\ 3734894549739161559687802629847940594705403796026730292990818217\ 4016704246669553068184531384603092100562337497529703172960792360\ 7591035738109227014230105359629346302911239436622383393172734580\ 0826831154609114924481455540359370067066884167203378604741904545\ 4911429944958060400239889760557690273361643736731299552191324484\ 291189833241641761276855267545040 Dieses Programmierprinzip nennt man dynamische Programmierung. Wir verweisen auf die Vorlesung "Algorithmen und Datenstrukturen" und werden hier nicht weiter darauf eingehen. Erinnerung: Eine Menge der Kardinalität hat Teilmengen. ÜBUNG [03]: Erkläre folgende Anzahlen durch Vergleich mit der Anzahl aller Teilmengen einer endlichen Menge: > map(part,[$3..40],2); (2.2.3) Hinweis: > 2^3,part(4,2)+1; 2^4,part(5,2)+1; 2^5,part(6,2)+1; (2.2.4) Wir wollen nun nicht mehr nur die Anzahl der Partitionen bestimmen sondern alle Partitionen angeben. > PartExt:=proc(P::set(set),n) local PP, M, Pneu; if convert(map(S->n in S,P),`or`) then error "wrong input"; end if; PP:={}; for M in P do Pneu:=subs(M=M union {n},P); PP:=PP union {Pneu} end do; Pneu:=P union {{n}}; PP:=PP union {Pneu}; end proc: > PartExt({{a,b}},c); (2.2.5) > PartExt({{a},{b}},c); (2.2.6) > PartExt({{1},{2}},3); (2.2.7) ÜBUNG [04]: 1) Verstehe und analysiere das obige Programm P a r t E x t. Beschreibe, was das Programm macht. Füge Kommentare ein. 2) Benutze P a r t E x t, um alle Partitionen von zu konstruieren. Die Gesamtzahl sollte > add(part(4,i),i=1..4); 15 (2.2.8) sein. 3) Schreibe ein Programm, das P a r t E x t benutzt, um alle Partitionen einer gegebenen endlichen Menge zu konstruieren. 4) Teste das Programm am Beispiel der Menge . Die Gesamtzahl der Partitionen sollte > add(part(6,i),i=1..6); 203 (2.2.9) sein. DENKANSTOSS: Die folgende Matrix sagt uns, wieviele surjektive Abbildungen von nach für , existieren. Warum? > Matrix(10,6,(i,j)->part(i,j)*j!); (2.2.10) Im gleichen Sinne: Was ist hier los? > map(i->evalf(part(i,3)/3^i),[$1..70]); (2.2.11) (2.2.11) > evalf(1/6); 0.1666666667 (2.2.12) Wir werden später darauf zurückkommen, wenn wir uns mit Konvergenz befasst haben. 3.) Äquivalenzrelationen Aufbauend auf: "Grundbegriffe: Elemente und Teilmengen ", "Cartesische Produkte und Abbildungen", "Partitionen" Aufgaben: 3 > restart; Definition und Beispiele Äquivalenzrelationen verallgemeinern Gleichheit. Es handelt sich um die Gleichheit unter einem gewissen Aspekt. Formal führt man diesen grundlegenden Begriff wie folgt ein: MATH: Man nennt eine Relation auf einer Menge . heißt reflexiv, falls gilt: . heißt symmetrisch, falls gilt: . heißt transitiv, falls gilt: Wir schreiben auch anstatt . MATH: Eine Relation auf einer Menge symmetrisch und transitiv ist. . heißt Äquivalenzrelation, wenn sie reflexiv, Offenbar ist eine Äquivalenzrelation auf : Je zwei Elemente sind äquivalent. (DENKANSTOSS: Warum?) Weiter: Ist die disjunkte Vereinigung zweier Teilmengen , also , so ist ebenfalls eine Äquivalenzrelation auf . (DENKANSTOSS: Warum?) Disjunkte Vereinigungen sollten uns an Partitionen erinnern: > P:={{1,2,3},{4,5,6,7},{8,9,10}}; (3.1.1) > RP:=map(a->op(map(b->op(map(c->[b,c],a)),a)),P); (3.1.2) ÜBUNG [01]: Sind folgende Relationen Äquivalenzrelationen? 1) > { [1,1], [2,2], [3,3], [1,2], [2,1] }; (3.1.3) 2) > { [1,1], [2,2], [3,3], [1,2], [2,1], [2,3], [3,2] }; (3.1.4) 3) 4) , . , für eine beliebige Menge , . Äquivalenzklassen MATH: Ist eine Äquivalenzrelation auf und , so heißt die Menge die Äquivalenzklasse von . Jedes Element einer Äquivalenzklasse heißt auch Vertreter seiner Klasse. Es gilt offenbar: . Die Menge der Äquivalenzklassen bildet eine Partition von . Diese Partition wird mit bezeichnet. Eine Teilmenge von , die aus jeder Äquivalenzklasse genau einen Vertreter enthält und darüberhinaus keine weiteren Elemente, heißt Vertretersystem oder Transversale. Hier ist ein Programm zur Bestimmung der Äquivalenzklasse eines Elementes: > AeKla:=proc(n::nonnegint,R::set(list(nonnegint))) return map(j->j[2],select(i->i[1]=n,R)); end proc: > AeKla(1,RP); (3.2.1) > map(a->AeKla(a[1],RP),RP); (3.2.2) MATH: Wir halten die grundlegende Tatsache fest, dass Äquivalenzrelationen und Partitionen verschiedene Beschreibungen derselben Sache sind. Hier ist nun noch ein weiteres fundamentales Beispiel einer Äquivalenzrelation: Die Bildgleichheit. Ist eine Abbildung, so heißen bildgleich, wenn . Dies ist offenbar eine Äquivalenzrelation. (DENKANSTOSS: Warum?) Die zugehörige Partition ist die Partition der Fasern von . Hier ist ein Programm, welches diese Äquivalenzrelation herstellt: > Bilglei:=proc(M::set, f::procedure) local S; map(a->op(map(b-> if f(a)=f(b) then [a,b] end if,M)),M); end proc: > f:=x->x mod 5; (3.2.3) > M:={$1..20}; (3.2.4) > M5:=Bilglei(M,f); (3.2.5) > map(a->AeKla(a[1],M5),M5); (3.2.6) DENKANSTOSS: Wieviele Transversalen hat diese Äquivalenzrelation? ÜBUNG [02]: Sei deine Matrikelnummer, und Wieviele Transversalen hat die Äquivalenzrelation der Fasern von ? . Zusammenhang: Abbildungen, Partitionen und Äquivalenzrelationen Wenn du bislang alles verstanden hast, ist der nachfolgende sehr wichtige Satz sehr einfach einzusehen. Trotzdem ist er Ausdruck einer der erfolgreichsten Philosophien, an algebraische und kombinatorische Probleme heranzugehen. MATH: ("Homomorphiesatz für Mengen") Sei 1) Die Menge der nichtleeren Fasern von bildet eine Partition von "Bildgleichheit unter ". 2) Die Abbildung eine Abbildung. Dann gilt: mit zugehöriger Äquivalenzrelation ist eine surjektive Abbildung. 3) Die Abbildung ist eine (wohldefinierte) injektive Abbildung. 4) Für die Komposition gilt . DENKANSTOSS: Gehe 1) bis 4) mit folgendem Beispiel durch: sei eine Menge von Briefen, die von Aachen aus verschickt werden sollen, sei eine Menge von Städten, so dass jede Stadt auf einer der Anschriften in bei vorkommt. sei die Abbildung, die jedem Brief seinem Bestimmungsort zuordnet. Am Ende deiner Analyse solltest du eingesehen haben, dass es sich lohnt, die Briefe nach Städten zu ordnen, bevor man sie losschickt. Wir haben bereits Programme, die alle vorkommenden Objekte konstruieren können. > showstat(f); f := proc(x) 1 `mod`(x,5) end proc > M:={$3..20}; (3.3.1) > M5:=Bilglei(M,f); (3.3.2) > F:=map(a->AeKla(a,M5),M); (3.3.3) > f1:=map(a->op(map(S -> if a in S then [a,S] end if,F)),M); (3.3.4) > f2:=map(A->[A,f(A[1])],F); (3.3.5) Wir lassen es als Übung, zu sehen, dass die Komposition von und > map(a->[a,f(a)],M); gleich dem Folgenden ist: (3.3.6) ÜBUNG [03]: 1) Verstehe die obigen Aussagen 1) bis 4) des Homomorphiesatzes und erkläre sie an dem obigen Beispiel mit f , f 1 und f 2. 2) Insbesondere: was bedeutet "wohldefiniert" in 3)? Hinweis: Was passiert, wenn ? 3) Sei eine Menge. Begründe, dass Partitionen und Äquivalenzrelationen das selbe Konzept mit verschiedenen Sprachen beschreiben. Gib dazu eine (natürliche) Bijektion zwischen der Menge aller Partitionen von und der Menge aller Äquivalenzrelationen auf an. Hinweis: Äquivalenzklassen. 4) Mach aus dem folgenden informellen Satz eine formelle mathematische Aussage und beweise diese: "Jede Äquivalenzrelation (oder Partition) lässt sich als als Bildgleichheitsrelation einer surjektiven Abbildung beschreiben." Hinweis: Nutze die Abbildung, die ein Element auf seine Äquivalenzklasse schickt. 5) Rekonstruiere f aus f 2 (als Menge von Paaren). 4.) Dreieckszahlen, Abzählbarkeit von < Aufbauend auf dem Abschnitt: "Fasern" Aufgaben: 2 > restart; Dreieckszahlen Der Inhalt dieses Abschnittes ist in der Populärwissenschaft unter dem Stichwort "Hilberts Hotel" bekannt. Erinnerung: Eine Folge ist eine Abbildung von der Menge der natürlichen Zahlen in eine vorgegebene Menge. MATH: Eine interessante Folge ist die Folge der Dreieckszahlen, d.h. der Anzahlen der Einsen in folgenden Matrizen (bis ins Unendliche fortzusetzen!): > map(n->Matrix(n,n,(i,j)->if i+j<n+2 then 1 else 0 end if), [$1..7]); (4.1.1) Mit anderen Worten ist die Folge der Dreieckszahlen gleich der Summen der natürlichen Zahlen von 1 bis n: > a:=(n::posint)->sum(i,i=1..n); (4.1.2) > map(a, [$1..10]); (4.1.3) MATH: Der zehnjährige Carl Friedrich Gauß kannte diese Folge bereits, weil er erkannte, dass sie gleich der folgenden Folge ist: > b:=(n::posint)->sum((n+1-i),i=1..n); (4.1.4) > map(b, [$1..10]); (4.1.5) Nun kann man berechnen, > Sum(i,i=1..n)+Sum((n+1-i),i=1..n); (4.1.6) was aber gleich ist. Also ist unsere Folge gegeben durch > factor(expand(binomial(n+1,2))); (4.1.7) > map(n->binomial(n+1,2), [$1..10]); (4.1.8) MATH: Als Anwendung dieser Folge geben wir eine bijektive Abbildung an: > f:=(i::Or(posint,symbol),j::Or(posint,symbol))->binomial(i+ j-1,2)+i; (4.1.9) Hierbei ist z. B. die Einschränkung dieser Abbildung auf : > A:=Matrix(7,7,(i,j)->f(i,j)); (4.1.10) ÜBUNG [01]: 1) Erkläre den Zusammenhang zwischen der oben definierten Abbildung und den Dreieckszahlen ausgehend von dieser Matrix. 2) Erkläre die Gleichung . Welcher Zusammenhang besteht zur obigen Matrix ? (Hinweis: Wir haben in Teil (1) gesehen, dass eine Dreickszahl ist.) > f(3,4),f(5,1)+3; (4.1.11) MATH: Wenn wirklich bijektiv ist, so sollten wir ein Rechts- und ein Linksinverses haben, die beide übereinstimmen, kurz ein Inverses. > f(i,j); (4.1.12) zu bestimmen, dann i. Hierzu lösen wir die obige Gleichung Es bietet sich an, zuerst nach k auf: > solve(expand(binomial(k-1,2))+1-n,k); (4.1.13) Beachte, nur die erste Lösung ist relevant. Diese ist aber nicht immer ganzzahlig. Dieses Problem soll durch das folgende Programm (F i für "f invers") gelöst werden: > Fi:=proc(n::posint) local k,i,j; k:=floor(3/2+1/2*(-7+8*n)^(1/2)); i:=n-binomial(k-1,2); j:=k-i; return [i,j]; end proc: > map(Fi, [$1..20]);; (4.1.14) DENKANSTOSS: Wie kommt dieses Inverse genau zustande? MATH: Anwendung: Die Menge der rationalen Zahlen ist abzählbar (oder abzählbar unendlich), d. h., es gibt eine bijektive Abbildung von ; , der Menge der natürlichen Zahlen, auf < , die Menge der rationalen Zahlen. Wir beschränken uns auf die positiven rationalen Zahlen. Wir geben auch keine genaue Bijektion zwischen und der Menge der positiven rationalen Zahlen an, sondern nur eine surjektive Abbildung von auf diese Menge. (Warum genügt das?) > FiQ:=proc(n::posint) local l; l:=Fi(n); return op(l)[1]/op(l)[2]; end proc: (FiQ für "f invers nach ") > map(FiQ,[$1..30]); (4.1.15) ÜBUNG [02]: 1) Zeige, dass jede Faser der Abbildung FiQ unendlich ist. 2) Begründe die (obige) Aussage: Die Existenz einer surjektiven Abbildung von auf diese Menge der positiven rationalen Zahlen impliziert, dass abzählbar ist. Hinweis: Zeige, dass jede unendliche Teilmenge von abzählbar ist. 3) Programmiere eine bijektive Funktion in Maple, welche nachweist, dass abzählbar ist. (Hinweis: bijektiv oder bijektiv angeben) 4) Beweise, dass die Menge der rationalen Zahlen abzählbar ist. (Hinweis: Benutze Aufgabenteile 2 und 3.) >