Umgang mit grosser Datenmenge einer Simulation

  • VB.NET

Es gibt 34 Antworten in diesem Thema. Der letzte Beitrag () ist von MMemanuel.

    Umgang mit grosser Datenmenge einer Simulation

    Hallo zusammen,

    Im Zusammenhang mit meiner Planung eines neuen Programms bin ich auf viel Neuland gestossen.
    Ich beabsichtige die Gravitationskräfte zwischen mehreren Himmelskörpern zu simulieren, wobei ich
    die rein mathematischen Kenntnisse bereits besitze, die programmatischen aber leider noch nicht.

    Datenbanken haben mich bis zu diesem Zeitpunkt nur mässig interessiert und daher habe ich wenig
    Wissen darüber; dasselbe gilt für Klassen und Objekte.
    Im oben beschriebenen Programm werden aber viele Daten entstehen, die es zu ordnen gilt:
    Eine Funktion wird die Simulation übernehmen, deren Rückgabewert voraussichtlich eine Position im
    R3 (also 3D ->3 Werte für x-, y-, und z-Achse) sein wird. Pro Himmelskörper entsteht so bei jedem
    Simulationsschritt eine neue Position.
    Die Positionen müssen nicht weiter verarbeitet werden, sondern der Zugriff sollte einfach möglichst schnell
    sein und das Ziel wäre es, die errechneten Daten auf der Festplatte zu Speichern und dann wieder zu
    laden. Die Effizienz ist bei diesem Problem natürlich massgebend.

    Wie soll ich mit dieser Datenmenge umgehen und wie/wo kann ich die Theorie dazu finden?
    Ich „kenne“ bereits: dynamischen Arrays, ADO.NET, SQL(lite)

    Gruss Marc
    Am besten wäre natürlich eine Structure zu machen:

    VB.NET-Quellcode

    1. Structure R3bla
    2. Dim x As Integer
    3. Dim y As Integer
    4. Dim z As Integer
    5. End Structure

    Dann kannst du eine Liste machen:

    VB.NET-Quellcode

    1. Function Test() As List(Of R3bla)

    Da hättest du ein Array von den Werten.
    Neuer Eintrag ist glaub ich so:

    VB.NET-Quellcode

    1. Dim test As R3bla
    2. test.x = 4
    3. test.y = 5
    4. test.z = 102
    5. Dim retList As List(Of R3bla)
    6. retList.Add(test)
    7. Return retList

    Aja ;) :

    VB.NET-Quellcode

    1. End Function
    Danke für die schnelle Antwort :)

    Hm. Also so wie ich das verstehe entsteht eine Struktur retList, welche die Werte x, y, z zu einem Indexwert „n“ enthält. Ist die Structure gewissermassen eine Klasse und retList dann etwas wie ein Objekt? sry aber ich hab ja geschrieben ich sei nicht so gut informiert ;)

    Der Code funktioniert so noch nicht ganz, ich glaube man sollte die Variable „test“ nicht gleich wie die Funktion benennen und es gibt ein Problem bei dem

    VB.NET-Quellcode

    1. retList.Add(test)

    Fehlermeldung: „Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.“
    Mein verwendeter Quellcode:

    VB.NET-Quellcode

    1. Structure R3bla
    2. Dim x As Integer
    3. Dim y As Integer
    4. Dim z As Integer
    5. End Structure
    6. Function NeuerEintrag(ByVal x As Integer, ByVal y As Integer, ByVal z As Integer) As List(Of R3bla)
    7. Dim test As R3bla
    8. test.x = x
    9. test.y = y
    10. test.z = z
    11. Dim retList As List(Of R3bla)
    12. retList.Add(test)
    13. Return retList
    14. End Function
    15. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    16. ListBox1.Items.Add(NeuerEintrag(4, 5, 102))
    17. End Sub

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „MMemanuel“ ()

    Dim test As New R3bla
    Dim retList As New List(Of R3bla)

    Ups, hab ich vergessen :rolleyes:

    ListBox1.Items.Add(NeuerEintrag(4, 5, 102)(0).x)
    (0) deswegen, weil du ja eine Liste hast und ein bestimmtes Element der Liste ansprechen musst.
    .x deswegen, weil R3Bla aus x, y und z besteht und du entweder x, y oder z ansprechen musst.

    Aja, und das darüber ist korrekt, (Klasse & Objekt)
    Meinst du:

    VB.NET-Quellcode

    1. Dim test As R3bla
    2. test.x = x
    3. test.y = y
    4. test.z = z
    5. Dim test2 As R3bla
    6. test.x2 = x2
    7. test.y2 = y2
    8. test.z2 = z2
    9. Dim test3 As R3bla
    10. test.x3 = x3
    11. test.y3 = y3
    12. test.z3 = z3
    13. Dim retList As List(Of R3bla)
    14. retList.Add(test)
    15. retList.Add(test2)
    16. retList.Add(test3)
    17. Return retList
    Eher so:

    VB.NET-Quellcode

    1. Function NeuerEintrag_retList(ByVal x As Integer, ByVal y As Integer, ByVal z As Integer) As List(Of R3bla)
    2. ...
    3. Dim retList As New List(Of R3bla)
    4. retList.Add(test)
    5. Return retList
    6. End Function
    7. Function NeuerEintrag_retList2(ByVal x As Integer, ByVal y As Integer, ByVal z As Integer) As List(Of R3bla)
    8. ...
    9. Dim retList2 As New List(Of R3bla)
    10. retList2.Add(test)
    11. Return retList2
    12. End Function
    13. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    14. NeuerEintrag_retList(4, 5, 102)
    15. NeuerEintrag_retList2(8, 10, 204)
    16. 'zuerst sollte ein Wert (zB LIST(0).x) von retList und dann von retList2 aufgerufen werden oder anders ausgedrückt: aus allen Listen von R3bla
    Hi,
    was du da geproggt hast, sieht sehr nach fehlenden Grundlagen aus.Davon abgesehen, dass deine beiden Funktionen im Grunde identisch sind, wird das nicht funtioniern. Bei jedem Aufruf wird die List(Of) neu initialisiert (als leere Liste erzeugt). Damit hat deine Liste immer nur 1 Eintrag. Außerdem kannst du so nicht von außerhalb der Funktion auf die Liste zugreifen. Du mußt die Listen global, also außerhalb der Funktionen instanzieren. Dann benötigst du auch für mehrere Listen nur 1x die Funktion Hinzufügen, der du die Liste und die Variablen übergibst.
    Zu deinem Verständnis von Klasse und Objekt:
    Eine Klasse ist ein Bauplan eines Objektes. Sie legt fest, welche Eigenschaften und Funktionen das Objekt haben kann.
    Ein Objekt ist die Instanz einer Klasse.
    Beispiel:
    Klasse Auto mit den Eigenschaften Farbe, Typ, Leistung etc.
    Mit Dim MeinAuto as new Auto erzeugst du eineneue Instanz Auto. Du kannst beliebig viele Autos produzieren und Ihnen jeweils eigene Farben usw. mitgeben.
    Sieh dir zu der ganzen Thematik mal die Galileo Openbooks an. :)
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:
    Hi Vatter,
    danke erstmals für deine Antwort.
    Ja, wie ich bereits geschrieben habe bin ich im Themenbereich (Klassen und Objekte) in VB noch sehr schwach und natürlich bin ich ein Anfänger was die gesamte Programmierung angeht, allerdings war mir bewusst, dass ich hier keinen wirklich effizienten (oder auch nur funktionierenden) Quellcode angebe, abgesehen von den globalen Variabeln; es ging mir "ums Prinzip". Ich werde versuchen mir bei kommenden Quellcodes mehr zu überlegen. ;)
    Ich habe bereits in Python mit Klassen gearbeitet, also ist mir deren grundlegende Definition bekannt. :)

    Um die Sache etwas gerade zu rücken habe ich den Quellcode ungestaltet:

    VB.NET-Quellcode

    1. Dim retList, retList2 As New List(Of R3bla)
    2. Structure R3bla
    3. Dim x As Integer
    4. Dim y As Integer
    5. Dim z As Integer
    6. End Structure
    7. Function NeuerEintrag(ByVal x As Integer, ByVal y As Integer, ByVal z As Integer) As Besser.R3bla.Form1.R3bla
    8. Dim test As New R3bla
    9. test.x = x
    10. test.y = y
    11. test.z = z
    12. Return test
    13. End Function
    14. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    15. retList.Add(NeuerEintrag(4, 5, 102))
    16. retList.Add(NeuerEintrag(8, 10, 204))
    17. retList2.Add(NeuerEintrag(-4, -5, -102))
    18. retList2.Add(NeuerEintrag(-8, -10, -204))
    19. 'zuerst sollte ein Wert (zB LIST(0).x) von retList und dann von retList2 aufgerufen werden oder anders ausgedrückt: aus allen Listen von R3bla
    20. End Sub

    gruss Marc

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „MMemanuel“ ()

    Wieso machst du 2 Listen? Eine Liste ist doch gerade dazu da um mehrere Objekte aufzunehmen...
    Falls sich das noch nicht geklärt hat:
    R3bla ist eine Struktur. test ist ein R3Bla-Objekt. retList ist eine Liste von R3bla-Objekten
    Damit Ich mehrere Listen von R3-Objekten habe, welche im Programm jeweils dem Verlauf der Position eines Himmelskörpers entsprechen (siehe Fragestellung).

    Ich schreibe den Code einmal so um, damit er vielleicht besser verständlich ist:

    VB.NET-Quellcode

    1. Dim Position_Sonne, Position_Erde As New List(Of R3)
    2. Structure R3
    3. Dim x As Decimal
    4. Dim y As Decimal
    5. Dim z As Decimal
    6. End Structure
    7. Function NeuerEintrag(ByVal x As Integer, ByVal y As Integer, ByVal z As Integer) As Besser.Form1.R3
    8. Dim neu_in_R3 As New R3
    9. neu_in_R3.x = x
    10. neu_in_R3.y = y
    11. neu_in_R3.z = z
    12. Return neu_in_R3
    13. End Function
    14. Private Sub Simulationsstart(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SimulationStarten.Click
    15. Position_Sonne.Add(NeuerEintrag(20000000, 435000, -30000))
    16. Position_Erde.Add(NeuerEintrag(20, -43500, 3000000))
    17. 'an dieser Stelle wird eine Funktion aufgerufen, welche die Berechnungen
    18. 'der nächsten Situation übernimmt. sie ist mit einer for-Schleife
    19. 'vereinfacht dargestellt (nicht die wirkliche Berechnung).
    20. 'Unabhängig von deren Bezeichnung sollten alle Listen mit R3-Objekten
    21. 'aufgerufen werden, auch wenn es mehr als 2 sind
    22. For i As Byte = 0 To 198
    23. Position_Sonne.Add(NeuerEintrag(Position_Sonne(i).x / 10, i, i))
    24. Position_Erde.Add(NeuerEintrag(i, Position_Erde(i).y * 1.001, i))
    25. Next
    26. End Sub

    Vielleicht wäre es sinnvoll die Listen wiederum zusammenzufassen? Diesen Schritt könnte ich jedoch wahrscheinlich nicht selbst machen. Ich versuch‘s mal :)

    hier hab ich mal was:
    1)Definieren

    VB.NET-Quellcode

    1. Dim Alle_Listen As New List(Of R3_Listen)
    2. Structure R3_Listen
    3. Dim Liste As System.Collections.Generic.List(Of Besser.Form1.R3)
    4. End Structure

    2)Listen hinzufügen

    VB.NET-Quellcode

    1. Dim neue_Liste_in_R3 As New R3_Listen
    2. neue_Liste_in_R3.Liste = Position_Sonne
    3. Alle_Listen.Add(neue_Liste_in_R3)

    3)Werte auslesen

    VB.NET-Quellcode

    1. Me.Text = Alle_Listen(0).Liste(0).x.ToString

    Ist das sinnvoll? :)

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „MMemanuel“ ()

    Wie sollte ich dann die Werte geordnet in nur eine Objekt-Liste einspeichern und diese wieder Abrufen?

    Edit: Es kann auch sein, dass neue Himmelskörper hinzugefügt werden, es ist also nicht immer möglich einen proportional steigenden Index zu verwenden:

    Index für Position_Sonne, wenn diese vor Position_Erde behandelt wird:
    I=n*2; n ist gewünster Wert der Liste
    Also ich bin immer mer der Überzeugung, dass du Klassen verwenden solltest. z.B. Klasse "Planet", mit der Eigenschaft Position und Zeitpunkt in einer List(Of). Der Zeitpunkt ist die Variable, die den Index deiner Konstellation darstellt. Die Objekte dieser Klasse sind dann Bestandteil einer weiteren Klasse "Planetensystem". Diese enthält neben einer Liste(Of Planeten) sämtliche Berechnungen. Das Hinzufügen weiterer Planeten zur Laufzeit ist dann kein Thema mehr. Einem zum Zeitpunkt X+n hinzugefügten Planet wird dann auch den Startindex X+n zugeordnet.
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:
    Ja, sowas in der Art würde Sinn ergeben. :)
    Ich habe gestern noch einen Versuch mit zwei Strukturen gemacht und dabei die Sache mit dem Index ähnlich geregelt wie vorgeschlagen:

    VB.NET-Quellcode

    1. Dim n As Byte = 100 'n ist die Anzahl der Durchläufe der Simulation, hier einmal auf 100 gesetzt
    2. Structure Position_St
    3. Dim x As Decimal
    4. Dim y As Decimal
    5. Dim z As Decimal
    6. End Structure
    7. Structure Koerper_St
    8. Dim masse As Decimal
    9. Dim name As String
    10. Dim position As System.Collections.Generic.List(Of Position_St)
    11. Dim entstehungszeit As Integer
    12. End Structure
    13. Function Position_hinzufuegen(ByVal x As Decimal, ByVal y As Decimal, ByVal z As Decimal) As Form1.Position_St
    14. Dim neue_Position As New Position_St
    15. neue_Position.x = x
    16. neue_Position.y = y
    17. neue_Position.z = z
    18. Return neue_Position
    19. End Function
    20. Function Koerper_hinzufuegen(ByVal masse As Decimal, ByVal name As String, ByVal x As Decimal, ByVal y As Decimal, ByVal z As Decimal, ByVal entstehungszeit As Integer) As Form1.Koerper_St
    21. Dim neuer_Koerper As New Koerper_St
    22. neuer_Koerper.masse = masse
    23. neuer_Koerper.name = name
    24. Dim neue_Position As New System.Collections.Generic.List(Of Position_St)
    25. neue_Position.Add(Position_hinzufuegen(x, y, z))
    26. neuer_Koerper.position = neue_Position
    27. neuer_Koerper.entstehungszeit = entstehungszeit
    28. Return neuer_Koerper
    29. End Function
    30. Private Sub Start_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Start.Click
    31. Dim Koerper As New System.Collections.Generic.List(Of Koerper_St)
    32. 'Hinzufügen eines Körpers bei n = 100
    33. Koerper.Add(Koerper_hinzufuegen(10, "Mond", 0, 0, 0, n))
    34. 'Die Simulation erweitert die Listen der Positionen
    35. Koerper(0).position.Add(Position_hinzufuegen(10, 10, 10))
    36. n += 1
    37. 'Auslesen des x-Wertes bei n = 101
    38. Me.Text = Koerper(0).position(n - Koerper(0).entstehungszeit).x.ToString
    39. End Sub
    Also das, was Ihr da macht sieht nicht wirklich nach ausgelernter OOP aus.
    Ich würde das ganze in XNA machen, da habt Ihr auch gleich eine Visuelle ausgebe. Das Rendern übernimmt die Graka.

    Wenn du gute Mathekenntnisse besitzt, dann kannst du auch mit Matrizen, Vektoren und so weiter rechnen.
    z.B. hier ein Anfang:

    VB.NET-Quellcode

    1. class Planet
    2. Public Location as Vector3
    3. protected _masse, _radius as integer
    4. Public Property Masse as integer
    5. get: return _masse : end get
    6. set(value as integer): _masse=value : end set
    7. end property
    8. Public Property Radius as integer
    9. get: return _radius : end get
    10. set(value as integer): _radius =value : end set
    11. end property
    12. protected sphere as boundingsphere
    13. pub sub new(byval _location as vector3,byval __masse as integer, __radius as integer)
    14. _masse = __masse
    15. _raduis = __radius
    16. location = _location
    17. sphere = new boundingsphere(_location, _radius)
    18. end sub
    19. end class


    Dann kannst du in der Update()-Methode deine Berechnungen durchführen. (Liste aller Planeten durchlaufen usw.)
    Von meinem iPhone gesendet
    @nikeee13,
    tschuldige meine Begriffsstutzigkeit, aber
    1. XNA hat doch mit der Fragestellung des TE rein ganischt zu tun
    2. In deinem Code ist XNA? Hilf mir ma auf die Sprünge bitte.
    ;(

    Dem TE geht es doch um das Grundgerüst seines Programmes, also die Ausführung der Structuren und Klassen. Und meiner bescheidenen Meinung nach dient XNA lediglich der Visualisierung des Ergebnisses (wo man mit XNA sicherlich super Effekte erzeugen kann). Kann mich aber auch irren :D , da ich mich damit bisher nur äußerst wenig beschäftigt habe. Dann bitte ich um Entschuldigung und Aufklärung.

    @MMemanuel,
    du solltest statt Structuren wirlich unbedingt Klassen verwenden. Nikee hat dir da schon eine schöne Klasse Planet gepostet. :D
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:
    ich sehe da nur die vom XNA verwendeten Klassen BoundingSphere und Vector3, welche sehr schnell nachgebaut sind...jedoch kann man mit Matrizen sehr viel mehr anstellen, wie mit den "normalen" Klassen des .Nets(natürlich kann man die Klassen von XNA auch nachbauen, aber da ist es schon vorprogrammiert :P)...ansonsten Dient XNA nur zur Visualisierung, zur Ausgabe und Eingabe von Informationen...
    den Rest des Problems hab ich mir ehrlich gesagt nicht angeguckt -> zu faul um so viel zu lesen :P
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---