Un programmatore competente dovrebbe essere in grado di elaborare il suo algoritmo di percorso più breve?


58

Sto soffrendo una crisi di fiducia nelle mie capacità di programmatore di computer.

Ieri ho provato a elaborare il mio algoritmo del percorso più breve per un grafico e dopo alcune ore ho semplicemente gettato la spugna e appreso l'algoritmo di Dijkstra.

È questo il genere di cose che un buon programmatore dovrebbe essere in grado di "reinventare" in un paio d'ore o sono irrealistico?

Vabbè, almeno sono stato in grado di reinventare l'ordinamento delle bolle: D


7
Qualcuno che ha eseguito l'interfaccia utente per 20 anni avrà probabilmente difficoltà a trovare una soluzione a un problema di un altro dominio, in breve tempo.
Coder

38
Trascorrere molto tempo sui siti SE dà a tutti una crisi di fiducia penso! (Non che sia una brutta cosa). La felicità nella vita sta trovando il perfetto equilibrio tra l'accettazione di ciò che è e il desiderio di cambiarlo.
TrojanName,

2
Non ho potuto reinventarlo da solo, ma provo a ricordare come funziona. assicurati di comprendere questa animazione: upload.wikimedia.org/wikipedia/commons/2/23/…
Giobbe

6
@Brian Tragedia del genio locale. Non puoi quasi più essere il migliore in niente.
Rei Miyasaka,

7
un computer buon scienziato, dovrebbe, ma non necessariamente un programmatore di computer o software engineer
Neil McGuigan

Risposte:


118

Un buon programmatore dovrebbe rendersi conto che è già stato scritto un ottimo algoritmo per risolvere un problema e non perde tempo a reinventare le ruote.

Dubito che Dijkstra abbia escogitato l'algoritmo del percorso più breve in poche ore, quindi sembra uno standard davvero elevato da utilizzare per determinare se qualcuno è un "buon programmatore"


25
@Nakilon - I programmatori che ignorano le soluzioni esistenti stanno solo perdendo tempo e, se non stanno perdendo tempo, stanno facendo una soluzione peggiore. Vedi: Ognuno crea il proprio schema di hashing della password rispetto a bcrypt.
Ripristina Monica il

10
@GSto: secondo Wikipedia, Dijkstra ha escogitato l'algoritmo in meno di un'ora: 20 minuti, secondo la prima nota su Wikipedia: en.wikipedia.org/wiki/Dijkstra%27s_algorithm
woliveirajr

9
È un algoritmo relativamente semplice, ma Dijkstra aveva molto talento ed era stato addestrato in fisica teorica e matematica avanzata. Non c'è niente come pochi anni a scrivere prove per migliorare la propria capacità di progettare algoritmi.
Kevin Cline,

19
@woliveirajr - Beh, sono sicuro che Newton abbia impiegato lo stesso tempo per elaborare le leggi del movimento. Dopo averci pensato per 20 anni prima.
Rook,

6
@Nakilon - Sì, è per questo che tutti scrivono tutto in C, perché altrimenti sei solo un programmatore, usando il linguaggio di alto livello di qualcun altro. Oh aspetta, intendo assemblaggio, altrimenti stai solo usando il linguaggio di basso livello di qualcun altro. Oh aspetta, intendo azionare gli interruttori per cambiare i circuiti elettrici, altrimenti stai solo usando le istruzioni di qualcun altro. O sai, potresti semplicemente usare ciò che è già lì e lavorare per creare qualcosa di nuovo . Perché perdere tempo a reinventare l'algoritmo di Dijkstra quando puoi inventare qualcosa di nuovo, come un programma che lo utilizza?
Ripristina Monica il

54

È questo il genere di cose che un buon programmatore dovrebbe essere in grado di "reinventare" in un paio d'ore o sono irrealistico?

Innanzitutto, stai forse confondendo la programmazione con l'informatica teorica. Un programmatore fantastico ha bisogno di un buon fondamento nell'informatica ma non deve essere fantastico. Dijkstra era fantastico in informatica.

In secondo luogo, mi aspetto che chiunque abbia una buona conoscenza dei grafici sviluppi il proprio attraversamento dei grafi dopo un po 'di riflessione. Ma non un algoritmo di percorso più breve. L'algoritmo di Dijkstra in particolare è altamente sofisticato. Una volta capito, è accecantemente ovvio. Ma la maggior parte delle cose è così.

Probabilmente potresti ricavare una sorta di algoritmo del percorso più breve dopo aver provato alcune cose e aver dato all'idea un po 'di tempo. Ma non essere deluso se ci vogliono ore o anche qualche giorno. Questo è completamente OK e normale.

(Avvertenza: beh, dovresti essere in grado di forzare il problema in poche ore al massimo, ma questo non produrrebbe un algoritmo funzionante anche su grafici abbastanza piccoli.)


56
Non preoccuparti, se la forza bruta non funziona, non ne stai usando abbastanza.
Robbie,

2
+1 per chiarire la differenza tra CS teorico e programmazione. La programmazione è la risoluzione dei problemi del mondo reale e il CS teorico è lì per supportare la programmazione. Tuttavia la CS teorica non è essenziale al 100% nella programmazione quotidiana della maggior parte delle persone.
Phil,

17

È questo il genere di cose che un buon programmatore dovrebbe essere in grado di "reinventare" in un paio d'ore o sono irrealistico?

Decisamente irrealistico. La gente non si limita a "inventare" algoritmi in poche ore. Ci vuole molto sforzo e lavoro. Per citare questo blog:

In Programming Pearls, Bentley, citando Donald Knuth, afferma "Mentre la prima ricerca binaria è stata pubblicata nel 1946, la prima ricerca binaria che funziona correttamente per tutti i valori di n non è apparsa fino al 1962".

e la versione di Bentley era anche problematica quando implementata per grandi set.

Inoltre, un buon programmatore sa quali strumenti sono a sua disposizione e quando utilizzarli. Non ottieni punti extra per l'originalità o per fare le cose in modo diverso: vuoi che funzioni e funzioni bene.


1
BlackJack, ho dovuto unirmi a questo forum per sottolineare che Bentley non ha detto quello che hai affermato di aver detto: Knuth l'ha detto e Bentley lo ha citato. Quando ho letto il tuo commento ho pensato che tu avessi un buon punto, ma mi piace verificare le mie fonti e non avevo mai sentito parlare di Bentley. Tuttavia, ho sentito parlare di Knuth e posso fidarmi di quello che dice. Per favore controlla le tue fonti meglio la prossima volta.
Richard,

8
@Richard - Il commento è stato "In Programming Pearls, Bentley dice .." Knuth è stato il primo a dirlo, ma la mia fonte è Programming Pearls, non TAoCP, quindi ho scritto ciò che Bentley ha scritto. Non ho affermato che Bentley è il creatore: ho semplicemente citato ciò che viene detto nel libro. Una grande quantità di materiale nei libri non è stato inventato dagli autori stessi, quindi non vedo perché lo vedresti in quel modo.
BlackJack,

Attribuendo la citazione esclusivamente a Bentley non si ottiene il dovuto credito Knuth e, se la dichiarazione di "Bentley" era errata, si è messo Bentley nella posizione di aver prodotto informazioni errate, anziché semplicemente diffonderle. A rigor di termini, non hai detto quello che ha detto Bentley: se lo avessi fatto, avresti detto "Bentley ha detto che Knuth ha detto che ...". La citazione è ben usata qui, ma è estratta dal contesto in cui è stata detta.
Richard,

3
@Richard - La citazione che ho elencato proviene direttamente dal blog, che cita direttamente dal libro (letteralmente, penso che sia la pagina 57 della prima edizione). Se hai così tanti problemi con la dichiarazione, contatta l'autore del blog e fallo cambiare.
BlackJack,

1
@Richard e BlackJack: entrambi avete ragione, ma l'attribuzione all'autore originale aggiunge credibilità e contesto alla dichiarazione. La mia modifica dovrebbe essere sufficiente.
Steven Evers,

9

È molto improbabile che tu sia in grado di trovare una soluzione migliore di quelle che puoi scegliere.

Uscire con un algoritmo migliore di quello considerato "il migliore" (nel tuo caso, il più breve) non è qualcosa che tutti possano fare. Probabilmente non è nemmeno possibile.

Un buon programmatore dovrebbe essere in grado di comprendere la logica alla base dell'algoritmo e perché sia ​​migliore o peggiore (o semplicemente inadeguato per quel particolare problema) rispetto ad altri algoritmi che cercano di risolvere lo stesso problema.

(s) Dovrebbe anche essere in grado di sapere se è davvero il modo migliore per risolvere quel particolare problema.

Comunque, se vuoi esercitarti, puoi comunque provare a scrivere la tua implementazione personale di un algoritmo, cercando di risolvere un problema usando la tua mente. Potrebbe non essere il migliore, ma è una buona pratica per la risoluzione dei problemi.


6

Questo mi ricorda qualcosa che ho letto sulla differenza tra "ingegneria del software" (quella che definirei programmazione) e le altre discipline ingegneristiche. Vieni a pensarci, penso che fosse il libro originale di Design Patterns. Sono sicuro che qualcuno qui può citarlo dalla cima della sua testa.

Comunque, il punto (sebbene non esattamente orientato alla progettazione di algoritmi) era che le discipline ingegneristiche sono codificate; nessun ingegnere civile probabilmente passerà il tempo a cercare di reinventare l'I-beam, ma i programmatori lo fanno sempre. Il problema (e mi rendo conto che sto semplicemente facendo eco ai sentimenti di molti) è che questo comportamento è dispendioso e soggetto a errori, e serve l'ego più della soluzione.

L'informatica mi ha portato alla programmazione e adoro entrambi. Tuttavia, sono un programmatore molto migliore di un informatico. Non ti accuserei mai di essere incompetente perché non potresti reinventare l'algoritmo di Dijkstra in un pomeriggio. Metterei in dubbio la tua competenza di programmatore se non riuscissi a riconoscere un problema che potrebbe essere risolto tramite un algoritmo grafico a percorso più breve.

Detto questo, credo che pensare agli algoritmi e provare a progettarne e implementarne di nuovi sia (potenzialmente) divertente e (quasi) sempre istruttivo. Cerco solo di separare in modo chiaro il mio tempo CS dal mio tempo di programmazione. Per i programmatori, il nostro tempo (specialmente pagato) viene speso meglio per risolvere problemi pratici anziché astratti. Inoltre, il tempo CS quasi sempre distrugge la mia fiducia.


Oh l'ironia ... ora che posso commentare ovunque, dovrei eliminare la risposta che mi ha guadagnato quel privilegio? Dovrebbe esserci un distintivo per quello.
Keith Layne,

Esiste - Disciplinato , tuttavia, se la tua reputazione viene ricalcolata, tornerai indietro a 1.
ChrisF

Sì, questo è esattamente il mio punto ... Andrei ben oltre la disciplina a quel punto IMO. Se avessi convertito la mia risposta in un commento prima dell'eliminazione, avrei potuto avere tutto ... Suggerisco un nuovo badge chiamato UberDisciplined per qualsiasi eliminazione che ti faccia tornare al nuovo stato utente. :)
Keith Layne,

3

Non noterai le stesse cose che fanno tutti gli altri. Penso che sia solo un dato di fatto con cui dobbiamo convivere. Gran parte di ciò dipende dal tuo apprendimento passivo e dai modelli mentali che hai sviluppato come risultato di essi.

Conosco alcuni programmatori molto intelligenti e competenti che hanno dovuto insegnare la legge di DeMorgan a scuola prima che potessero farlo coerentemente. Mi è capitato di capire l'algoritmo di Dijkstra da solo (e devo ammettere che ne sono un po 'orgoglioso), ma mi ci è voluto molto tempo prima che potessi anche capire la specie di bolla.

Ancora più famoso, Einstein, che penseresti fosse un esperto di teoria dei nodi, non riuscì a legare i propri lacci fino a quando non aveva circa dieci anni.

È probabile che tu abbia reinventato inconsapevolmente molte cose che molti altri non avrebbero mai capito se non fosse stato per loro che è stato insegnato esplicitamente.


3

Mi permetto di differire per ciò che dice la maggior parte delle risposte. Anche se non mi aspetto che un programmatore di qualsiasi livello sia in grado di inventare da solo l'algoritmo di Dijkstra, sicuramente mi aspetterei che trovasse un modo (efficiente o meno) per risolvere il problema.

Ad esempio, hai detto come commento laterale che sei stato in grado di inventare il bubble sort da solo. So che è il più avanzato degli algoritmi di ordinamento, ma hai trovato un modo per risolvere un problema, ed è quello che mi aspetto che i programmatori siano in grado di: trovare un modo per risolvere i problemi.

Certo, anche investigare e trovare soluzioni fatte da altri funziona, ma l'estremo di quel punto è un ragazzo che non pensa a se stesso e i cui programmi sono un compendio delle ricerche di Google.

Penso di sembrare più duro di quanto realmente voglia, ma il mio punto è: mi aspetto che un programmatore sia abbastanza creativo da trovare una soluzione a un problema, anche se la soluzione è buggy o disordinata.


Quindi, tornando al tuo caso, non penso che dovresti inventare l'algoritmo di Dijkstra, ma se hai la possibilità di scrivere un algoritmo per provare diverse possibilità e trovare il percorso più breve senza finire su un ciclo infinito, allora hai la mia approvazione.

(A proposito, la mia approvazione conta nello stesso ordine di importanza di un coupon per autolavaggio gratuito.)


3
Sono d'accordo che sì, un programmatore competente dovrebbe essere in grado di elaborare una sorta di bolla o un suo equivalente. Potrebbe anche essere un uso produttivo del tempo per implementarlo e provarlo, forse solo per capire meglio il problema. Ma penso che bisogna dire che nessun programmatore competente andrebbe avanti e lo userebbe effettivamente nel codice di produzione. Questo è ciò che fa tornare i tuoi clienti l'anno prossimo e si lamenta che, ora che hanno più dati da elaborare, il tuo algoritmo O (n!) Richiederà il doppio dell'età dell'universo per completare ...
Thomas Padron-McCarthy

A chi importa se riesci a inventare algoritmi, se non riesci nemmeno a riconoscere quando fa schifo? L'autocritica è importante per un programmatore quanto la creatività. Preferirei lavorare con un programmatore che ammette rapidamente quando sanno che la loro soluzione sta impiegando troppo tempo o che è improbabile che sia la migliore, piuttosto che con un programmatore che vuole reinventare ogni ruota perché fa male al loro ego di fare diversamente.
Rei Miyasaka,

Sono d'accordo su entrambi i punti, ma penso che stiamo misurando due cose diverse. Uno è la capacità del programmatore di risolvere i problemi (qualcosa che considero essenziale). Altro è l'autocritica (lo considero essenziale ma non per la programmazione: per la vita) e la capacità di giudicare il codice (altamente desiderabile). Direi anche che le soluzioni che durano per sempre non sono realmente soluzioni, vero? ;)
Alpha

2

Sì, dovrebbe farlo.

Potrebbe essere l'equivalente morale di una sorta di bolla, ma penso che un buon programmatore dovrebbe essere in grado di trovare almeno qualcosa che funzioni, per quanto inefficiente possa essere.

Inutile dire che se si presentasse quel particolare problema, un buon programmatore verrebbe dapprima se c'è una libreria per farlo per lui, o quali algoritmi pubblicati lo fanno e sono facili da implementare.

Naturalmente, molte attività di programmazione sono molto meno difficili e non tutti devono essere in grado di affrontare problemi così difficili. Ma vorrai avere qualcuno con una mente simile nella tua squadra, perché potresti avere alcuni complicati problemi specifici del progetto in cui non puoi fare affidamento su un sacco di ricerche scientifiche precedenti.


1

Non preoccuparti

Come programmatore Perl, non sto mai reinventando la ruota. Questo è il lavoro di CPAN. Se esiste un algoritmo o un modulo semplice e ben supportato, lo usiamo. Se non c'è un buon modulo, poi ci inventiamo la ruota. Questa è una delle cose più belle di Perl.

Quindi quello che sto dicendo è questo:

  1. Non consiglio di reinventare la ruota ma quando lo fai ...
  2. Cerca di non reinventarlo completamente e ...
  3. Non preoccuparti se non puoi farlo. Ecco perché abbiamo una comunità di programmatori :-).

Non si tratta di reinventarlo, ma di risolvere i problemi in generale. Se non provi a inventare cose da solo, non migliorerai mai.
Nils,

0

La teoria dei grafi e gli algoritmi che si applicano ad esso sembrano semplici in superficie ma sono generalmente lontani da esso. Penseresti che la formazione di grafici non plananti (planari) sia semplice, ad esempio, a prima vista. L'anno scorso ho approfondito questo problema (planarità attraverso l'eliminazione dei sottografi di Kuratowski). Posso dirti, da quell'esperienza, che le persone che scrivono questi algoritmi in genere trascorrono la durata dei loro studi di dottorato a farlo, e talvolta che la ricerca viene svolta in team. E come ricercatori , questo è il loro unico focus di lavoro in quel periodo di tempo. Non è ragionevole pensare che noi ingegneri sul campo possiamo aspettarci lo stesso. Come qualcun altro qui giustamente ha detto, è accecantemente ovvio una volta che la soluzione è davanti a te. Questo sembra sempre essere il caso!


0

È questo il genere di cose che un buon programmatore dovrebbe essere in grado di "reinventare" in un paio d'ore o sono irrealistico?

Direi che se sei in grado di inventare un algoritmo per un problema ben noto come Shortest Path da solo, sei un cattivo programmatore.

Significherebbe che stai ignorando abbastanza una storia sul problema del Percorso più breve , passando da un algoritmo O (| V | ^ 4) pubblicato nel 1955 all'algoritmo O (E + V log V) pubblicato nel 1984 (che è Dijkstra algoritmo con alberi di Fibonacci). Sei quasi sicuro di fare peggio degli algoritmi già concepiti. Peggio ancora, ci sono buone probabilità che il tuo algoritmo abbia lacune o errori che lo rendono errato. Inoltre, quasi sicuramente trascorrerai molto più tempo a pensare al tuo algoritmo, implementarlo e testarlo rispetto al tempo necessario per riutilizzare un algoritmo esistente.

Lascia la progettazione degli algoritmi ai progettisti degli algoritmi. I programmatori sono consumatori dei loro risultati. I programmatori combinano algoritmi e li mettono a lavorare su compiti del mondo reale. Un ufficiale di polizia non deve essere in grado di reinventare la legge per poter lavorare o essere un buon ufficiale.

Ti incoraggio persino a utilizzare implementazioni fatte da esperti piuttosto che implementare tu stesso gli algoritmi per qualsiasi algoritmo moderatamente complicato. È più probabile che sia corretto, è probabile che lo abbiano fatto più velocemente di quanto tu abbia mai fatto e ti fa risparmiare un sacco di tempo. Ciò è particolarmente vero per gli algoritmi crittografici, perché ottieni l'ulteriore richiesta di sicurezza, che di solito solo gli esperti possono fornirti.


Gli algoritmi crittografici sono facili da verificare un'implementazione di; i vettori di test corretti noti sono un centesimo per qualsiasi algoritmo specificato pubblicamente ed è corretto o no. (È possibile ottenere prestazioni non ottimali con un'implementazione personalizzata, ma se è solo corretto, su cui si può lavorare.) La parte difficile della crittografia è qualcosa come la generazione di numeri casuali, la corretta gestione delle chiavi non elaborate e le tabelle di espansione delle chiavi in ​​memoria, corretta gestione degli input dell'utente (salting, ecc.), memorizzazione di qualcosa per permetterti di capire se i dati decifrati sono validi, e così via.
un CVn

Stavo pensando di più sulla falsariga di attacchi temporali ecc., Cose che quasi nessun programmatore conosce. Non è sempre un problema, ma comunque importante. Inoltre, la combinazione di primitive crittografiche di solito non funziona come ci si aspetta, anche questa è una parte difficile della sicurezza.
Alex ten Brink,

Mentre gli attacchi ai tempi, ecc. Sono certamente una preoccupazione valida (e non solo nella crittografia), direi che la suscettibilità di un'implementazione a questo non ha alcun impatto sulla sua correttezza . E ci sono molti, molti modi per rovinare la crittografia in modo molto più che abilitare semplicemente gli attacchi di cronometraggio. Bruce Schneier gestiva la sua serie Doghouse ; Di recente non ho visto nulla, ma ci sono molti esempi di cautela lì. google.com/search?q=site%3Aschneier.com+%22the+doghouse%22
un CVn
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.