Vorschläge, wie man "viele" abhängige Parameter "berechnet"

8

Ich habe mehrere Indikatoren, die immer auf dem neuesten Stand sein müssen. I.e. Wenn etwas geändert wird, muss ich "abhängig" neu berechnen. Ich habe mehrere Ebenen, auf denen jedes nächste Level nur berechnet werden sollte, wenn das vorherige Level berechnet wird. Lassen Sie mich durch dieses leuchtende Bild erklären:

Angenommen, Franc hat sich verändert. Dann sollten wir:

  1. berechneter Franc / Dinar
  2. berechneter Franc / Dinar / Peso

Oder, wenn Peso, Franc und Dinar auf einmal geändert werden, dann sollten wir:

  1. berechneter Franc / Dinar
  2. berechneter Franc / Dinar / Peso
  3. berechneter Peso + Euro / (Euro + USD)

Wenn also irgendetwas am Level 0 geändert wird, sollten wir alle anderen Ebenen neu berechnen. Aber

  • wir sollten nur die benötigten Artikel berechnen. Wenn der Euro sich ändert, müssen wir Franc / Dinar nicht neu berechnen
  • wir sollten nichts mehr als einmal berechnen. Wenn Euro und Usd sofort geändert werden, sollten wir Euro + Usd nur einmal (nicht zweimal) berechnen.

Die einfachste Lösung wäre:

  • speichert jede Ebene im Array
  • für jedes Element im Array Track "Listeners" von den nächsten Leveln (könnte Schwierigkeiten bereiten, weil zum Beispiel Peso Zuhörer aus verschiedenen Leveln hat - Franc / Dinar / Peso von Level2 und Peso + Euro / (Euro + Usd) von Level 3, Also zwei-Dimmer-Array ist erforderlich ..)
  • Wenn der Artikel neu berechnet wird, markieren Sie alle Listener, die ebenfalls neu berechnet werden sollen
  • Gehen Sie von Level 0 auf die letzte Ebene und berechnen Sie die neu zu kalkulierenden Elemente neu (anfänglich aktualisierte Elemente sind neu zu berechnen, z. B. Peso).

Ich schätze, dass mein Problem ziemlich bekannt ist, und wahrscheinlich können Sie mir eine allgemein bekannte Lösung vorschlagen. Ich will das Rad nicht neu erfinden :) Danke!

    
javapowered 18.07.2013, 13:59
quelle

4 Antworten

2

Ich denke, der Level-basierte Ansatz ist in Ordnung, unter der Annahme, dass die Zuhörer immer auf einer niedrigeren Ebene sind.

Die Idee:

Haben Sie ein 2D-Array mit Ihren tatsächlichen Daten, der erste Index ist die Ebene, der zweite ist die Position auf der Ebene. Lassen Sie jedes Element ein willBeRecalculated Flag haben.

Haben Sie eine toBeRecalculated Liste für jede Ebene (also ein Array von Listen).

Fügen Sie für jedes Element eine Liste von Elementen (die Listener) mit 2 ganzen Zahlen ein - eine für die Ebene und eine für den Index.

Fügen Sie für jedes Element, das geändert werden soll, das Element toBeRecalculated auf der entsprechenden Ebene hinzu und setzen Sie willBeRecalculated auf wahr.

Gehe dann durch toBeRecalculated von der ersten zur letzten Ebene, rechne jedes Element neu, setze sein willBeRecalculated auf false und suche für jedes Listener das passende Element nach, wenn willBeRecalculated wahr ist, tue nichts, Andernfalls setzen Sie willBeRecalculated auf true und fügen Sie toBeRecalculated auf der Ebene (des Zuhörers) hinzu.

Dieser Ansatz durchläuft nicht alle Daten, um zu prüfen, was modifiziert / modifiziert werden muss, er überprüft nur die anwendbaren Elemente und es gibt keine wiederholten Berechnungen.

Beispiel:

Dafür:

(Für meine Abkürzungen habe ich einfach den ersten Buchstaben jedes Wortes genommen. Ich verwende 0-indizierte Arrays)

Tatsächliche Daten:

%Vor%

Listeners:

%Vor%

Ändern von E und U :

Fügen Sie E und U zu toBeRecalculated[0] hinzu und setzen Sie willBeRecalculated für beide auf true.

Gehe durch toBeRecalculated[0] .

Wenn Sie E ändern, setzen Sie willBeRecalculated auf false und setzen E+U willBeRecalculated auf true und fügen Sie es zu toBeRecalculated[1] hinzu und setzen E/E+U 's willBeRecalculated auf true und fügen hinzu es zu toBeRecalculated[2] .

Wenn Sie U ändern, setzen Sie willBeRecalculated auf false und wir überprüfen E+U s willBeRecalculated und sehen, dass es wahr ist, also tun Sie nichts.

Gehe dann durch toBeRecalculated[1] . Wenn Sie E+U ändern, setzen Sie willBeRecalculated auf false und überprüfen Sie E/E+U s willBeRecalculated und sehen Sie, dass es wahr ist. Tun Sie nichts.

Hinweis:

Es könnte besser sein, wenn die Listener Zeiger auf die Elemente statt auf eine Ebene und eine Indexvariable sind.

    
Dukeling 18.07.2013 14:19
quelle
2

Nun, wenn Sie sagen, dass Sie mit Ebenen arbeiten, kommt Ihnen eine Art Baumstruktur in den Sinn.

Aber für Ihr Problem, ich denke, es würde funktionieren, um eine Art von gerichteten azyklischen Graphen zu modellieren.

Ihr Diagramm sieht möglicherweise so aus (alle Richtungen sind abwärts).

%Vor%

Wenn Sie diese Struktur wie eine Baumstruktur durchqueren, aktualisieren Sie jede Conversion-Rate für jede Aktualisierung der Währung genau einmal.

    
Joel 18.07.2013 14:28
quelle
0

Was Sie beschreiben, kann leicht in einer reaktiven Programmiersprache erreicht werden.

Die QML von Qt bietet auch einen Eigenschaftsbindungsmechanismus, der dies für eine Benutzerschnittstelle ermöglicht.

Wenn Sie sich die Implementierungen von Qt-Eigenschaftsbindungen und anderen reaktiven Sprachen ansehen, können Sie einige Implementierungsideen erhalten.

Die Seite Wikipedia identifiziert Bibliotheken für reaktive Programmierung in Javascript, .NET, Python, Java, C ++ und vielen anderen Sprachen auch.

    
Doug Currie 18.07.2013 14:54
quelle
0

Ich denke, dass Sie Polymorphie hier verwenden können. Haben Sie eine Liste von Währungen, von denen jede einen Vektor mit Zeigern (zu der Basisklasse) aller depedanten Elemente enthält.

Die Basisklasse zwingt sie, eine Funktion update() einzufügen, die jedes Mal aufgerufen wird, wenn die aktuelle Währung aktualisiert wird.

Die depedanten Elemente wiederum haben Zeiger für jede Währung, von der sie abhängen, und verwenden diese, um sich selbst in ihrer update() -Implementierung zu aktualisieren.

%Vor%

Dies aktiviert:

%Vor%

Drucken:

  

3
  9

Vielleicht können Sie eine std::vector<std::weak_ptr> Ihrer Währungen haben, während jeder Knoten eine std::shared_ptr für jede Währung hat, so dass die Währungen nicht außerhalb des Geltungsbereichs liegen / zerstört werden, es sei denn, es gibt keine Knoten mehr, die sich auf sie beziehen.

    
Pixelchemist 18.07.2013 15:10
quelle

Tags und Links