Trace task (costruire il grafico di una funzione) - pagina 2

 
sergeev:
Una stessa funzione può essere chiamata sia da start che da init. Questo dovrebbe essere corretto.

Posso farlo con le dita, ma bisogna pensarci bene))

come questo:

contare il numero di funzioni, che sia 4, scrivere #define X 4 nell'intestazione del codice

supporre che il numero massimo di chiamate in un tick sia #define Y 100

abbiamo una matrice di dimensioni 4 x 100, inizializziamo matrice = -1

e ora, quando si chiama una funzione al punto di entrata della funzione, aggiungere una chiamata del contatore (modellatore di grafici), che dovrebbe aggiungere il codice (1,2,3 o 4) alla posizione desiderata X all'entrata nella nostra matrice sulla linea libera - che ha chiamato

Penso che il tuo problema sia più simile ai grafi di rete, sospetto che la matrice per i grafi di rete sia stata sviluppata da tempo - devi cercare su Google

SZY: beh, qui c'è già la 2a pagina dell'argomento ;)

 

IgorM, il modo in cui proponi di memorizzare il grafico si chiama "matrice di adiacenza". È molto antieconomico per i grafi radi (e i programmatori dovrebbero essere picchiati per l'architettura a "grafo connesso completo", ecc.)

È molto meglio usare una lista di bordi (cioè memorizziamo un array unidimensionale di strutture composto da 2 elementi - id della funzione chiamante e id della funzione chiamata; la struttura può essere completata con campi aggiuntivi - contatori di chiamata, ecc.)

p.s. Il matapparato è stato davvero sviluppato molto tempo fa :)

 
lea:

IgorM, il modo in cui proponi di memorizzare il grafico si chiama "matrice di adiacenza".

Grazie, almeno ho iniziato a ricordare qualcosa, sono passati 15 anni da quando ho studiato tutta questa roba, che non è mai stata usata nella vita reale )))) - Ma non dimenticare che "impacchettare i dati" (risparmio di memoria) - porterà ad una perdita di prestazioni a causa della maggiore complessità della matrice, anche se potrei sbagliarmi
 
MetaDriver:
Prova di impossibilità di un'idea ?
Registrare gli input e gli output delle funzioni è facile in C++,
ci sono distruttori e una cosa come lo stack unwinding.
Anche se... per lo stesso C++ ci sono librerie che permettono di costruire l'ordine delle chiamate di funzione per qualsiasi
punto del codice tramite stack.
.
Quindi... ogni ritorno significa ulteriori chiamate :-).
 
lea:
Un albero è un caso speciale di un grafo.

Sì, è quello che intendevo. Sulla base della linearità del codice MQL - sarà un albero nella sua forma pura. Dato che i nodi non punteranno l'uno all'altro.

IgorM:
avere una matrice di dimensione 4 x 100, inizializzare la matrice = -1
e ora quando chiamiamo la funzione al punto di entrata della funzione aggiungiamo una chiamata del contatore (graph shaper) che dovrebbe aggiungere un codice (1,2,3 o 4) nella posizione richiesta X alla riga libera all'entrata nella nostra matrice - che ha chiamato

Sì, ora lo vedo. Ma mi sembra che questo approccio sia davvero laborioso non tanto in codice, quanto in risorse e preparazione per l'analisi. Per la ramificazione si dovrebbe fare una matrice tridimensionale.
In generale, l'opzione è accettata. Ma lasciamolo a pagina 4 del riassunto per ora :)

Penso che il tuo problema sia più simile ai grafi di rete, sospetto che l'apparato matematico per i grafi di rete sia stato sviluppato da tempo - devi cercare su Google

Il compito non è né un know-how, né una novità. Un semplice grafico di funzioni. Niente di più.
Non c'è una nuova matematica, abbiamo solo bisogno di una versione semplificata il più possibile.

 
lea:

È molto meglio usare l'edge list (cioè memorizzare un array unidimensionale di strutture composto da 2 elementi - id della funzione chiamante e id della funzione chiamata; la struttura può essere completata con campi aggiuntivi - contatori di chiamata, ecc.)

Eugene, questo è esattamente ciò che è già stato fatto.

Ma il codice si è bloccato. Per il terzo giorno non riesco a dormire o a bere.... . :)

Non riesco a capire come fare il ritorno dal bordo (più precisamente dal nodo discendente) al nodo padre per andare al nuovo bordo (nuovo nodo discendente). Ma per mantenere la regola - usiamo solo una funzione di tracciamento all'inizio della funzione sorgente.

 
sergeev:

Non riesco a capire come fare un ritorno da una costola a un nodo per andare in un nuovo ramo.


E tutto con una funzione che ha già fatto un passaggio in avanti? Questo è abbastanza - per fare un ritorno senza fare nulla)) Va bene, è già la seconda pagina, Vladimir non lo sopporterà più)))
 
alsu:
E tutto con una sola funzione che ha già fatto un passaggio in avanti? Hai fatto abbastanza - fai un ritorno senza fare assolutamente nulla))) Beh, niente, è la seconda pagina è già finita, presto Vladimir non sarà in grado di sopportarlo))))

Dio sia con loro, con queste pagine. Il compito è interessante.

Vedete, è così che si può.... Il rollback al nodo padre può essere fatto già nel nuovo discendente chiamato. Cioè, quando si va al discendente, il sistema scenderà prima nell'albero fino a un livello inferiore, e poi salirà fino al nuovo discendente chiamato.

Ma in questa opzione non può fare rami con una profondità di più di due. Perché il sistema tornerà sempre indietro prima di andare avanti. Cioè, tutte le funzioni saranno disegnate allo stesso livello.

Così sembra che dovremo usare alcuni array di variabili, per identificare la posizione attuale. per andare oltre e non tornare. È esattamente la complessità di questo ritorno...

 

Nel rimorchio "pezzo concettuale", più precisamente un esempio di implementazione. su MT 5

Le funzioni In() e Out() devono essere riscritte per farle funzionare con la lista delle chiamate. Ora si limitano a stampare gli input e gli output nel thread standard.

Cattive notizie: non ho salvato il sogno del topicstarter di una funzione di tracciamento. Scusa Sergeyev. :)

Buone notizie: tutto funziona.

Manuale d'uso.

1. La macro "_in" è inserita all'inizio di ogni funzione.

2. Tutte le chiamate di ritorno sono sostituite da "_return".

3. Due definizioni sono scritte all'inizio del programma

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


Questo è tutto.

File:
rettest.mq5  2 kb
 
sergeev:

Che diavolo di queste pagine. È un compito interessante.

Vedete, è così che si può.... Il rollback al nodo padre può essere fatto già nel nuovo discendente chiamato. Cioè, quando si va al discendente, il sistema scenderà prima nell'albero fino a un livello inferiore, e poi salirà fino al nuovo discendente chiamato.

Ma in questa variante non si possono fare rami con più di due profondità. Perché il sistema tornerà sempre indietro prima di andare avanti. Cioè, tutte le funzioni saranno disegnate allo stesso livello.

Quindi si pensa che dovremo usare alcuni array di variabili, per identificare la posizione attuale. per andare avanti, piuttosto che tornare. Questa è esattamente la difficoltà di questo ritorno...

E da dove viene un compito così strano? Vale la pena spendere sforzi in ricerche dubbie, quando si possono semplicemente fare due funzioni - input e output - e non preoccuparsi?
Motivazione: