Analisi della complessità degli algoritmi sulle implementazioni del linguaggio di programmazione funzionale


10

Ho imparato oggi che l'analisi dell'algoritmo differisce in base al modello computazionale. È qualcosa a cui non ho mai pensato o sentito parlare.

Un esempio che mi è stato illustrato, che lo ha ulteriormente illustrato, dall'utente @chi è stato:

Ad esempio, considerare l'attività: dato restituisce . Nella RAM questo può essere risolto in poiché l'accesso all'array è a tempo costante. Usando le TM, dobbiamo scansionare l'intero input, quindi èx i O ( 1 ) O ( n )(i,x1,,xn)xiO(1)O(n)

Questo mi fa meravigliare dei linguaggi funzionali; Da quanto ho capito, "I linguaggi funzionali sono intimamente correlati al calcolo lambda" (da un commento di Yuval Filmus qui ). Quindi, se i linguaggi funzionali sono basati sul calcolo lambda, ma funzionano su macchine basate su RAM, qual è il modo corretto di eseguire analisi di complessità su algoritmi implementati usando strutture e linguaggi di dati puramente funzionali?

Non ho avuto l'opportunità di leggere Strutture di dati puramente funzionali, ma ho esaminato la pagina di Wikipedia per l'argomento e sembra che alcune delle strutture di dati sostituiscano le matrici tradizionali con:

"Le matrici possono essere sostituite da una mappa o da un elenco di accessi casuali, che ammette un'implementazione puramente funzionale, ma i tempi di accesso e aggiornamento sono logaritmici."

In tal caso, il modello computazionale sarebbe diverso, giusto?


3
Sicuramente non sono un esperto di questo argomento, ma credo di aver sentito che 1) una macchina lisp-like (con il suo modello di costo) può simulare programmi RAM con un fattore aggiuntivo (sembra facile dimostrarlo) e 2) se questo fattore sia realmente necessario è ancora un problema aperto. Inoltre, si può sostenere che l'assegnazione di un costo O (1) all'accesso all'array nel modello RAM è troppo generosa. Nell'hardware, l'accesso alla memoria deve attraversare porte O ( log n ) dove n è la dimensione della memoria fisica. O(logn)O(logn)n
Chi,

1
Inoltre, tieni presente che praticamente tutte le lingue FP del mondo reale hanno array in qualche forma, con un tempo di accesso garantito (come nelle lingue imperative). Questo è generalmente risolto aggiungendoli come una lingua primitiva. O(1)
Chi,

1
Un esempio di un diverso modello computazionale sarebbe il numero di riduzioni beta fatte su un termine di calcolo lambda. In FP stiamo usando un modello di ariete vestito come un calcolo lambda, se questo ha senso
Kurt Mueller,

1
@KurtMueller Nota che possiamo ottenere un termine lambda di dimensione dopo solo riduzioni di bete O ( n ) . Questo rende irrealistico il modello di costo del conteggio del numero di beta. Probabilmente uno migliore potrebbe essere quello di pesare ogni passo in base alla dimensione dei termini a portata di mano. Tuttavia, questo non è l'unico modello possibile: la valutazione ottimale dei termini lambda non applica la beta in modo ingenuo, preferendo alcune macchine di riduzione dei grafici più sofisticate. In tal caso, il conteggio dei beta non sarebbe probabilmente appropriato. O(2n)O(n)
Chi,

1
Nota che devi anche sapere se il tuo linguaggio funzionale è desideroso o pigro / rigoroso o non rigoroso. Di recente ho riscontrato una situazione in cui un algoritmo del mondo reale era polinomiale in Haskell (non rigoroso) ma la traduzione ingenua in OCaml (rigoroso) era esponenziale.
Eric Lippert,

Risposte:


6

Dipende dalla semantica del tuo linguaggio funzionale. Non è possibile eseguire analisi di algoritmi su linguaggi di programmazione in isolamento, perché non si conosce il significato delle affermazioni. Le specifiche per la tua lingua devono fornire una semantica sufficientemente dettagliata. Se la tua lingua specifica tutto in termini di calcolo lambda, hai bisogno di una misura dei costi per le riduzioni (sono O (1) o dipendono dalla dimensione del termine che riduci?).

Penso che la maggior parte dei linguaggi funzionali non lo facciano in questo modo e forniscano invece istruzioni più utili come "le chiamate di funzione sono O (1), aggiungendo a capo di un elenco è O (1)", cose del genere.


Credo di capire in qualche modo la tua risposta (il malinteso è molto probabilmente dovuto alla mia mancanza di comprensione nel calcolo lambda): Stai dicendo che devi fondamentalmente fare l'analisi caso per caso (caso che sia il linguaggio), piuttosto che un modo generale, perché alcune operazioni hanno significati diversi per lingua. La mia comprensione è corretta?
Abdul,

Sì. Il progettista della lingua deve dirti cosa significano effettivamente le cose che puoi scrivere nella lingua prima di poter analizzare il runtime di un algoritmo.
adrianN,

"Non è possibile eseguire analisi di algoritmi su linguaggi di programmazione isolati" - si riferiva a linguaggi FP o linguaggi in generale? Se si riferiva al precedente, allora come possiamo algoritmo di analisi a scuola in modo così generale, cioè fare analisi su problemi Java, C / C ++, Python? È perché sono tutti molto simili? O è perché le strutture dati e gli ADT sottostanti sono tutti uguali e implementati allo stesso modo? O infine, è perché questi corsi sono semplicemente a scopo educativo e non devono necessariamente essere rigorosamente precisi?
Abdul,

1
È vero per tutti i linguaggi di programmazione. Per essere strettamente corretti, devi prima correggere un modello di macchina, dire la RAM e (una piccola manciata) di istruzioni che supporta. Puoi fare analisi sui programmi solo usando solo quelle istruzioni. Quindi puoi pensare a una mappatura del tuo linguaggio di programmazione su quel modello di macchina. Quindi è possibile analizzare i programmi nel linguaggio di programmazione. Per un trattamento molto rigoroso controlla come Knuth lo fa in The Art of Computer Programming. Molte di queste cose possono essere semplificate a causa delle costanti che nascondono i big-O.
adrianN,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.