Mengenpartitionen

Neue Frage »

angsthase Auf diesen Beitrag antworten »
Mengenpartitionen
Hi,

wir sollen ein Programm schreiben, das alle überkreuzungsfreien Mengenpartitionen angibt (das sind zum beispiel {1,2,5},{3,4} oder {1,2},{3,5},{4}, aber nicht {1,3,4},{2,5} ... wers kennt, weiß jetzt sicher, was ich meine) ... nun, das hab ich jetzt hoffentlich hinbekommen, müsste aber zum testen wissen, wieviele solche partitionen existieren.
hab nun schon im www gesucht, finde aber absolut nix unglücklich . Deswegen frage ich hier nach, falls es jemand wissen sollte, das wär knorke Augenzwinkern .

LG angsthase.
Reksilat Auf diesen Beitrag antworten »
RE: Mengenpartitionen
Sehe ich das richtig, dass die Zahlen 1..n im Kreis angeordnet werden und eine überkreuzungsfreie Partition dann bedeutet, dass sich die Verbindungslinien nicht überschneiden dürfen?
Ansonsten bin ich nämlich überfragt, was das sein soll. Einfach nur Mengenpartition ist hier wohl der falsche Begriff, da es in einer Menge ja keine Strukturen zwischen den einzelnen Elementen gibt.
angsthase Auf diesen Beitrag antworten »

ich kann mir das grad im kreis schwer vorstellen
aber wenn man 2 mengen der partition hat, so muss etweder die eine "in der anderen liegen" und zwar geschlossen (also 2,4 liegt nicht geschlossen in 1,3,5; da die 3 die menge unterbricht; 2,3,4 liegt geschlossen in 1,5) bzw. beide disjunkt sein.
is schwirig zu erklären, aber mann muss quasi die partition geordnet aufschriben können, ohne "falsche" mengen zu schreiben

A:{1,...,6}

überkreuzungsfrei Partition: {1,2,5},{3,4},{6} --> {1,2,{3,4},5},{6}
nicht überkreuzungsfreie Partition: {1,3,6},{2,4,5} --> {1,{2, ... geht nicht weiter,
da 3 in 1. menge und 2. menge noch nicht geschlossen.


is schwer zu erklären ... der prof hats auch nur an die tafel gemalt ... und das geht hier nicht
Reksilat Auf diesen Beitrag antworten »

Malen kann man hier auch. Ich habe zum Beispiel mal gemalt wie ich mir hier die Partitionen vorstelle: Links die Partition {1,2,5}{3,4} (überkreuzungsfrei), rechts {1,4}{2,3,5} (nicht überkreuzungsfrei). Ohne eindeutige Definition ist es schwer, ein Problem vernünftig zu behandeln, aber nach meinem Verständnis habe ich für die Mengen mit 2,3,4,5,6 Elementen die folgenden Zahlen von überkreuzungsfreien Partitionen ermittelt: 2,5,15,42,111 (kann aber sein, dass ich was übersehen habe)

Wie funktioniert eigentlich Dein Algorithmus? Probierst Du einfach alle möglichen Partitionen durch, ob sie überkreuzungsfrei sind?
angsthase Auf diesen Beitrag antworten »

JA, ich produziere erstmal alle und schmeiß dann die raus, die nicht überkreuzungsfrei sind ... das ganze ist recht verwirrend geworden deswegen schwer zu erklären ...

ich sortiere die grundmenge und schau dann, in welcher menge das element liegt ... dann speicher ich die "nummer" der menge (dabei wird nicht nummeriert, wenn vorher schon 2 mal die nummer drin liegt)
dann nehm ich ne neue liste, geh die andere durch und schreib in die neue das "aktuelle" element genau dann, wenns in der neuen noch nicht drin ist, vorne dran - andernfalls lösche ich es von der 1. stelle. wenn es nicht an der 1. stelle steht, sonder zum beispiel an der 3., dann is ne überkreuzung vorhanden --> die partition fliegt raus

so einfach ist das Augenzwinkern
aber ich bin mir halt nicht sicher, ob ich so alle fälle abdecke oder enventuell zu viel rauswerfe ... deswegen wollt ich wissen, wieviele so ne partitionen es gibt

so viele hab ich ... normale partitionen

{1} ----- 1-----1
{1, 2} ----- 2 ----- 2
{1, 2, 3} ----- 5 ----- 5
{1, 2, 3, 4} ----- 14 ----- 15
{1, 2, 3, 4, 5} ----- 41 ----- 52
{1, 2, 3, 4, 5, 6} ----- 123 ----- 203
{1, 2, 3, 4, 5, 6, 7} ----- 375 ----- 877
Reksilat Auf diesen Beitrag antworten »

Also ich versteh' hier nur Bahnhof
Zitat:
ich sortiere die grundmenge und schau dann, in welcher menge das element liegt ... dann speicher ich die "nummer" der menge (dabei wird nicht nummeriert, wenn vorher schon 2 mal die nummer drin liegt)

Was ist die Grundmenge und vor allem was ist "das Element"? verwirrt

Egal, die 14 bei der vierelementigen Menge ist richtig, habe nur was falsch in Erinnerung gehabt. Bei 5 Elementen habe ich aber 42 nach folgendem Schema raus:
1x (1,1,1,1,1)
10x (1,1,1,2)
10x (1,2,2)
10x (1,1,3)
5x (2,3)
5x (1,4)
1x (5)
(In Klammern jeweils die Größe der einzelnen Mengen der Partition)

Edit:
Mir fällt noch eine Implementierungsmöglichkeit ein, um Überkreuzungsfreiheit zu prüfen:
Zerlege für jede Partition die Mengen in alle möglichen Paare von Elementen:
{1,3,5}|{2,4} wird in {1,3}{1,5}{3,5}|{2,4} zerlegt, d.h. wenn {a1,..,an} eine Menge der Partition ist, dann wird sie ersetzt durch alle {ai,aj} 1<=i<j<=n.

Nun kann man relativ leicht überprüfen, ob eine Partition überkreuzungsfrei ist, da man nur alle Paare von verschiedenenen Mengen miteinander vergleichen muss, im obigen Beispiel also:
{1,3} und {2,4} => nicht überkreuzungsfrei!
{1,5} und {2,4}
{3,5} und {2,4} => nicht überkreuzungsfrei!
 
 
Reksilat Auf diesen Beitrag antworten »

Habe mein obiges Verfahren mal implementiert und konnte die folgenden Ergebnisse ermitteln. Für die Mengenmächtigkeit 1-6 auch per Hand bestätigt.



Bei 11 rechnet er noch, mein Verfahren ist auch wirklich sehr grob programmiert.

Edit: 11 hab ich noch angehängt, bei 12 will der Speicher (512MB) nicht mehr.
angsthase Auf diesen Beitrag antworten »

ja, meins geht nicht ... unglücklich

aber ich weiß jetzt, wie die zahlen heißen, die die überkreuzungsfreien partitionen angeben:
binomial(2*i, i)/(i+1) ... Catalan-Zahl
Reksilat Auf diesen Beitrag antworten »

Catalan-Zahl also - wieder was gelernt! Da muss ich mir auch mal die rekursive Vorschrift anschauen, denn bei den kreuzfreien Partitionen habe ich eine solche nicht gleich gesehen.

Hier mal mein Programm, geschrieben mit GAP. Die Befehle sollten allgemeinverständlich sein, die Funktionen PartitionsSet und Tuples sind bei GAP vorimplementiert.

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
for w in [1..20] do;
A:=PartitionsSet( [1..w] ); # Array mit allen Partitionen von {1..w}
count:=0; # Zähler der gekreuzten Partitionen

for z in [1..Size(A)] do; # Läuft über alle Partitionen
B:=A[z]; # In B werden die Teilmengen der Partition gesammelt
n:=Size(B);
T:=[];
for i in [1..n] do
T[i]:=Tuples(B[i],2); # Bildet zur Menge B[i] einen Array aller möglichen Tupel [x,y] mit x,y aus B[i]
od;

p:=0;
for i in [1..n] do # Vergleicht die Mengen i und j der Partition auf Überkreuzungsfreiheit
for j in [(i+1)..n] do
for k in [1..Size(T[i])] do
for l in [1..Size(T[j])] do
F:=Set(T[i][k]); # Ordnet die Tupel, Tupel der Form [x,x] werden auf [x] abgeändert
G:=Set(T[j][l]);
if Size(F)=1 then F:=[F[1],F[1]];fi; # Tupel der Form [x] zurück auf [x,x]
if Size(G)=1 then G:=[G[1],G[1]];fi;
if F[1]<G[1] and G[1]<F[2] and F[2]<G[2] then p:=1;fi; # Vergleich, ob sich die beiden Tupel kreuzen
if F[1]>G[1] and G[1]>F[2] and F[2]>G[2] then p:=1;fi;
od;od;od;od;
count:=count+p;
od;
Print(w," ",Size(A)-count," ",Size(A),"\n");
od;
angsthase Auf diesen Beitrag antworten »

Freude

ich hab es smile

war ganz schön hart Augenzwinkern

ich bedank mich vielmals ... ohne dich wär ich nie auf die idee mit den vergleich der 2er-mengen gekommen.
Neue Frage »
Antworten »



Verwandte Themen

Die Beliebtesten »
Die Größten »
Die Neuesten »