Trace-Aufgabe (Konstruktion eines Funktionsgraphen) - Seite 2

 
sergeev:
Ein und dieselbe Funktion kann sowohl von start als auch von init aufgerufen werden. Dies sollte behoben werden.

Ich kann es mit den Fingern machen, aber man muss es durchdenken))

wie diese:

Zählen Sie die Anzahl der Funktionen, z.B. 4, und schreiben Sie #define X 4 in den Code-Header

angenommen, dass die maximale Anzahl von Aufrufen pro Tick #define Y 100 ist

wir haben eine Matrix der Größe 4 x 100, Initialisierung der Matrix = -1

und fügen Sie nun beim Aufruf einer Funktion am Eintrittspunkt der Funktion einen Aufruf des Zählers (Graphenformer) hinzu, der an der gewünschten Stelle X beim Eintritt in unsere Matrix auf der freien Zeile den Code (1,2,3 oder 4) hinzufügen soll - wer rief

Ich denke, dass Ihr Problem eher mit Netzwerkgraphen zu tun hat. Ich vermute, dass die Matrix für Netzwerkgraphen schon lange entwickelt wurde - Sie müssen googeln

SZY: nun, hier ist bereits die 2. Seite des Themas ;)

 

IgorM, die von Ihnen vorgeschlagene Art der Graphenspeicherung wird "Adjazenzmatrix" genannt. Bei spärlichen Graphen ist dies sehr unwirtschaftlich (und die Programmierer sollten für die "Full Connected Graph"-Architektur usw. verprügelt werden).

Es ist viel besser, eine Kantenliste zu verwenden (d.h. wir speichern ein eindimensionales Array von Strukturen, das aus 2 Elementen besteht - ID der aufrufenden Funktion und ID der aufgerufenen Funktion; die Struktur kann durch zusätzliche Felder ergänzt werden - Aufrufzähler usw.)

p.s. Der Matapparatus wurde wirklich schon vor langer Zeit entwickelt :)

 
lea:

IgorM, die Art und Weise, wie Sie vorschlagen, den Graphen zu speichern, wird "Adjazenzmatrix" genannt.

Danke, wenigstens habe ich angefangen, mich an etwas zu erinnern, es ist 15 Jahre her, seit ich all dieses Zeug gelernt habe, das nie im wirklichen Leben verwendet wurde )))) - Vergessen Sie aber nicht, dass das "Packen von Daten" (Speicherplatzeinsparung) aufgrund der erhöhten Komplexität der Matrix zu Leistungseinbußen führt, auch wenn ich mich vielleicht irre.
 
MetaDriver:
Ein Beweis für die Unmöglichkeit einer Idee ?
Die Protokollierung der Ein- und Ausgaben von Funktionen ist in C++ leicht zu bewerkstelligen,
es gibt Destruktoren und so etwas wie Stack-Unwinding.
Obwohl... Für dasselbe C++ gibt es Bibliotheken, mit denen man die Reihenfolge der Funktionsaufrufe für jeden
Punkt im Code per Stack erstellen kann.
.
Also... jede Rückkehr bedeutet zusätzliche Anrufe :-).
 
lea:
Ein Baum ist ein Spezialfall eines Graphen.

Ja, genau das habe ich gemeint. Aufgrund der Linearität des MQL-Codes wird es sich um einen Baum in seiner reinen Form handeln. Da die Knotenpunkte nicht aufeinander zeigen.

IgorM:
eine Matrix der Dimension 4 x 100 haben, initialisieren Sie die Matrix = -1
und nun fügen wir beim Aufruf der Funktion am Eintrittspunkt der Funktion einen Aufruf des Zählers (Graphenformer) hinzu, der an der gewünschten Position X einen Code (1,2,3 oder 4) in die freie Zeile am Eintritt in unsere Matrix einfügen soll - wer hat ihn aufgerufen

Ja, ich sehe es jetzt. Aber ich habe den Eindruck, dass dieser Ansatz sehr arbeitsintensiv ist, nicht so sehr im Hinblick auf den Code, sondern auf die Ressourcen und die Vorbereitung der Analyse. Für Verzweigungen müsste man eine dreidimensionale Matrix erstellen.
Im Allgemeinen wird diese Option akzeptiert. Aber wir belassen es vorerst bei Seite 4 in der Zusammenfassung :)

Ich denke, Ihr Problem ist eher mit Netzwerkgraphen vergleichbar. Ich vermute, dass der mathematische Apparat für Netzwerkgraphen schon lange entwickelt wurde - Sie müssen googeln

Die Aufgabe ist weder ein Know-how noch eine Neuheit. Nur ein einfacher Graph von Funktionen. Mehr nicht.
Es gibt keine neue Mathematik, wir brauchen nur eine so weit wie möglich vereinfachte Version.

 
lea:

Es ist viel besser, eine Randliste zu verwenden (d.h. wir speichern ein eindimensionales Array von Strukturen, die aus 2 Elementen bestehen - ID der aufrufenden Funktion und ID der aufgerufenen Funktion; die Struktur kann durch zusätzliche Felder ergänzt werden - Aufrufzähler usw.)

Eugene, genau das ist bereits geschehen.

Aber der Code ist ins Stocken geraten. Seit dem dritten Tag kann ich nicht schlafen oder trinken..... :)

Ich kann nicht herausfinden, wie die Rückkehr von der Kante (genauer gesagt absteigenden Knoten) zum übergeordneten Knoten, um eine neue Kante (neue absteigenden Knoten) zu gehen. Aber um die Regel einzuhalten - wir verwenden nur eine Tracing-Funktion am Anfang der Quellcode-Funktion.

 
sergeev:

Ich kann nicht herausfinden, wie ich von einer Rippe zu einem Knoten zurückkehren kann, um zu einem neuen Zweig zu gelangen.


Und das alles nur mit einer Funktion, die bereits einen Pass nach vorne gemacht hat? Das ist genug - um eine Rückkehr zu machen, ohne etwas zu tun)) Schon gut, es ist schon die zweite Seite, Vladimir wird es nicht mehr aushalten können)))
 
alsu:
Und das alles mit nur einer Funktion, die bereits einen Vorwärtspass gemacht hat? Sie haben genug getan - machen Sie ein Comeback, ohne überhaupt etwas zu tun))) Naja, nichts, die zweite Seite ist schon zu Ende, bald wird Vladimir es nicht mehr aushalten können))))

Gott sei mit ihnen, mit diesen Seiten. Die Aufgabe ist interessant.

Siehst du, so kannst du.... Ein Rollback zum übergeordneten Knoten kann bereits im neu aufgerufenen Nachkömmling durchgeführt werden. Das heißt, wenn Sie zu einem Nachkommen gehen, geht das System zuerst auf eine niedrigere Ebene im Baum und dann auf den neu aufgerufenen Nachkommen.

Aber in dieser Option kann nicht machen Zweige mit einer Tiefe von mehr als zwei. Denn das System geht immer zurück, bevor es vorwärts geht. Das heißt, alle Funktionen werden auf der gleichen Ebene gezeichnet.

Es ist also davon auszugehen, dass wir einige Arrays von Variablen verwenden müssen, um die aktuelle Position zu ermitteln. um weiterzugehen, anstatt zurückzukehren. Genau das ist die Komplexität dieser Rückkehr...

 

In dem Anhänger "konzeptionelles Werkstück", genauer gesagt ein Beispiel für die Umsetzung. auf MT 5

Die Funktionen in() und out() müssen umgeschrieben werden, damit sie mit der Anrufliste funktionieren. Jetzt drucken sie nur noch die Ein- und Ausgaben in den Standard-Thread.

Die schlechte Nachricht: Ich habe den Traum des Themenstarters von einer Tracing-Funktion nicht gespeichert. Tut mir leid, Sergejew. :)

Die gute Nachricht: Alles funktioniert.

Benutzerhandbuch.

1. Das Makro "_in" wird am Anfang jeder Funktion eingefügt.

2. Alle Rückgabeaufrufe werden durch "_return" ersetzt.

3. Am Anfang des Programms werden zwei Defines geschrieben

#define _in in(__FUNCTION__);
#define _return out(__FUNCTION__); return


Das ist alles.

Dateien:
rettest.mq5  2 kb
 
sergeev:

Was zum Teufel ist mit diesen Seiten? Das ist eine interessante Aufgabe.

Siehst du, so kannst du.... Ein Rollback zum übergeordneten Knoten kann bereits im neu aufgerufenen Nachkömmling durchgeführt werden. Das heißt, wenn Sie zu einem Nachkommen gehen, geht das System zuerst auf eine niedrigere Ebene im Baum und dann auf den neu aufgerufenen Nachkommen.

Bei dieser Variante können Sie jedoch keine Zweige mit mehr als zwei Tiefen erstellen. Denn das System geht immer zurück, bevor es vorwärts geht. Das heißt, alle Funktionen werden auf der gleichen Ebene gezeichnet.

Es ist also davon auszugehen, dass wir einige Arrays von Variablen verwenden müssen, um die aktuelle Position zu ermitteln. um weiterzugehen, anstatt zurückzukehren. Genau das ist die Schwierigkeit bei dieser Rückkehr...

Und woher kommt eine solch seltsame Aufgabe? Lohnt sich der Aufwand für zweifelhafte Forschung, wenn man einfach zwei Funktionen - Input und Output - machen kann, ohne sich die Mühe zu machen?