Hallo zusammen,
meine Frage gilt vor allem der Performance - und der bestmöglichen Umsetzung.
Ich würde gerne das Game Of Life in einem 3 - Dimensionalen Array darstellen. Einen ersten Entwurf habe ich bereits im SingleThread fertig.
Nur ist die Geschwindigkeit extrem langsam. Ein 1000x1000x500 Array (Boolsche Werte) zu berechnen dauert über 5 Minuten.
Vorteil ist das ich für die Spätere Darstellung direkt weiß, wo ich den Block zeichnen muss wenn ich mit x,y und z die Schleife laufen lasse.
Nachteil ist das ich bei einer Dichte von ~10% die übrigen 90% tzd überprüfe - was dann sinnlose Arbeitszeit beansprucht.
Ich könnte das Array auch in einzelne Chunks unterteilen, und parallel Berechnen lassen. Würde das Abhilfe Schaffen? Es bleiben tzd. 500mio zu überprüfen.
Mein 2ter Ansatz wäre folgender:
Eine List(of Vector3D) als Hilfe holen, die meine aktiven Zellen zwischenspeichert. Nun muss ich nicht mehr die 500mio überprüfen, sondern nur das was in der Liste ist.
Das Problem dabei ist: Ich hole mir immer die Nachbarn um die Zelle.(Wie ein RubixCube, in der Mitte ist sozusagen die Zelle um die es geht, und alles drum herum sind die Nachbarn von denen der Zustand der Zentralen Zelle abhängt).
Ich erstelle mir also einen Abstrackten Würfel, der die Zellen um die Aktive angibt:
Spoiler anzeigen
Und diese Zellen hole ich mir aus dem Array, würde ich diese in der Liste suchen, müsste ich die Liste pro Eintrag nochmal 24 durchgehen, um zu überprüfen ob die Zelle vorhanden ist.
Das bedeutet für mich, ich bräuchte sowohl das Array inklusive der Liste. Ich gehe aber nicht alle Bereiche im Array durch, sondern nur die in der Liste.
Hoffe ihr versteht ungefähr wo meine Überlegung hingeht.
LG
meine Frage gilt vor allem der Performance - und der bestmöglichen Umsetzung.
Ich würde gerne das Game Of Life in einem 3 - Dimensionalen Array darstellen. Einen ersten Entwurf habe ich bereits im SingleThread fertig.
Nur ist die Geschwindigkeit extrem langsam. Ein 1000x1000x500 Array (Boolsche Werte) zu berechnen dauert über 5 Minuten.
Vorteil ist das ich für die Spätere Darstellung direkt weiß, wo ich den Block zeichnen muss wenn ich mit x,y und z die Schleife laufen lasse.
Nachteil ist das ich bei einer Dichte von ~10% die übrigen 90% tzd überprüfe - was dann sinnlose Arbeitszeit beansprucht.
Ich könnte das Array auch in einzelne Chunks unterteilen, und parallel Berechnen lassen. Würde das Abhilfe Schaffen? Es bleiben tzd. 500mio zu überprüfen.
Mein 2ter Ansatz wäre folgender:
Eine List(of Vector3D) als Hilfe holen, die meine aktiven Zellen zwischenspeichert. Nun muss ich nicht mehr die 500mio überprüfen, sondern nur das was in der Liste ist.
Das Problem dabei ist: Ich hole mir immer die Nachbarn um die Zelle.(Wie ein RubixCube, in der Mitte ist sozusagen die Zelle um die es geht, und alles drum herum sind die Nachbarn von denen der Zustand der Zentralen Zelle abhängt).
Ich erstelle mir also einen Abstrackten Würfel, der die Zellen um die Aktive angibt:
VB.NET-Quellcode
- Private Function GetActive(ByVal pk As Point3D) As Integer 'Gibt den Wert zurück, wv Nachbarn leben
- Dim EP1, EP2, EP3, EP4, EP5, EP6, EP7, EP8, EP9 As Point3D
- Dim MP1, MP2, MP3, MP4, MP5, MP6, MP7, MP8 As Point3D
- Dim HP1, HP2, HP3, HP4, HP5, HP6, HP7, HP8, HP9 As Point3D
- With pk
- 'Die Erste Ebne
- EP1 = New Point3D(.X - 1, .Y - 1, .Z - 1)
- EP2 = New Point3D(.X, .Y - 1, .Z - 1)
- EP3 = New Point3D(.X + 1, .Y - 1, .Z - 1)
- EP4 = New Point3D(.X - 1, .Y, .Z - 1)
- EP5 = New Point3D(.X, .Y, .Z - 1)
- EP6 = New Point3D(.X + 1, .Y, .Z - 1)
- EP7 = New Point3D(.X - 1, .Y + 1, .Z - 1)
- EP8 = New Point3D(.X, .Y + 1, .Z - 1)
- EP9 = New Point3D(.X + 1, .Y + 1, .Z - 1)
- 'Die Mittlere Ebne
- MP1 = New Point3D(.X - 1, .Y - 1, .Z)
- MP2 = New Point3D(.X, .Y - 1, .Z)
- MP3 = New Point3D(.X + 1, .Y - 1, .Z)
- MP4 = New Point3D(.X - 1, .Y, .Z)
- MP5 = New Point3D(.X + 1, .Y, .Z)
- MP6 = New Point3D(.X - 1, .Y + 1, .Z)
- MP7 = New Point3D(.X, .Y + 1, .Z)
- MP8 = New Point3D(.X + 1, .Y + 1, .Z)
- 'Die Hintere Ebne
- HP1 = New Point3D(.X - 1, .Y - 1, .Z + 1)
- HP2 = New Point3D(.X, .Y - 1, .Z + 1)
- HP3 = New Point3D(.X + 1, .Y - 1, .Z + 1)
- HP4 = New Point3D(.X - 1, .Y, .Z + 1)
- HP5 = New Point3D(.X, .Y, .Z + 1)
- HP6 = New Point3D(.X + 1, .Y, .Z + 1)
- HP7 = New Point3D(.X - 1, .Y + 1, .Z + 1)
- HP8 = New Point3D(.X, .Y + 1, .Z + 1)
- HP9 = New Point3D(.X + 1, .Y + 1, .Z + 1)
- End With
- 'Nun müssen wir die Randbereiche Kontrollieren
- EP1.CheckCross(Breite, Höhe, Tiefe)
- EP2.CheckCross(Breite, Höhe, Tiefe)
- EP3.CheckCross(Breite, Höhe, Tiefe)
- EP4.CheckCross(Breite, Höhe, Tiefe)
- EP5.CheckCross(Breite, Höhe, Tiefe)
- EP6.CheckCross(Breite, Höhe, Tiefe)
- EP7.CheckCross(Breite, Höhe, Tiefe)
- EP8.CheckCross(Breite, Höhe, Tiefe)
- EP9.CheckCross(Breite, Höhe, Tiefe)
- MP1.CheckCross(Breite, Höhe, Tiefe)
- MP2.CheckCross(Breite, Höhe, Tiefe)
- MP3.CheckCross(Breite, Höhe, Tiefe)
- MP4.CheckCross(Breite, Höhe, Tiefe)
- MP5.CheckCross(Breite, Höhe, Tiefe)
- MP6.CheckCross(Breite, Höhe, Tiefe)
- MP7.CheckCross(Breite, Höhe, Tiefe)
- MP8.CheckCross(Breite, Höhe, Tiefe)
- HP1.CheckCross(Breite, Höhe, Tiefe)
- HP2.CheckCross(Breite, Höhe, Tiefe)
- HP3.CheckCross(Breite, Höhe, Tiefe)
- HP4.CheckCross(Breite, Höhe, Tiefe)
- HP5.CheckCross(Breite, Höhe, Tiefe)
- HP6.CheckCross(Breite, Höhe, Tiefe)
- HP7.CheckCross(Breite, Höhe, Tiefe)
- HP8.CheckCross(Breite, Höhe, Tiefe)
- HP9.CheckCross(Breite, Höhe, Tiefe)
- Dim Aktive As Integer = 0
- If AlleZellen(EP1.X, EP1.Y, EP1.Z) Then Aktive += 1
- If AlleZellen(EP2.X, EP2.Y, EP2.Z) Then Aktive += 1
- If AlleZellen(EP3.X, EP3.Y, EP3.Z) Then Aktive += 1
- If AlleZellen(EP4.X, EP4.Y, EP4.Z) Then Aktive += 1
- If AlleZellen(EP5.X, EP5.Y, EP5.Z) Then Aktive += 1
- If AlleZellen(EP6.X, EP6.Y, EP6.Z) Then Aktive += 1
- If AlleZellen(EP7.X, EP7.Y, EP7.Z) Then Aktive += 1
- If AlleZellen(EP8.X, EP8.Y, EP8.Z) Then Aktive += 1
- If AlleZellen(EP9.X, EP9.Y, EP9.Z) Then Aktive += 1
- If AlleZellen(MP1.X, MP1.Y, MP1.Z) Then Aktive += 1
- If AlleZellen(MP2.X, MP2.Y, MP2.Z) Then Aktive += 1
- If AlleZellen(MP3.X, MP3.Y, MP3.Z) Then Aktive += 1
- If AlleZellen(MP4.X, MP4.Y, MP4.Z) Then Aktive += 1
- If AlleZellen(MP5.X, MP5.Y, MP5.Z) Then Aktive += 1
- If AlleZellen(MP6.X, MP6.Y, MP6.Z) Then Aktive += 1
- If AlleZellen(MP7.X, MP7.Y, MP7.Z) Then Aktive += 1
- If AlleZellen(MP8.X, MP8.Y, MP8.Z) Then Aktive += 1
- If AlleZellen(HP1.X, HP1.Y, HP1.Z) Then Aktive += 1
- If AlleZellen(HP2.X, HP2.Y, HP2.Z) Then Aktive += 1
- If AlleZellen(HP3.X, HP3.Y, HP3.Z) Then Aktive += 1
- If AlleZellen(HP4.X, HP4.Y, HP4.Z) Then Aktive += 1
- If AlleZellen(HP5.X, HP5.Y, HP5.Z) Then Aktive += 1
- If AlleZellen(HP6.X, HP6.Y, HP6.Z) Then Aktive += 1
- If AlleZellen(HP7.X, HP7.Y, HP7.Z) Then Aktive += 1
- If AlleZellen(HP8.X, HP8.Y, HP8.Z) Then Aktive += 1
- If AlleZellen(HP9.X, HP9.Y, HP9.Z) Then Aktive += 1
- Return Aktive
- End Function
Und diese Zellen hole ich mir aus dem Array, würde ich diese in der Liste suchen, müsste ich die Liste pro Eintrag nochmal 24 durchgehen, um zu überprüfen ob die Zelle vorhanden ist.
Das bedeutet für mich, ich bräuchte sowohl das Array inklusive der Liste. Ich gehe aber nicht alle Bereiche im Array durch, sondern nur die in der Liste.
Hoffe ihr versteht ungefähr wo meine Überlegung hingeht.
LG