Hallo liebe Community,
Vorher ein Hinweis: Dieser Thread ist sehr lang, und ich habe versucht, alle meine Gedanken so gut es mir möglich war, darzulegen. Das Thema ist wahrscheinlich eines für Nerds oder Leute, die gerne sehr knifflige Probleme lösen.
Zu meinem Ziel:
Ich möchte mithilfe von PHP berechnen, welche möglichen Fellfarben Jungtiere erhalten, wenn zwei Elterntiere verpaart werden.
Nehmen wir das schwarze Kaninchen A, und das weiße Kaninchen B.
Dabei gelten folgende Rahmenbedingungen, die aus der Biologie bekannt sind:
* Die Farbe eines Tierfells wird durch einzelne Farbmerkmale bestimmt.
* Ein Farbmerkmal ist entweder gar nicht (xx), einfach (von einer Elternseite, Xx) oder doppelt (von beiden Elternseiten, XX) vorhanden.
* Des weiteren gibt es in etwa zwanzig Farbmerkmale
* Dadurch ergeben sich 3^20 mögliche Farbkombinationen = 1.048.576
* Für diese Farbkombinationen gibt es jeweils eigene Namen, auch davon gut über 200
* Farbmerkmale können im Gencode versteckt sein, und bei Kombination von zwei Elterntieren bei den Jungtieren wieder hervortreten
* Dadurch gilt nicht: Brauner Hase + Brauner Hase ist 100% brauner Hase. Es könnte unerwartet ein weißer Hase herauskommen.
Wenn zwei Tiere verpaart werden, werden Farbmerkmale nach dem nachfolgenden Schema mit den notierten Wahrscheinlichkeiten vererbt:
* XX + XX = 100% XX
* Xx + Xx = 25% XX, 50% Xx, 25% xx
* XX + xx = 100% Xx
* XX + Xx = 50% XX, 50% Xx
* Xx + xx = 50% Xx, 50% xx
* xx + xx = 100% xx
Zunächst habe ich für mich festgelegt, dass ich, da es sich ja um Programmierung handelt, festlege, dass
* xx = 0
* Xx = 1
* XX = 2
Für die Berechnung der möglichen Elterncodes habe ich mir bereits eine Klasse geschrieben, die die gegebenen Daten der Eltern auswertet und ein Array mit möglichen Farbcodes der Jungtiere berechnet.
Nun stehe ich vor dem Problem, dass jedem Farbcode z.B. 01220120120120102102, ein Farbname zugeordnet werden muss. Das bedeutet, dass alle Codes am besten in einer Datenbank gespeichert und anschließend durch ein weiteres Programm den Farbnamen zugeordnet werden müssen.
Problem A:
Ich möchte alle 1.048.576 Codes durch ein Programm in eine Datenbank eintragen lassen, sodass keines fehlt oder doppelt vorkommt. Und zugegebenermaßen habe ich keine Ahnung, wie ich dieses Problem am geschicktesten lösen kann. Ich habe irgendetwas improvisiert. Es handelt sich dabei quasi um eine Ziehung aus einer Urne mit drei verschiedenfarbigen Kugeln mit anschließendem Zurücklegen und 20 Durchgängen.
Spontan kamen mir folgende Gedanken:
Kartesische Produkte, die aus der Mengenlehre stammen. Kartesische Produkte sind die Menge aller Kombinationsmöglichkeiten der Elemente zweier Mengen.
In meinem Fall wäre das die Menge:
Menge A = {0, 1, 2}
Das kartesische Produkt von
A x A = {(0,0),(0,1),(0,2),(1,0), ... } => Kombinationen aus zwei Elementen
Wenn ich jetzt B = A x A nehme, und B x B rechne, erhalte ich {((0,0),(0,0)),((0,1),(0,0)),... } => Kombinationen mit 4 Elementen
Wenn ich jetzt C = B x B nehme, und C x C rechne, erhalte ich {(((0,0),(0,0)),((0,1),(0,0))),(((0,0),(0,0)),((0, 1),(0,0))), ... } => Kombinationen mit 8 Elementen
... Somit erhalte ich bei D = C x C alle Kombinationen mit 16 Elementen
Für B x D erhalte ich somit alle Kombinationen mit 20 Elementen.
Meine erste Zwischenfrage:
Erhalte ich wirklich alle Kombinationsmöglichkeiten für 0,1,2 aus 20 Elementen mit der von mir erdachten Bearbeitungsweise?
Ungeachtet dessen bin ich weitergegangen und habe das ganze auf die Programmierung übertragen:
Eine Menge kann man in der Programmierung natürlich mit einem Array vergleichen.
Also in meinem Fall wäre dies jetzt $a = [0,1,2];
Ich habe keine Möglichkeit gefunden, kartesische Produkte zweier Arrays in PHP zu bilden. Also habe ich mir Gedanken gemacht, wie ich dies "händisch" lösen kann.
Wenn ich jetzt $a[0] mit $a[0] verknüpfe, erhalte ich 00
Für $a[1] mit $a[1], erhalte ich 11,
Für $a[2] mit $a[2], erhalte ich 22
Um ein kartesisches Produkt zu erhalten, würde ich jetzt ein zweites Array b erstellen, das ich mit a gleichsetze, und mit hilfe einer Schleife das letzte Element des Array an erste Stelle ziehen.
Dadurch erhalte ich:
$a = [0,1,2] x $b = [0,1,2] => 00, 11, 22
$a = [0,1,2] x $b = [2,0,1] => 02, 10, 21
$a = [0,1,2] x $b = [1,2,0] => 01, 12, 20
Das heißt, ich muss die Kardinalität n (die Anzahl der Elemente) des Array ermitteln, und n-1 mal das letzte Element des Array an erste Stelle setzen.
Mithilfe einer rekursiven Funktion würde ich das drei mal machen, und immer das Array der im letzten Durchlauf ermittelten Verknüpfungen nutzen.
Am Ende würde ich das Ergebnis nach dem dritten Durchlauf mit dem Ergebnis des ersten Durchlauf wie dargestellt verknüpfen, und in der Datenbank ablegen.
Problem B:
Jetzt mache ich mir Sorgen, ob PHP oder allgemein mein Rechner das schaffen kann.
Am Ende müsste er ja hunderdtausende Objekten verknüpfen... das ganze speichern... und zwischendurch nicht flöten gehen. Auch nimmt die Speichergröße der Array-Elemente ja mit jedem Durchgang zu.
Oder ist meine Befürchtung grundlos?
Meine zweite Frage also:
Wie löse ich das ganze also am elegantesten und ressourcenschonendsten?
Jeder, der sich bis hierher durchgekämpft hat, verdient von mir schon mal den größten Respekt! Ich verneige mich vor euch.
Wenn ich etwas so ausgedrückt habe, dass ihr mir nicht folgen könnt, bitte: Fragt nach, dann kläre ich das so schnell ich kann.
Wenn ihr keine "Komplettlösung" (also die direkte Antwort) sondern nur Ergänzungen (also weiterführende Ideen) habt: Auch diese nehme ich sehr, sehr gerne an.
Wenn ich Informationen ergänzen soll, so werde ich auch dies tun.
Ich danke euch vielmals für eure Gedanken, eure Zeit und eure Hilfsbereitschaft!
Gruß,
Mina
Vorher ein Hinweis: Dieser Thread ist sehr lang, und ich habe versucht, alle meine Gedanken so gut es mir möglich war, darzulegen. Das Thema ist wahrscheinlich eines für Nerds oder Leute, die gerne sehr knifflige Probleme lösen.
Zu meinem Ziel:
Ich möchte mithilfe von PHP berechnen, welche möglichen Fellfarben Jungtiere erhalten, wenn zwei Elterntiere verpaart werden.
Nehmen wir das schwarze Kaninchen A, und das weiße Kaninchen B.
Dabei gelten folgende Rahmenbedingungen, die aus der Biologie bekannt sind:
* Die Farbe eines Tierfells wird durch einzelne Farbmerkmale bestimmt.
* Ein Farbmerkmal ist entweder gar nicht (xx), einfach (von einer Elternseite, Xx) oder doppelt (von beiden Elternseiten, XX) vorhanden.
* Des weiteren gibt es in etwa zwanzig Farbmerkmale
* Dadurch ergeben sich 3^20 mögliche Farbkombinationen = 1.048.576
* Für diese Farbkombinationen gibt es jeweils eigene Namen, auch davon gut über 200
* Farbmerkmale können im Gencode versteckt sein, und bei Kombination von zwei Elterntieren bei den Jungtieren wieder hervortreten
* Dadurch gilt nicht: Brauner Hase + Brauner Hase ist 100% brauner Hase. Es könnte unerwartet ein weißer Hase herauskommen.
Wenn zwei Tiere verpaart werden, werden Farbmerkmale nach dem nachfolgenden Schema mit den notierten Wahrscheinlichkeiten vererbt:
* XX + XX = 100% XX
* Xx + Xx = 25% XX, 50% Xx, 25% xx
* XX + xx = 100% Xx
* XX + Xx = 50% XX, 50% Xx
* Xx + xx = 50% Xx, 50% xx
* xx + xx = 100% xx
Zunächst habe ich für mich festgelegt, dass ich, da es sich ja um Programmierung handelt, festlege, dass
* xx = 0
* Xx = 1
* XX = 2
Für die Berechnung der möglichen Elterncodes habe ich mir bereits eine Klasse geschrieben, die die gegebenen Daten der Eltern auswertet und ein Array mit möglichen Farbcodes der Jungtiere berechnet.
Nun stehe ich vor dem Problem, dass jedem Farbcode z.B. 01220120120120102102, ein Farbname zugeordnet werden muss. Das bedeutet, dass alle Codes am besten in einer Datenbank gespeichert und anschließend durch ein weiteres Programm den Farbnamen zugeordnet werden müssen.
Problem A:
Ich möchte alle 1.048.576 Codes durch ein Programm in eine Datenbank eintragen lassen, sodass keines fehlt oder doppelt vorkommt. Und zugegebenermaßen habe ich keine Ahnung, wie ich dieses Problem am geschicktesten lösen kann. Ich habe irgendetwas improvisiert. Es handelt sich dabei quasi um eine Ziehung aus einer Urne mit drei verschiedenfarbigen Kugeln mit anschließendem Zurücklegen und 20 Durchgängen.
Spontan kamen mir folgende Gedanken:
Kartesische Produkte, die aus der Mengenlehre stammen. Kartesische Produkte sind die Menge aller Kombinationsmöglichkeiten der Elemente zweier Mengen.
In meinem Fall wäre das die Menge:
Menge A = {0, 1, 2}
Das kartesische Produkt von
A x A = {(0,0),(0,1),(0,2),(1,0), ... } => Kombinationen aus zwei Elementen
Wenn ich jetzt B = A x A nehme, und B x B rechne, erhalte ich {((0,0),(0,0)),((0,1),(0,0)),... } => Kombinationen mit 4 Elementen
Wenn ich jetzt C = B x B nehme, und C x C rechne, erhalte ich {(((0,0),(0,0)),((0,1),(0,0))),(((0,0),(0,0)),((0, 1),(0,0))), ... } => Kombinationen mit 8 Elementen
... Somit erhalte ich bei D = C x C alle Kombinationen mit 16 Elementen
Für B x D erhalte ich somit alle Kombinationen mit 20 Elementen.
Meine erste Zwischenfrage:
Erhalte ich wirklich alle Kombinationsmöglichkeiten für 0,1,2 aus 20 Elementen mit der von mir erdachten Bearbeitungsweise?
Ungeachtet dessen bin ich weitergegangen und habe das ganze auf die Programmierung übertragen:
Eine Menge kann man in der Programmierung natürlich mit einem Array vergleichen.
Also in meinem Fall wäre dies jetzt $a = [0,1,2];
Ich habe keine Möglichkeit gefunden, kartesische Produkte zweier Arrays in PHP zu bilden. Also habe ich mir Gedanken gemacht, wie ich dies "händisch" lösen kann.
Wenn ich jetzt $a[0] mit $a[0] verknüpfe, erhalte ich 00
Für $a[1] mit $a[1], erhalte ich 11,
Für $a[2] mit $a[2], erhalte ich 22
Um ein kartesisches Produkt zu erhalten, würde ich jetzt ein zweites Array b erstellen, das ich mit a gleichsetze, und mit hilfe einer Schleife das letzte Element des Array an erste Stelle ziehen.
Dadurch erhalte ich:
$a = [0,1,2] x $b = [0,1,2] => 00, 11, 22
$a = [0,1,2] x $b = [2,0,1] => 02, 10, 21
$a = [0,1,2] x $b = [1,2,0] => 01, 12, 20
Das heißt, ich muss die Kardinalität n (die Anzahl der Elemente) des Array ermitteln, und n-1 mal das letzte Element des Array an erste Stelle setzen.
Mithilfe einer rekursiven Funktion würde ich das drei mal machen, und immer das Array der im letzten Durchlauf ermittelten Verknüpfungen nutzen.
Am Ende würde ich das Ergebnis nach dem dritten Durchlauf mit dem Ergebnis des ersten Durchlauf wie dargestellt verknüpfen, und in der Datenbank ablegen.
Problem B:
Jetzt mache ich mir Sorgen, ob PHP oder allgemein mein Rechner das schaffen kann.
Am Ende müsste er ja hunderdtausende Objekten verknüpfen... das ganze speichern... und zwischendurch nicht flöten gehen. Auch nimmt die Speichergröße der Array-Elemente ja mit jedem Durchgang zu.
Oder ist meine Befürchtung grundlos?
Meine zweite Frage also:
Wie löse ich das ganze also am elegantesten und ressourcenschonendsten?
Jeder, der sich bis hierher durchgekämpft hat, verdient von mir schon mal den größten Respekt! Ich verneige mich vor euch.
Wenn ich etwas so ausgedrückt habe, dass ihr mir nicht folgen könnt, bitte: Fragt nach, dann kläre ich das so schnell ich kann.
Wenn ihr keine "Komplettlösung" (also die direkte Antwort) sondern nur Ergänzungen (also weiterführende Ideen) habt: Auch diese nehme ich sehr, sehr gerne an.
Wenn ich Informationen ergänzen soll, so werde ich auch dies tun.
Ich danke euch vielmals für eure Gedanken, eure Zeit und eure Hilfsbereitschaft!
Gruß,
Mina
Kommentar