Che cos'è esattamente un algoritmo?


12

So che questo può sembrare un po 'fuori dagli schemi, in effetti una volta pensavo sempre dentro la scatola, ma recentemente ho pensato, forse perché l'informatica offre un alto grado di libertà, su modi per ideare programmi diversi da quelli insegnati all'università.

Considera la funzione fattoriale. Tipicamente definiamo questa funzione come

 int fact(int n) 
 { 
 int r = 1; 
 for(int i=2;i<=n;i++) 
 r = r*i; 
 return r; 
 } 

Lo definirei un algoritmo e non ho dubbi che questo è il modo giusto di farlo. Quindi, mi chiedevo "posso farlo in tempo costante?", Che lascia alla seguente idea: cosa succede se avessi un array di numeri interi in cui array [n] ospita il fattoriale di n? Una volta riempito questo array, potrei semplicemente definire il fatto come:

 int fact(int n) 
 { 
 return array[n]; 
 } 

Non riesco ancora a definire questo algoritmo, anche se fornisce il risultato corretto e funziona a tempo costante O (1). Questo può essere chiamato un algoritmo? Altrimenti, perché no? Potrei sostenere che riempire l'array richiederebbe un algoritmo per funzionare in qualche momento, anche se era nel nostro cervello per riempire l'array, ma potrebbero essere questi i criteri? Come vengono gestiti formalmente questi aspetti?

Si noti che questo concetto potrebbe essere esteso a qualsiasi funzione che opera su numeri interi indipendentemente dal suo numero di argomenti, dovrei semplicemente usare una matrice se la funzione avesse 2 argomenti o 3 se la funzione avesse 3 argomenti, e così via. Inoltre, queste soluzioni non vengono utilizzate semplicemente a causa del consumo di memoria?

Inoltre, non che le funzioni possano comprendere anche qualsiasi programma con output, poiché potrei trovare un modo per indicizzare ogni singolo output possibile che un programma potrebbe fornire.

Come altro esempio, si consideri l'uso comune di un array: allocare inizialmente un array di dimensioni N, quindi aggiungo elementi all'array memorizzando il valore all'indice n e aumentando n di un'unità. Quindi, se voglio cercare un elemento, non posso fare a meno di eseguire una ricerca lineare sull'array. Se invece creassi una matrice di dimensioni, ad esempio Integer.MAXVALUE, per memorizzare numeri interi, inizializzata con zero, potrei memorizzare un numero intero posizionando 1 nel suo indice. Quindi potrei cercare la sua esistenza nell'array in O (1) volta. E se volessi poter posizionare più unità dello stesso numero? Nessun problema, aumenterei semplicemente il valore memorizzato nell'indice dell'intero.

L'ordinamento sarebbe un po 'più complicato, ma la ricerca e l'aggiunta potrebbero essere eseguite in O (1).


La tua seconda funzione dovrebbe avere l'array come parametro. Altrimenti ti perdi nella trappola imperativa dello stato implicito, che è utile nella programmazione ma può rendere molto difficile ragionare sul tuo codice.
jmite,

Sì, il tuo secondo codice può essere chiamato un algoritmo per il quale l'input è il numero n e l'array che ha tutti i fattoriali. Nel primo codice l'algoritmo ha un solo input, cioè il numero n.
Ankur,

Obbligatorio: oggi non tenterò ulteriormente di definire i tipi di materiale che intendo includere nella descrizione abbreviata ["algoritmo"], e forse non potrei mai riuscire a farlo in modo intelligente. Ma lo so quando lo vedo e le cose descritte nei post qui sotto non lo sono .
Patrick87,

In relazione a questa domanda (ma non rispondendo direttamente), è anche interessante leggere "Cos'è un algoritmo?" di Yuri Gurevich, Microsoft Research, Rapporto tecnico MSR-TR-2011-116 research.microsoft.com/pubs/155608/209-3.pdf
godfatherofpolka,

Dici: "... e se avessi un array di numeri interi in cui array [n] ospita il fattoriale di n? Una volta che questo array è riempito ....". Come hai intenzione di riempire un array con i fattoriali di tutti i numeri interi? Questo array avrebbe una dimensione infinita e richiederebbe infinito tempo per essere riempito. Pertanto la tua domanda è mal posta.
AP

Risposte:


9

La definizione informale di un algoritmo in un popolare libro di testo è simile a:

Un algoritmo è (1) una procedura computazionale ben definita (2) che accetta alcuni input e (3) produce alcuni output (4) per un problema computazionale ben definito.

Nel tuo primo caso hai codificato un algoritmo in cui: Il problema è trovare il fattoriale (parte 4 della definizione), dato int n come input (parte 2 della definizione), il codice descrive il calcolo da eseguire (parte 1 della definizione ), l'output è fattoriale (parte 3 della definizione).

Nel secondo caso: il problema è trovare l'elemento array nella posizione n (parte 4 della definizione), dato n come input (parte 3 della definizione), il codice descrive il calcolo da eseguire (parte 2 della definizione), il output è l'elemento nella posizione n (parte 1 della definizione).

Hai memorizzato fattoriali lì in modo che ti dia fattoriali. Se avessi immagazzinato quadrati o cubi lì avresti ottenuto quadrati o cubi, quindi non si può dire che il secondo frammento da solo sia un algoritmo per calcolare fattoriali.

E se dici che un array cerca insieme a un array che ha f (n) nella posizione n è un algoritmo per calcolare f (n), sei andato così in profondità che non c'è più calcolo sotto. Una procedura computazionale ben definita dovrebbe essere un'informazione finita. Se una serie infinita di fattoriali fa parte della procedura computazionale, ciò non vale. Quindi non sarebbe un algoritmo per calcolare fattoriali.


Il vero problema con il suggerimento del PO è che la descrizione della "procedura computazionale ben definita" non è limitata. Naturalmente, a meno che non spieghiamo cosa intendiamo con "procedura computazionale ben definita", non si può dire in anticipo se l'algoritmo del PO è legittimo o meno. In realtà è una "procedura computazionale ben definita" data la matrice infinita, quindi perché è illegale? L'OP può persino descrivere in termini limitati come popolare l'array. Cosa poi va storto? La tua definizione informale non è in grado di distinguere tra calcolo dell'ipercomputazione e (Turing).
Yuval Filmus,

Una procedura computazionale ben definita dovrebbe essere espressiva come un'informazione finita. Se una serie infinita di fattoriali ne fa parte, ciò non vale.
Ranbir,

2
È espressibile come un'informazione finita, come ha dimostrato l'OP. La matrice è inizializzata con tutti i fattoriali. Questa è una descrizione finita. Non è solo finito dal punto di vista operativo. Allo stesso modo, ha una descrizione finita senza essere finito. {(n,n!):nN}
Yuval Filmus,

La descrizione dell'array è espressibile come un'informazione finita ma l'array stesso non lo è.
Ranbir,

Direi che entrambi gli esempi del PO sono algoritmi e che non calcola il fattoriale per tutti i numeri interi. Ma è solo essere pignoli, suppongo.
Patrick87,

5

Più in generale, un algoritmo è una serie di passaggi per risolvere un problema .

In CS, quando si usa il termine algoritmo, sono comunemente compresi / assunti:

  • L'algoritmo ha una descrizione finita e una procedura ben definita per eseguire i suoi passi data l'istanza del problema. (Più sotto).
  • Un'istanza del problema fornita come una stringa finita (sequenza di simboli di input) e l'output dell'algoritmo possono essere codificati come una stringa finita.
  • Un problema è una raccolta di istanze problematiche insieme a possibili output "corretti" per ogni istanza. "Risolvere" significa produrre un output corretto.
  • (Di solito) le istanze problematiche possono essere arbitrariamente grandi (esiste un numero infinito di possibili istanze che l'algoritmo finito deve risolvere).

Prima della fondazione di CS, i matematici avevano gli stessi tipi di preoccupazioni che hai sollevato e hanno introdotto definizioni formali di calcolo per affrontare queste preoccupazioni. Pertanto, al giorno d'oggi, possiamo formalizzare tutti i presupposti di cui sopra semplicemente dicendo "un algoritmo è una procedura che può essere implementata su una macchina di Turing" . Questa è probabilmente la migliore risposta formale alla tua domanda.

Si noti che la tesi di Church-Turing dice che noi pensiamo non v'è alcuna formalizzazione "più potente" di algoritmi rispetto alla Macchina di Turing.

L'esempio fattoriale entra in un diverso modello di calcolo, chiamato calcolo non uniforme. Una macchina di Turing è un esempio di un modello uniforme di calcolo: ha una singola descrizione finita e funziona per input di dimensioni arbitrariamente grandi. In altre parole, esiste una TM che risolve il problema per tutte le dimensioni di input.

Ora, potremmo invece considerare il calcolo come segue: per ogni dimensione di input, esiste una TM (o qualche altro dispositivo di calcolo) che risolve il problema. Questa è una domanda molto diversa. Si noti che una singola TM non può memorizzare il fattoriale di ogni singolo numero intero, poiché la TM ha una descrizione finita. Tuttavia, possiamo creare una TM (o un programma in C) che memorizza i fattoriali di tutti i numeri inferiori a 1000. Quindi, possiamo creare un programma che memorizza i fattoriali di tutti i numeri tra 1000 e 10000. E così via.

Questi tipi di calcolo non uniformi sono tipicamente modellati in CS teorici da circuiti. Si considera una diversa costruzione del circuito per ogni possibile dimensione di ingresso.

I modelli di calcolo non uniformi non sono generalmente considerati algoritmi , anche se potrebbero adattarsi alla mia prima frase. Il motivo è che non rientrano nelle nostre ipotesi chiave: non hanno una descrizione limitata che può essere implementata per risolvere il problema "intero" per qualsiasi dimensione di input. Piuttosto, hanno bisogno di una descrizione sempre più grande man mano che il problema aumenta (come se fosse necessaria una tabella di ricerca più ampia). Tuttavia, sono ancora interessanti modelli di calcolo.


Penso che il tuo modello computazionale basato su circuito sia inappropriato. Come dici tu, una TM ha una descrizione finita. Ma ciò non preclude la presenza di un nastro ausiliario riempito con una versione tabellare di fattoriale. Si potrebbe anche fare "peggio" e avere ancora una descrizione finita. Ma davvero tutto ciò che serve è una descrizione calcolabile, che alla fine è necessariamente finita. Esistono molti modi computazionalmente uniformi per definire una macchina di Turing con un fattoriale tabulato, nessuno dei quali è in grado di aumentare effettivamente il potere computazionale di una TM. Quindi la tua conclusione non regge.
babou,

@babou, non capisco cosa intendi. Cosa intendi con "inappropriato" e quale conclusione ho fatto che è falsa? Note: non ho inventato il modello di circuito. Forse non ho fatto un buon lavoro descrivendolo. Il punto chiave è che, per ogni input, consentiamo un diverso dispositivo computazionale (TM o circuito), il che significa che potrebbe non esserci un algoritmo uniforme che genera tutti questi dispositivi (per tutte le dimensioni di input), o in altre parole, potrebbe non essere una descrizione finita che li descriva tutti.
usul

Vedere la tabulazione della funzione fattoriale come un calcolo non uniforme non mi sembra la strada giusta da percorrere. In realtà è molto uniforme, a tal punto che i suoi segmenti finiti possono essere visti come continui con un limite all'infinito che è l'intero tavolo. Questo è ciò che viene fatto con la semantica di Scott. Inoltre, l'intera tabella può essere effettivamente descritta in modo definitivo in modo calcolabile, in modo che avrebbe senso dal punto di vista computazionale considerare una TM con un nastro aggiuntivo contenente la tabella pre-calcolata. La tua risposta sembra concludere che una tabella pre-calcolata non può essere considerata un algoritmo.
babou,

Qualsiasi tabella precompilata particolare potrebbe far parte di un algoritmo e, per una sequenza infinita di tabelle precompilate sempre più grandi, è possibile produrre una di queste cose utilizzando un algoritmo. Ma non considererei un insieme infinito di tabelle di ricerca sempre più grandi come, di per sé, un algoritmo o un calcolo uniforme poiché ha dimensioni infinite.
usul,

Non lo considereresti un algoritmo. Questo è soggettivo. Ciò che conta è sapere perché non dovresti. E non c'è motivo che io possa vedere. Qualsiasi concetto che abbia senso per gli algoritmi ha senso in quel caso. Tutto ciò che fa è astrarre la creazione della tabella, anche se può essere spiegata separatamente. In realtà questa è una questione puramente semantica, poiché considerare la sequenza crescente in quanto tale o sostituirla con il suo limite infinito, equivale matematicamente alla stessa. E le teorie semantiche del calcolo considerano tali limiti infiniti, comunque prodotti o rappresentati.
babou,

4

Un algoritmo è un programma scritto in C che dovrebbe funzionare per qualsiasi lunghezza di input (presupponendo memoria infinita e numeri interi illimitati). Nei tuoi esempi, se volessimo che il programma funzioni per tutte le lunghezze di input, la tabella in cui sono memorizzati i risultati sarebbe infinitamente grande; i programmi in C sono sempre finiti, quindi questo approccio non può essere usato.

n!n!) può essere calcolato in esso in modo molto più efficiente, rispetto a C.

Quando siamo preoccupati per i tempi di esecuzione reali su un computer reale, dovremmo essere ancora più attenti, ma questo di solito è oltre i limiti dell'informatica teorica, sfortunatamente.


nn!

Quale nozione di algoritmo dovremmo usare? Un suggerimento, delineato sopra, è di usare i programmi C. Possiamo chiamare questa nozione C-computazione. Il calcolo di Turing è ciò che ottieni quando usi le macchine di Turing. Si scopre che una funzione è calcolabile in C se e solo se è calcolabile in Turing. È in questo senso che entrambi questi modelli di calcolo sono equivalenti. In effetti, molti altri modelli sono equivalenti, ad esempio tutti i linguaggi di programmazione di uso comune (assumendo memoria infinita e variabili illimitate).

Diciamo che un linguaggio di programmazione P è Turing completo è una funzione calcolabile P se e solo se è calcolabile Turing. L'ipotesi Church-Turing è un'affermazione informale secondo cui tutti i modelli di calcolo ragionevoli che hanno una descrizione finita e che impiegano un tempo finito sono completi di Turing. Il tuo modello ha una descrizione finita ma non richiede tempo finito.


3
lol "Un algoritmo è un programma scritto in C ..."?!?
vzn

2
"Un algoritmo è un programma scritto in C" ... Perché stai specificando la lingua? Non ha senso.
sostantivo

1
@nouney Sto solo cercando di essere concreto. Anche il tuo linguaggio di programmazione preferito è Turing completo.
Yuval Filmus,

@YuvalFilmus Beh, non sei concreto, sei confuso.
sostantivo

@nouney Puoi aggiungere la tua risposta.
Yuval Filmus,

4

La parte importante della definizione comune di un algoritmo che manca al tuo è che la specifica deve essere limitata e la dimensione della specifica non deve variare con la dimensione dell'input.

La memoria può essere arbitrariamente grande, così come gli input, ma per essere una definizione utile di un algoritmo, lo spazio dei codici deve essere finito. Altrimenti ottieni il problema che hai appena identificato.

O(logA)AO(logn)O(logn!)O(n(logn)2)sn=O(2s)O(2s s2)O(1)


" lo spazio del codice deve essere finito ": Intendi dire che un programma Lisp che chiama la evalfunzione su una grande struttura di dati appena creata e che rappresenta un'espressione lLisp, non può essere considerato un algoritmo. Sospetto che gran parte del codice prodotto al MIT nel 20 ° secolo non sia qualificato come algoritmo. Questo è solo un argomento informale, ma il problema formale sta nella vista di cosa sia una specifica finita, che leggi in un modo troppo restrittivo.
babou,

Se l'espressione è stata generata, è finita. Non importa quanto sia grande. Tuttavia, può essere utile rimuovere la restrizione sulla finezza dello spazio dei codici, può essere utilizzata per dimostrare limiti inferiori in fase di esecuzione (come provare un limite inferiore in fase di esecuzione dell'ordinamento degli elenchi). Ma quasi tutti i risultati interessanti sugli stessi algoritmi richiedono uno spazio dei codici finito. È simile al modo in cui i polinomi devono avere un numero finito di coefficienti, ma anche le serie di potenze sono utili.
DanielV,

Non sono un esperto di come calcolare la complessità (non il mio campo), ma il fatto che tu abbia o non abbia la matematica per farlo non dovrebbe influire su ciò che è un algoritmo. Il punto è che il programma Lisp può continuare ad aumentare le dimensioni del suo codice senza alcun limite. Quindi potrebbe avere più senso analizzare questo come un pezzo infinito di codice con proprietà computazionali specifiche. Il caso della funzione tabulata può essere visto in quella luce. Sono sorpreso che le risposte abbiano una visione così limitata (stavo per dire parrocchiale ) di cosa sia un algoritmo.
babou,

3

Alcune osservazioni che potrebbero essere utili:

I problemi sono dichiarazioni su input consentiti e output corrispondenti. Sono ciò che vogliamo risolvere. Gli algoritmi sono procedure computazionali. Possiamo dire che un algoritmo è corretto rispetto a un problema se accetta input che sono consentiti rispetto al problema e produce output in base alla descrizione del problema.

Entrambi i tuoi esempi sono algoritmi, in quanto sono entrambe procedure di calcolo chiaramente. La correttezza o meno degli algoritmi dipende da come si definisce il problema e da come si interpreta la rappresentazione dell'algoritmo. Alcune dichiarazioni di problemi:

  1. nn!
  2. n>0n!< INT_MAXn!

Alcune interpretazioni del tuo primo frammento di codice:

  1. Questo è pseudocodice che assomiglia a C / C ++ tranne nei dettagli. intsignifica davvero "qualsiasi numero intero", per esempio.
  2. Questo deve essere interpretato come se fosse un vero programma C / C ++.

L'interpretazione 1 è corretta per l'istruzione problema 1, purché il fattoriale assuma il valore 1 per i numeri negativi (altrimenti, potremmo modificare l'istruzione problema per limitare il dominio o l'algoritmo per tenere conto del comportamento desiderato). L'interpretazione 2 è corretta per l'istruzione problematica 2, con lo stesso avvertimento.

arrayarraynn>0n!< INT_MAXn!n<0

nn!232n!264

kknknk+n


Penserei che il concetto di algoritmo vada un po 'oltre i limiti delle dimensioni delle parole di un computer. Sento che stai solo schivando il problema.
babou,

1

Un algoritmo è un programma scritto in un linguaggio completo di Turing che si arresta in modo dimostrabile su tutti gli input validi. Tutti i linguaggi di programmazione standard sono completi di Turing. La parola nasce come traduzione europea del nome al-Khwārizmī, un matematico, astronomo e geografo persiano, il cui lavoro si basò su quello del matematico indiano Brahmagupta del VII secolo, che introdusse il sistema numerico indiano nel mondo occidentale.

La domanda sembra fondamentalmente se le tabelle di ricerca fanno parte degli algoritmi. Assolutamente! Nelle macchine Turing (TM) le tabelle possono essere codificate nella tabella di stato della TM. Il TM può inizializzare il nastro in base a una quantità finita di dati memorizzati nella tabella di transizione. Tuttavia, gli "algoritmi" che non funzionano su input infiniti, solo input finiti, sono macchine a stati finiti "banalmente" (FSM) .


3
Perché deve essere in una lingua completa TUring?
babou,

1

In breve : un algoritmo è la parte costruttiva di una dimostrazione costruttiva che un determinato problema ha una soluzione. La motivazione di questa definizione è l'isomorfismo di Curry-Howard tra programmi e prove, considerando che un programma ha un interesse solo se risolve un problema, ma in modo evidente. Questa definizione consente una maggiore astrazione e lascia aperte alcune porte per quanto riguarda il tipo di domini che potrebbero essere interessati, ad esempio per quanto riguarda le proprietà di finiteness.

Attenzione . Sto cercando di trovare un approccio formale adeguato per rispondere alla domanda. Penso che sia necessario, ma sembra che nessuno degli utenti che hanno risposto finora (me compreso, e alcuni erano più o meno espliciti al riguardo in altri post) ha le basi giuste per sviluppare correttamente i problemi, che sono correlati a matematica costruttiva, teoria delle prove, teoria dei tipi e risultati come l' isomorfismo di Curry-Howard tra prove e programmi. Sto facendo del mio meglio qui, con qualsiasi frammento di conoscenza che io abbia (credo di) avere, e sono fin troppo consapevole dei limiti di questa risposta. Spero solo di dare alcuni suggerimenti su come penso che dovrebbe apparire la risposta. Se vedi un punto che è chiaramente sbagliato formalmente (dimostrabilmente), per favore fammi ora in un commento - o via e-mail.

Individuare alcuni problemi

Un modo standard di considerare un algoritmo è affermare che un algoritmo è un programma arbitrariamente specificato in modo preciso per alcuni dispositivi di elaborazione , compresi quelli che non hanno limiti in memoria. Il linguaggio può anche essere il linguaggio macchina del computer. In realtà è sufficiente considerare tutti i programmi per un dispositivo di elaborazione completo di Turing (il che implica che non ha limiti di memoria). Potrebbe non darti presentazioni di tutti gli algoritmi, nel senso che gli algoritmi devono essere espressi in una forma che dipende dai suoi dettagli dal contesto di interpretazione, anche teorica, poiché tutto è definito fino a una certa codifica. Ma dal momento che calcolerà tutto ciò che deve essere calcolato, includerà in qualche modo tutti gli algoritmi, fino alla codifica.

π

π, forse nel senso matematico di quasi tutti. Ma ciò richiederebbe maggiore precisione nelle definizioni.

Quindi la vera domanda è sapere quali sono gli algoritmi significativi. La risposta è che gli algoritmi significativi sono quelli che risolvono un problema, calcolando passo dopo passo la "soluzione", la "risposta", a quel problema. Un algoritmo è interessante se è associato a un problema che risolve.

Quindi, dato un problema formale, come possiamo ottenere un algoritmo che risolva il problema. Sia esplicitamente che implicitamente, gli algoritmi sono associati all'idea che esiste una soluzione al problema, che può essere dimostrata corretta. Se le nostre tecniche di prova sono accurate è un'altra questione, ma cerchiamo almeno di convincerci. Se ti limiti alla matematica costruttiva, che in realtà è ciò che dobbiamo fare (ed è un vincolo assiomatico molto accettabile per la maggior parte della matematica), il modo per dimostrare l'esistenza di una soluzione è passare attraverso prove che mostrano effettivamente un costrutto che rappresenta la soluzione, inclusi eventualmente altri passaggi che la stabiliscono in modo corretto.

Tutti i programmatori pensano qualcosa del genere: se giocherò con i dati in tale e in quel modo, allora otterrò questo widget che ha le proprietà giuste a causa del teorema di Sesame e, eseguendo questa trasformazione che preserva i piedi, ottengo la risposta desiderata . Ma la prova è di solito informale e non elaboriamo tutti i dettagli, il che spiega perché un satellite abbia tentato di orbitare sotto terra su Marte (tra le altre cose). Facciamo molto del ragionamento, ma in realtà manteniamo solo la parte costruttiva che costruisce la soluzione e la descriviamo in un linguaggio informatico come l'algoritmo che risolve il problema.

Algoritmi (o programmi) interessanti

Tutto ciò è stato quello di introdurre le seguenti idee, che sono oggetto di molte ricerche attuali (di cui non sono uno specialista). La nozione di " algoritmo interessante " qui usata è la mia, introdotta come segnaposto informale per definizioni più precise.

Un algoritmo interessante è la parte costruttiva di una prova costruttiva che un determinato problema ha una soluzione . Ciò significa che la prova deve effettivamente mostrare la soluzione piuttosto che dimostrarne semplicemente l'esistenza, ad esempio per contraddizione. Per maggiori dettagli vedi Logica intuitiva e costruttivismo in matematica.

Questa è ovviamente una definizione molto restrittiva, che considera solo ciò che ho chiamato algoritmi interessanti. Quindi li ignora quasi tutti. Ma anche tutti i nostri libri di testo sull'algoritmo. Tentano di insegnare solo alcuni di quelli interessanti.

Dati tutti i parametri del problema (dati di input), spiega come ottenere un risultato specificato passo dopo passo. Un esempio tipico è la risoluzione delle equazioni (l' algoritmo del nome è in realtà derivato dal nome di un matematico persiano, Muhammad ibn Mūsā al-Khwārizmī , che ha studiato la risoluzione di alcune equazioni). Parti della dimostrazione vengono utilizzate per stabilire che alcuni valori calcolati nell'algoritmo hanno alcune proprietà, ma queste parti non devono essere mantenute nell'algoritmo stesso.

Naturalmente, ciò deve avvenire all'interno di un quadro logico formalizzato che stabilisce con quali dati vengono calcolati, quali sono i passaggi di calcolo elementari consentiti e quali sono gli assiomi utilizzati.

Tornando al tuo esempio fattoriale, può essere interpretato come un algoritmo, anche se banale. La normale funzione fattoriale corrisponde a una prova che, dato un quadro aritmetico e dato un numero intero n, esiste un numero che è il prodotto dei primi n numeri interi. Questo è piuttosto semplice, così come il calcolo fattoriale. Potrebbe essere più complesso per altre funzioni.

Ora, se decidi di tabellare fattoriale, supponendo che tu possa, il che non è vero per tutti gli interi (ma potrebbe essere vero per qualche dominio finito di valori), tutto ciò che stai facendo è includere nei tuoi assiomi l'esistenza di fattoriale definendo con un nuovo assioma il suo valore per ogni numero intero, in modo che non sia più necessario provare (quindi calcolare) nulla.

Ma un sistema di assiomi dovrebbe essere finito (o almeno definito in modo fine). E c'è un'infinità di valori per fattoriale, uno per intero. Quindi sei nei guai per il tuo sistema finito di assiomi se assiomi una funzione infinita, cioè definita su un dominio infinito. Ciò si traduce computazionalmente nel fatto che la tua possibile ricerca nella tabella non può essere implementata per tutti i numeri interi. Ciò ucciderebbe il solito requisito di finitezza per gli algoritmi (ma deve essere rigoroso come spesso presentato?).

Potresti decidere di avere un generatore di assiomi finemente definito per gestire tutti i casi. Ciò equivarrebbe, più o meno, a includere il programma fattoriale standard nel tuo algoritmo per inizializzare l'array secondo necessità. Questo è chiamato memoization da parte dei programmatori. Questo è in realtà il più vicino che si ottiene all'equivalente di una tabella pre-calcolata. Si può capire che ha una tabella pre-calcolata, tranne per il fatto che la tabella viene effettivamente creata in modalità di valutazione lenta , quando necessario. Questa discussione avrebbe probabilmente bisogno di cure un po 'più formali.

Puoi definire le tue operazioni primitive come desideri (in coerenza con il tuo sistema formale) e assegnare loro il costo che scegli quando usato in un algoritmo, in modo da fare analisi di complessità o prestazioni. Ma se i sistemi concreti che implementano effettivamente il tuo algoritmo (un computer o un cervello, ad esempio) non possono rispettare queste specifiche di costo, la tua analisi può essere intellettualmente interessante, ma non vale per l'uso reale nel mondo reale.

21000

Quali programmi sono interessanti

Questa discussione dovrebbe essere più propriamente collegata a risultati come l' isomorfismo di Curry-Howard tra programmi e prove. Se qualsiasi programma è in realtà una prova di qualcosa, qualsiasi programma può essere interpretato come un programma interessante nel senso della definizione sopra.

Tuttavia, per la mia (limitata) comprensione, questo isomorfismo è limitato a programmi che possono essere ben digitati in un sistema di tipizzazione appropriato, in cui i tipi corrispondono alle proposizioni della teoria assiomatica. Quindi non tutti i programmi possono qualificarsi come programmi interessanti. La mia ipotesi è che è in quel senso che un algoritmo dovrebbe risolvere un problema.

Ciò probabilmente esclude la maggior parte dei programmi "generati casualmente".

È anche una definizione piuttosto aperta di ciò che è un "algoritmo interessante". Qualsiasi programma che può essere considerato interessante lo è sicuramente, in quanto esiste un sistema di tipi identificato che lo rende interessante. Ma un programma che finora non era tipizzabile, poteva diventare scrivibile con un sistema di tipo più avanzato, e quindi diventare interessante. Più precisamente, è sempre stato interessante, ma per mancanza di conoscenza del sistema di tipi corretto, non abbiamo potuto conoscerlo.

Tuttavia, è noto che non tutti i programmi sono tipizzabili, poiché è noto che alcune espressioni lambda, come l'implementazione del combinatore Y , non possono essere digitate in un sistema di tipi di suono .

Questo punto di vista si applica solo ai formalismi di programmazione che possono essere direttamente associati ad alcuni sistemi di prova assiomatica. Non so come possa essere esteso a formalismi computazionali di basso livello come la Turing Machine. Tuttavia, poiché l'algoritmo e la calcolabilità sono spesso un gioco di codifica di problemi e soluzioni (si pensi all'aritmetica codificata nel calcolo lambda ), si può considerare che qualsiasi calcolo definito formalmente che può essere mostrato come codifica di un algoritmo è anche un algoritmo. Tali codifiche probabilmente usano solo una piccola parte di ciò che può essere espresso in un formalismo di basso livello, come le macchine di Turing.

Un interesse di questo approccio è che fornisce una nozione di algoritmo che è più astratta e indipendente dai problemi di codifica effettiva, di "rappresentabilità fisica" del dominio di calcolo. Quindi, per esempio, si possono considerare domini con oggetti infiniti purché esista un modo computazionale di usarli.


2
Questa non è una visione facile del problema, sebbene sia fondamentale. Ho dovuto semplificare oltraggiosamente e potrei aver fatto degli errori. Ma, se vuoi votare in basso, per favore dimmi perché.
babou,

Sì, non sono sicuro di cosa ci siano i voti negativi.
Pseudonimo,

@Pseudonym Nel mio caso. Penso di sapere. Sospetta che sia la vecchia battaglia tra semantisti e algoritmi, in particolare quelli che lavorano sulla computabilità. Questa è la battaglia tra filosofia e impresa, cos'è e cosa costa. Sono interessato ad algoritmi "significativi". Ho modificato di conseguenza (ma sono al limite delle mie conoscenze che sembra ancora meglio della maggior parte). Potresti soffrire della stessa ghettizzazione. - - - Tuttavia. è abbastanza chiaro che su questo argomento sottile, chiunque abbia un'opinione di mezzo centesimo non sognerà di effettuare il downgrade senza una spiegazione adeguata.
babou,

Dopo aver letto sia la domanda che la risposta, sono tentato di ridimensionarla, perché non si concentra abbastanza sulla domanda reale e contiene troppi pensieri incompiuti. Inoltre, non penso che "risolvere un problema" sia la parte mancante nella definizione di un algoritmo. Ma concordo sul fatto che la "semantica" non dovrebbe essere ignorata nella definizione di ciò che costituisce un algoritmo.
Thomas Klimpel,

@ThomasKlimpel Come ho già detto, non sono abbastanza esperto sui problemi reali. E ho aggiunto che non c'è altra risposta. Fare algoritmi non equivale a capire cosa sono. La mia consapevolezza della mia conoscenza limitata, che non sarebbe scientifico nascondere è la fonte di questo sentimento di pensieri incompiuti. Sembra meglio sottolineare l'esistenza del problema, piuttosto che ignorarli. Ho affrontato ogni esempio, più da un punto di vista semantico che da uno algoritmico, poiché la domanda è una domanda semantica ("Che cos'è ...?"). Pensi che altre risposte portino una comprensione formale. Cfr. I miei commenti
babou,

0

Non esiste una buona definizione formale di "algoritmo" al momento della scrittura. Tuttavia, ci sono persone intelligenti che ci lavorano.

Quello che sappiamo è che qualunque sia un "algoritmo", si colloca tra "funzione matematica" e "programma per computer".

Una funzione matematica è la nozione formale di una mappatura da input a output. Quindi, ad esempio, "ordinamento" è una mappatura tra una sequenza di articoli ordinabili e una sequenza di articoli ordinabili dello stesso tipo, che mappa ogni sequenza sulla sequenza ordinata. Questa funzione potrebbe essere implementata utilizzando algoritmi diversi (ad esempio, unisci ordinamento, ordinamento heap). Ogni algoritmo, a sua volta, potrebbe essere implementato utilizzando programmi diversi (anche con lo stesso linguaggio di programmazione).

Quindi il miglior modo di gestire un "algoritmo" è che si tratta di una sorta di classe di equivalenza sui programmi, in cui due programmi sono equivalenti se fanno "essenzialmente la stessa cosa". Ogni due programmi che implementano lo stesso algoritmo deve calcolare la stessa funzione, ma il contrario non è vero.

Allo stesso modo, esiste una classe di equivalenza tra algoritmi, in cui due algoritmi sono equivalenti se calcolano la stessa funzione matematica.

La parte difficile di tutto ciò è cercare di catturare ciò che intendiamo per "essenzialmente la stessa cosa".

Ci sono alcune cose ovvie che dovremmo includere. Ad esempio, due programmi sono essenzialmente gli stessi se differiscono solo per rinominazioni variabili. La maggior parte dei modelli di linguaggi di programmazione hanno nozioni native di "equivalenza" (ad es. Riduzione beta e conversione eta nel calcolo lambda), quindi dovremmo anche inserirle.

Qualunque relazione di equivalenza scegliamo, questo ci dà una struttura. Gli algoritmi formano una categoria in virtù del fatto che sono la categoria quoziente di programmi. È noto che alcune interessanti relazioni equivalenti danno origine a interessanti strutture categoriche; ad esempio, la categoria di algoritmi ricorsivi primitivi è un oggetto universale nella categoria di categorie. Ogni volta che vedi una struttura interessante come quella, sai che questa linea di indagine sarà probabilmente utile.


1
Non credo sia giusto dire che non esiste una buona definizione formale di un algoritmo. Questo è stato il caso circa 100 anni fa.
Juho,

1
@Juho Può darsi che lo pseudonimo lo sembri troppo forte, anche se cerca di mitigare l'affermazione, aggiungendo in particolare che la situazione sta facendo progressi. Tuttavia, penso che abbia piuttosto ragione nella sua valutazione. Sto reagendo tardi, perché ho trascorso molto tempo su questo, e mi sento praticamente lo stesso. Le persone hanno migliorato notevolmente la loro comprensione, ma l'intera discussione mostra che non esiste un vero consenso ... e ho trovato la maggior parte dei contributi estremamente immaturi, dato il livello delle persone coinvolte. Se è ingiusto, chi pensi abbia dato una buona definizione formale?
babou,

Hai ragione al 100%. E penso che se Turing fosse vivo, o qualsiasi altro teorico della teoria della complessità, sarebbe d'accordo al 100% con te. Gli accademici devono rinunciare al loro trogloditismo. In realtà sta ostacolando il campo. Questo alla fine accadrà comunque, una volta che moriranno. Grazie al cielo per quello.
Gode ​​di matematica il

-4

La tua domanda e descrizione non riguardano molto. L'algoritmo è teorico e non si riferisce a nessun linguaggio di programmazione. L'algoritmo è un insieme di regole o passaggi (procedura) per risolvere un problema. Il problema può essere risolto in molti modi o in molti algoritmi.

Le tue seconde soluzioni significano prima calcolare una vasta gamma di fattoriali che inizialmente impiegheranno molto tempo per poi memorizzarli. Consumerà più spazio di archiviazione, ma alla fine sarà più veloce mentre il primo non consuma spazio di archiviazione ma consuma potenza di elaborazione, quindi dovrai scegliere in base al tuo ambiente.


Sì, non c'è assolutamente alcuna relazione. Roba rivoluzionaria.
Gode ​​di matematica il
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.