Wie verwaltet man Abhängigkeiten
-
Wie meinst du das? Es gibt ja nicht nur enabled/disabled, sondern zu jedem Schalter noch ein attribut.
-
ness schrieb:
Wie meinst du das? Es gibt ja nicht nur enabled/disabled, sondern zu jedem Schalter noch ein attribut.
ich meine das umgekehrte. bisher hast du ja in jedem objekt eine liste der abhängigkeiten. aber man kann's auch so machen, dass es für jede abhängigkeit eine einzige liste gibt, in der alle objekte drin stehen (als pointer oder referenz) die diese abhängigkeit haben sollen. es könnte natürlich auch ein objekt in mehreren listen sein. wie's genau funktionieren soll, musste überlegen, vielleicht bringt das was in deinem fall oder es passt gar nicht.
-
Ich muss erst mal verstehen was Du überhaupt machen willst.
ness schrieb:
Ich hab einen haufen Objekte. Zu jedem hab ich einen vektor (der auch leer sein kann) mit abhängigkeiten in der form enabled/disable abhängigkeit. Mit enable(abhängigkeit) und disable(abhängigkeit) kann ich abhängigkeiten ein/ausschalten.
Du hast einen Vector als Member der Objekte aus dem "Haufen". Was sind die Einträge? Abhängigkeitsobjekte, Strings, ...?
ness schrieb:
Nun muss ich mit jedem Objekt eine Aktion ausführen, und die Abhängigkeiten müssen zum Zeitpunkt der Ausführung erfüllt sein.
Was ist eine Aktion, bzw. Wer führt die Aktion aus. Hast Du ein anderes Objekt, welches Referenzen auf die Objekte aus dem "Haufen" hat und für jedes eine (bestimmte?) Aktion ausführt?
Was heisst die Abhängigkeit muss erfüllt sein? Vergleichst Du den Vector der Member des Objekts ist, mit welchem die Aktion durchgeführt wird mit einem Refernzvektor für die Aktion?ness schrieb:
Außerdem gehe ich davon aus, dass ein/ausschalten von Abhängigkeiten relativ gesehen inperformant ist.
Warum? Gibt es Abhängigkeiten zwischen den Objekten, welche die Abhängigkeiten halten?
ness schrieb:
Nun ist die Frage, wie ich die Objekte möglichst geschickt sortiere, so dass ich enable/disable möglichst selten aufrufen muss.
Hat jemand eine Idee?enable/disable solltest Du doch nur aufrufen wenn sich eine Abhängigkeit vom default-Wert ändert, oder? Oder meinst Du "isEnabled()" zum prüfen??
Du musst einfach mehr zu Deinem Problem erzählen. Vor allem, von welcher Natur Deine Abhängigkeiten sind (Wer hängt von wem ab?, etc.), warum müssen diese in jedem Objekt gehalten werden?, wie beeinflussen die Abhängigkeiten die Aktionen, etc....
-
Abhängigkeitsprobleme kann man graphentheoretisch formalisieren und mit entsprechenden algorithmen entsprechend bearbeiten.
Suchst du vll. sowas ?
-
OK, ich versuche mal die Fragen zu beantworten:
kneifel schrieb:
Du hast einen Vector als Member der Objekte aus dem "Haufen". Was sind die Einträge? Abhängigkeitsobjekte, Strings, ...?
kneifel schrieb:
Was ist eine Aktion, bzw. Wer führt die Aktion aus. Hast Du ein anderes Objekt, welches Referenzen auf die Objekte aus dem "Haufen" hat und für jedes eine (bestimmte?) Aktion ausführt?
Was heisst die Abhängigkeit muss erfüllt sein? Vergleichst Du den Vector der Member des Objekts ist, mit welchem die Aktion durchgeführt wird mit einem Refernzvektor für die Aktion?Das ganze sieht etwa so aus:
enum abh_art{...}; //sehr viele Arten von Abhängigkeiten class obj //Basisklasse { public: virtual void do_action()=0; virtual const std::vector<abh_art>& enabled()=0; virtual const std::vector<abh_art>& disabled()=0; }; class manager //verwaltet die objs (referenzen) und führt für jedes do_action aus. //soll garantieren, dass alles unter enabled eingeschaltet und unter disabled ausgeschaltet ist wenn do_action ausgeführt wird //und enabled und disabled sich nicht widersprechen { //... }; void enable(abh_art) { //... }; void disable(abh_art) { //... };
kneifel schrieb:
Warum? Gibt es Abhängigkeiten zwischen den Objekten, welche die Abhängigkeiten halten?
Der Aufruf der Funktionen enable/disable ist vergleichsweise inperformant.
Nein, Objekte können nur von abh_art enabled/disabled abhängen.kneifel schrieb:
enable/disable solltest Du doch nur aufrufen wenn sich eine Abhängigkeit vom default-Wert ändert, oder? Oder meinst Du "isEnabled()" zum prüfen??
Das mit enabled/disabled ist so:
am Anfang befindet sich jede Abhängigkeit in undefiniertem Status (eigentlich nicht, sie haben default-werte, spielt aber keine Rolle). Ein Objekt, dass sowohl für enabled als auch für disabled einen leeren Vektor liefert, kann also jetzt (und zu jedem anderen Zeitpunkt) aufgerufen werden. Wenn ich jetzt ein anderes Objekt mit Abhängigkeiten aufrufen will, muss ich vorher enable/disable für alle enabled/disabled abhängigkiten aufrufen, da ja alle globalen attribute undefiniert sind. Theoretisch könnte ich vor jedem aufruf von do_action diese Funktionen aufrufen, aber das wäre Zeitverschwendung: Die Objekte werden einmal registriert und dann in einer (quasi-endlos)schleife aufgerufen.
Nun ist also die Frage, in welcher Reihenfolge ich die Objekte aufrufe und wann ich enable/disable aufrufen muss. Dieses sortieren könnte einmal vor Beginn der Schleife geschehen, ich denke so kann ich viel Zeit sparen.prolog@work schrieb:
Abhängigkeitsprobleme kann man graphentheoretisch formalisieren
Wie?
Was allgemeines zum Modell:
ich habe eine externe state-machine, die eventuell sogar als daemon realisiert ist(daher die inperformanz von enable/disable). Je nach dem, wie die state-machine eingestellt ist, wird sie Anforderungen anders erfüllen. Die Objekte rufen nun in do_action Funktionen der state-machine auf. Sie speichern den Status, den sie beim Aufruf der state-machine gern hätten. abh_art, enable und disable sind alle von der state-machine bereitgestellt.
-
Ok, das Problem ist einigermaßen verstanden.
Ist die Art und Anzahl der Abhängigkeiten immer gleich? Ändern sich die Objekte wenn Du die Aktionen ausführst?
Aber prinzipiell würde ich folgendermaßen Vorgehen. Du brauchst ein Maß mit dem Du den Unterschied zwischen zwei Abhängigkeitsvektoren messen kannst. Die Werte für das Maß sollten zumindest auf einer Intervallskala besser noch einer Rationalskala darstellbar sein. Ersteres bedeuted grob gesagt, dass zwischen den Werten ein Abstand definiert ist, welches auch Bedeutung hat. Bei einer Rationalskala können diese Abstände auch noch sinnvoll in Relation gesetzt werden (doppelt so viel Abstand wäre in unserem Fall doppelt so großer Unterschied im Vektor).
Für jedes Objekt musst Du den Wert für die Merkmalsausprägung berechnen et voila, Du hast Die Reihenfolge.Ziel des Ganzen soll sein, dass Du über das Maß eine Reihenfolge der Objekte erstellen kannst, die die geringste Anzahl an enables/disables erzeugt.
Problem ist jetzt "nur" noch die sinnvolle Definition eines Maß. Erster (schlechter) Spontaneinfall wäre das Hamminggewicht der einzelnen Vektoren der Objekte (als Bitvektor aufgefasst) und den Abhängigkeiten in der state machine. Bringt aber auch nix ... obwohl quick and dirty: Mach aus den Abhängigkeitsvektoren (vorrausgesetzt sie bleiben konstant) Bitvektoren. Jetzt könntest Du vor jeder Auführung eines Objektes Prüfen welches Objekt gegenüber der augenblicklichen Konfiguration das geringste Hamminggewicht hat und dieses Ausführen ... Frage ist nur ob sich das Ganze dann noch lohnt??
Sei es drum, es ist spät, vielleicht kannst Du ja was mit diesem geistigen Erguß anfangen - Nacht!
-
kneifel schrieb:
Ist die Art und Anzahl der Abhängigkeiten immer gleich? Ändern sich die Objekte wenn Du die Aktionen ausführst?
Ich gehe davon aus, dass sich die Abhängigkeiten nicht ändern. Dem Objekt ist das natürlich freigestellt, aber derzeit habe ich nicht vor darauf einzugehen...
Ein weiteres Problem ist, dass ich einen geschlossenen Kreis bilden muss: die Abhängigkeiten, die ich bei dem letzten Objekt eingestellt hab, sind in der nächsten Runde immer noch so.
Was du vorschlägst klingt mir irgendwie nach brute force: bewertung festlegen und dann alle möglichkeiten ausprobieren um zu sehen, wos am niedrigsten bleibt. Das würde ich gern vermeiden, weil ich davon ausgehe, dass es hunderte von Objekten seien können.
Achja, da fällt mir grad noch ein Problem ein. Es gibt noch andere Sortierkriterien. Beispielsweise müssen alle Objekte mit der und der Eigenschaft (die ich in einer bool bekomme) nach allen anderen Objekten aufgerufen werden. Ich dachte erst daran mit std::stable_sort zu sortieren, dass kann aber nicht klappen. Man könnte sie auch erst nach den wichtigeren Kriterien sortieren und danach nur intern die Reihenfolge vertauschen.
Also, ich bin für Vorschläge immer offen, steh auch nicht unter Zeitdruck...
-
ness schrieb:
Was du vorschlägst klingt mir irgendwie nach brute force: bewertung festlegen und dann alle möglichkeiten ausprobieren um zu sehen, wos am niedrigsten bleibt. Das würde ich gern vermeiden, weil ich davon ausgehe, dass es hunderte von Objekten seien können.
klar der Vorschlag mit dem Hamminggewicht war nicht der schönste, aber lange dauert das auch bei 100 Objekten nicht. Es handelt sich hier um den Vergleich von Bitvektoren.
ness schrieb:
Achja, da fällt mir grad noch ein Problem ein. Es gibt noch andere Sortierkriterien. Beispielsweise müssen alle Objekte mit der und der Eigenschaft (die ich in einer bool bekomme) nach allen anderen Objekten aufgerufen werden. Ich dachte erst daran mit std::stable_sort zu sortieren, dass kann aber nicht klappen. Man könnte sie auch erst nach den wichtigeren Kriterien sortieren und danach nur intern die Reihenfolge vertauschen.
Also, ich bin für Vorschläge immer offen, steh auch nicht unter Zeitdruck...Na jetzt haben wir doch Abhängigkeiten untereinander, dann ist die Geschichte mit dem Maß natürlich hinfällig.
Falls die Abhängigkeiten untereinander stärker werden, also a la "Objekt A vor B aber nach C, G, I" und es davon viele gibt, mach dich mal über Constraint Programming schlau. Frage hier aber auch wieder ob sich der Aufwand lohnt.
-
Bisher gibt es nur alle ohne Attribut foo vor denen mit Attribut foo.
Ja, eigentlich suche ich eine unkomplizierte Lösung, aber dafür ist die Problemstellung wohl zu kompliziert...
-
ness schrieb:
Bisher gibt es nur alle ohne Attribut foo vor denen mit Attribut foo.
Na wenn's nicht viel mehr wird, ist das ja vernachlässigbar. Jetzt haste halt einfach zwei Gruppen innerhalb derer Du Sortieren musst.
ness schrieb:
Ja, eigentlich suche ich eine unkomplizierte Lösung, aber dafür ist die Problemstellung wohl zu kompliziert...
Zu kompliziert würde ich die Problematik nicht bezeichnen. Sie ist lediglich mit gewissem Aufwand verbunden.
Im Endeffekt hast Du ein Optimierungsproblem. Jag einen genetischen Algorithmus oder dynamische Programmierung darauf los und das ganze ist im Nu geritzt; es kostet allerdings Aufwand; sowohl von der Implemnentierung als natürlich auch Rechenzeit.
-
An einen genetischen Algorithmus hab ich noch garnicht gedacht! Könnte eine Härteprobe für mein genetic_algorithm template werden...
/edit: ich deute die Masse an Vorschlägen mal so, dass es keinen "perfekten" Algo dafür gibt...