Vai al contenuto
PLC Forum


Ordinamento Di Vettori Con Plc


Messaggi consigliati

Inserito:

Come consigliato da Livio Orsini ho aperto una nuova discussione.

Con riferimento a quanto scritto nella discussione sull'alternanza pompe da dove si è partiti a parlare di algoritmi di ordinamento da implementare su PLC , vorrei capire quale algoritmo sia più efficace per l'ordinamento di 20-30 word in modo decrescente.

Qualche suggerimento?


Inserita:

PEr ordinare nel modo più veloce, anni fa, con google, avevo trovato trovato non meno di cinque metodi, confrontati, dove si mostrava quale era il più veloce. Però non l'ho usato sul PLC, mi in altro contesto.

Basta che cerchi con google, che trovi di tutto, poi dovrai traddurre la tecnica che più ti piace, nel codice per il PLC che usi.

Ora come ora, mi viene in mente:

- un loop che, partendo dalla prima word, se trova un valore più alto del successivo, li inverte;

- andando avanti fino alla penultima word, sei certo che l'ultima ha il valore maggiore;

- ripeti il loop, che questa volta avrà un ciclo in meno, in quanto l'ultima word è definitiva, e così, per i successivi loop dovrai farne sempre uno in meno, fino ad aver ripetuto, nel tuo caso, 19 volte il loop.

E' un poco lento, perchè hai un loop principale che gira 19 volte, che farà però un numero decrescente di iterazioni: da 19 ad 1.

Inserita:

Trattandosi di PLC è per prima cosa necessario sapere come il PLC in uso tratta indici e vettori; purtroppo non tutti i PLC hanno istruzioni ottimizzate per questo scopo.

Poi bisognerebbe valutare alcune condizioni particolari su come vengono immessi i dati ed ogni quanto tempo debbano essere ordinati.

Facciamo due casi di esempio con un vettore di 30 elementi.

Primo caso; all'accensione i dati sono già presenti in modo casuale, poi saranno aggiornati sempre in modo casuale.

Per prima cosa si procede ad un ordinamento classico, con algoritmo ricorsivo, nel momento in cui il PLC esegue l'inizializzazione ed il sistema non può ancora essere abilitato al lavoro. QUi il tempo necesario non è fondamentale.

Una volta che il vettore è ordinato e la macchina è abilitata al lavoro si potranno avere dati aggiornati. All'ingresso di ogni nuovo dato si esegue una comparazione con il valore centrale del vettore. Il risultato sarà maggiore o minore. Secondo quale risultato si è ottenuto si eseguirà la comaprazione con il valore a 1/4 o a 3/4. Si prosegue così dimezzando sempre l'intervallo, sino a che si ottiene la giusta collocazione del nuovo elemento. SI procederà poi a traslare gli altri elementi del vettore.

E' un metodo per approssimazioni successive; permette di ridurre mediamente a metà il numero di comparazioni necessarie.

Secondo caso: all'accensione il vettore è vuoto.

Man mano che si inseriscono i valori dei vari elementi si ordinano sino alla totale occupazione di tutto il vettore. Da questo momento in poi si può procedere ad aggiornare i dati con la metodologia descritta nel primo caso.

QUesti son due modi possibili. Non sono ne i migliori ne i più veloci. Le valutazioni van fatte di volta in volta in funzione del dispositivo impiegato e delle valutazioni "ambientali"

Inserita:

Cercando in vecchie riviste di programmazione ho trovato anchio l'algoritmo Bubble Sort (se a qualcuno interessa posso dogitalizzare le pagine della rivista e inviarle) che è un buon compromesso tra velocità e difficoltà di implementazione. In pratica si eseguono due loop uno esterno di lunghezza_vettore -1 passi e uno interno che ad ogni iterazione del loop esterno ne esegue uno in meno dell'iterazione precedente. In pratica ad ogni passata viene ordinato un dato , quindi la volta seguente i dati da ordinare sono uno in meno. Appena riesco provo ad implementare la funzione con S7 (io normalmente utilizzo Siemens).

  • 2 weeks later...
Inserita:

Buon giorno , ho implementato l'algoritmo di Bubble Sort con S7. Di seguito posto il codice.

Se qualcuno ha qualche suggerimento per ottimizare il codice ben venga.

FUNCTION "Bubble_Sort" : VOID
TITLE =
//Algoritmo di Bubble Sort
//Dato un vettore con n record , questi vengono riordinati in ordine crescente.
//Psudo Codice 
//for i=1 to lunghezza-1
//   for j= lunghezza downto i+1 (esegue il loop a ritroso)
//      if vettore[j] > vettore[j+1] then 
//         temp = vettore[j]
//         vettore[j] = vettore[j-1]
//         vettore[j-1] = temp
//    next j
//next i
//Viene passato in ingresso una DB organizzata nel seguente modo:
//DW0         int  Lunghezza del Vettore da Ordinare
//DW2 - DWn - int  Record del Vettore
//
//Note :
//Tempi di esecuzione con CPU 313C-2DP FW 2.6.11
// 5 record: <1 msec (circa)
//10 record: 2 msec (circa)
//20 record: 4 msec (circa)
VERSION : 0.1


VAR_INPUT
  Vettore : BLOCK_DB ;	
END_VAR
VAR_TEMP
  lung_vettore : INT ;	
  id_1 : INT ;	
  max_id_1 : INT ;	
  id_2 : INT ;	
  max_id_2 : INT ;	
  p_sorg : DWORD ;	
  p_dest : DWORD ;	
  buffer : INT ;	
END_VAR
BEGIN
NETWORK
TITLE =

// Inizializzo i dati per i due loop
      AUF   #Vettore; 
      L     DBW    0; 
      T     #lung_vettore; 
      DEC   1; 
      T     #max_id_1; 

// Inizio Loop più esterno
      L     0; 
      T     #id_1; 
NXT1: INC   1; 
      T     #id_1; 
      INC   1; 
      T     #max_id_2; 
// Inizio Loop più interno
      L     #lung_vettore; 
NXT2: T     #id_2; 
      SLW   4; 
      T     #p_sorg; 

      L     #id_2; 
      DEC   1; 
      SLW   4; 
      T     #p_dest; 

      L     DBW [#p_sorg]; 
      L     DBW [#p_dest]; 
      >I    ; 
      SPB   END2; 
      T     DBW [#p_sorg]; 
      POP   ; 
      T     DBW [#p_dest]; 
END2: L     #id_2; 
      L     #max_id_2; 
      <=I   ; 
      SPB   END1; 
      L     #id_2; 
      LOOP  NXT2; 
END1: NOP   0; 
      L     #max_id_1; 
      L     #id_1; 
      >I    ; 
      SPB   NXT1; 


END_FUNCTION


Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...