Чи повинен компетентний програміст придумати свій алгоритм найкоротшого шляху?


58

Я переживаю кризу впевненості у своїх можливостях як комп'ютерного програміста.

Вчора я спробував придумати свій власний найкоротший алгоритм для графіка, а через кілька годин я просто кинув рушник і вивчив алгоритм Дікстра.

Це така річ, яку хороший програміст повинен мати можливість «винаходити» за пару годин, чи я нереальний?

Ну добре, принаймні мені вдалося винайти сортування міхурів: D


7
Комусь, хто користувався інтерфейсом користувача протягом 20 років, напевно, буде важко знайти рішення проблеми з іншого домену за короткий проміжок часу.
Кодер

38
Проведення багато часу на сайтах ДП дає всім кризу впевненості, я думаю! (Не те, що це погано). Щастя в житті - це знаходження ідеального балансу між прийняттям того, що є, і бажанням його змінити.
TrojanName

2
Я сам не міг її винаходити, але намагаюся згадати, як це працює. переконайтеся, що ви розумієте цю анімацію: upload.wikimedia.org/wikipedia/commons/2/23/…
робота

6
@ Бріанська трагедія місцевого генія. Навряд чи ти можеш бути найкращим у чомусь більше.
Rei Miyasaka

7
хороший вчений- комп'ютер повинен, але не обов'язково, програміст або інженер-програмний інженер
Ніл МакГуйган

Відповіді:


118

Хороший програміст повинен усвідомити, що для вирішення проблеми вже написаний чудовий алгоритм і не витрачає час на переосмислення коліс.

Я сумніваюсь, Dijkstra придумав алгоритм найкоротшого шляху за кілька годин, так що це здається дійсно високим стандартом, який слід визначити, хтось "хороший програміст"


25
@Nakilon - Програмісти, які ігнорують існуючі рішення, просто витрачають свій час, і якщо вони не витрачають час, вони роблять гірше рішення. Див.: Кожен розробляє власну схему хешування паролів проти bcrypt.
Відновіть Моніку

10
@GSto: згідно з Вікіпедією, Dijkstra придумав алгоритм менше ніж за годину: 20 хвилин, згідно першої замітки у wikipedia: en.wikipedia.org/wiki/Dijkstra%27s_algorithm
woliveirajr

9
Це відносно простий алгоритм, але Дайкстра був дуже талановитим і пройшов навчання з теоретичної фізики та передової математики. Немає нічого, як кілька років писати докази, щоб покращити вміння розробляти алгоритми.
кевін клайн

19
@woliveirajr - Ну, я впевнений, що Ньютону потрібно було стільки ж часу, щоб придумати закони руху. Після цього подумав спочатку 20 років.
Грак

6
@Nakilon - Так, тому всі пишуть все на C, бо інакше ти просто кодер, використовуючи чужу мову високого рівня. О, зачекайте, я маю на увазі збірку, інакше ви просто використовуєте чужу мову низького рівня. О зачекайте, я маю на увазі перемикання перемикачів для зміни електричних ланцюгів, інакше ви просто використовуєте чужий набір інструкцій. Або ви знаєте, ви могли просто використати те, що вже є, і попрацювати над створенням чогось нового . Навіщо витрачати час на переосмислення алгоритму Діккстри, коли можна вигадати щось нове, наприклад програму, яка його використовує?
Відновіть Моніку

54

Це така річ, яку хороший програміст повинен мати можливість «винаходити» за пару годин, чи я нереальний?

По-перше, ви, можливо, плутаєте програмування з теоретичною інформатикою. Фантастичному програмісту потрібен хороший фундамент інформатики, але йому не потрібно бути фантастичним. Дайкстра був фантастичним в галузі інформатики.

По-друге, я б очікував, що хтось із чітким розумінням графіків розробить власний обхід графів після роздумів. Але не найкоротший алгоритм шляху. Зокрема, алгоритм Дейкстри є надзвичайно складним. Як тільки ви це зрозумієте, це сліпо очевидно. Але більшість речей саме так.

Можливо, ви могли б отримати якийсь алгоритм найкоротшого шляху, спробувавши деякі речі та давши ідеї деякий час. Але не розчаруйтесь, якщо це займе години, а то й кілька днів. Це повністю нормально і нормально.

(Caveat: ну, ви повинні мати можливість вирішити проблему за кілька годин, але це не призведе до роботи алгоритму навіть на досить малих графіках.)


56
Не хвилюйтесь, якщо груба сила не працює, ви просто не використовуєте її достатньо.
Роббі

2
+1 для усунення різниці між теоретичним КС та програмуванням. Програмування - це вирішення проблем у реальному світі, і теоретичний КС є для підтримки програмування. Однак теоретичний КС не є на 100% важливим у повсякденному програмуванні більшості людей.
Філ

17

Це така річ, яку хороший програміст повинен мати можливість «винаходити» за пару годин, чи я нереальний?

Однозначно нереально. Люди не просто "придумують" алгоритми за кілька годин. Це вимагає багато зусиль і роботи. Щоб процитувати цей блог:

У програмуванні Pearls Бентлі, цитуючи Дональда Кнута, зазначає: "Поки перший бінарний пошук був опублікований у 1946 році, перший бінарний пошук, який працює правильно для всіх значень n, з'явився до 1962 року".

і версія Bentley також була проблематичною, коли вона реалізована для великих наборів.

Крім того, хороший програміст знає, які інструменти є в його розпорядженні та коли їх використовувати. Ви не отримуєте додаткових балів за оригінальність або робити щось інакше - ви хочете, щоб це працювало і працювало добре.


1
Блекджек, мені довелося приєднатися до цього форуму, щоб зазначити, що Бентлі не сказав того, що ти стверджував, що він сказав: Кнут сказав це, і Бентлі цитував його. Коли я прочитав ваш коментар, я подумав, що ви зробили хорошу думку, але мені подобається перевіряти свої джерела і ніколи не чув про Бентлі. Однак я чув про Кнут і можу довіряти тому, що він говорить. Будь ласка, перевірте свої джерела краще наступного разу.
Річард

8
@Richard - коментар був "У програмуванні перлів, Бентлі каже." Кнут першим сказав це, але моє джерело - програмування перлів, а не TAoCP, тому я написав те, що написав Бентлі. Я не стверджував, що Бентлі є автором - я просто цитував те, що сказано в книзі. Велика кількість матеріалів у книгах не були винайдені самими авторами, тому я не бачу, чому б ви бачили саме так.
BlackJack

Привласнюючи цитату виключно Bentley, ви не отримуєте належного кредиту Knuth, і якщо вислів "Bentley" був невірним, ви ставите Bentley в позицію неправдивої інформації, а не просто поширювати її. Строго кажучи, ви не сказали того, що сказав Бентлі: якби у вас був, ви б сказали: "Бентлі сказав, що Кнут сказав, що ...". Цитата тут добре використовується, але вона виведена з контексту, в якому вона була сказана.
Річард

3
@Richard - Цитата, яку я перерахувала, безпосередньо з блогу, який цитує безпосередньо з книги (буквально, я думаю, це сторінка 57 першого видання). Якщо у вас є стільки проблем із заявою, тоді зв’яжіться з автором блогу і змусьте його змінити.
BlackJack

1
@Richard та BlackJack: Ви обоє правильні, але віднесення до оригінального автора додає висловлюванню довіру та контекст. Моя редакція повинна бути достатньою.
Стівен Еверс

9

Навряд чи ви зможете знайти краще рішення, ніж ті, з яких ви можете вибрати.

Виходити з кращим алгоритмом, ніж той, який вважається "найкращим" (у вашому випадку найкоротшим) - це не те, що кожен може зробити. Напевно, це навіть неможливо.

Хороший програміст повинен вміти розуміти логіку алгоритму, і чому він кращий чи гірший (або просто неадекватний цій конкретній проблемі), ніж інші алгоритми, які намагаються вирішити ту саму проблему.

(s) Він також повинен мати можливість знати, чи справді це найкращий шлях для вирішення конкретної проблеми.

У будь-якому випадку, якщо ви хочете попрактикуватися, ви все ще можете спробувати написати свою персональну реалізацію алгоритму, намагаючись вирішити проблему, використовуючи свій розум. Це може бути не найкращим, але це хороша практика для вирішення проблем.


6

Це нагадує мені щось, що я читав про різницю між "інженерією програмного забезпечення" (що я б назвав програмуванням) та іншими інженерними дисциплінами. Подумайте про це, я думаю, це була оригінальна книга "Шаблони дизайну". Я впевнений, що хтось тут може процитувати це з голови.

У будь-якому разі, суть (хоча не зовсім орієнтована на розробку алгоритму) полягала в тому, що інженерні дисципліни кодифіковані; жоден інженер-цивільний інженер, ймовірно, не витратить час, намагаючись винаходити променеву балку, але програмісти роблять це постійно. Проблема (і я усвідомлюю, що я просто повторюю почуття багатьох) полягає в тому, що така поведінка є марною і схильною до помилок, і служить его більше, ніж рішення.

Інформатика привела мене до програмування, і я обоє люблю. Однак я набагато кращий програміст, ніж інформатик. Я ніколи не звинувачував би вас у некомпетентності, оскільки ви не змогли винайти алгоритм Дейкстри вдень. Я б поставив під сумнів вашу компетентність програміста, якщо ви не зможете розпізнати проблему, яку можна вирішити за допомогою алгоритму графіків найкоротшого шляху.

З цього приводу я вважаю, що думати про алгоритми та намагатися розробляти та впроваджувати нові - це (потенційно) цікаво і (майже) завжди повчально. Я просто намагаюся чітко відокремити час свого CS від мого часу програмування. Для програмістів наш (особливо оплачуваний) час краще витратити на вирішення практичних завдань, а не на асфрактних. Крім того, час КС майже завжди руйнує мою впевненість.


О іронія ... тепер, коли я можу коментувати де завгодно, чи слід видалити відповідь, яка принесла мені цей привілей? Для цього повинен бути знак.
Кіт Леййн

Є - Дисципліновано, проте, якщо ваша репутація буде перерахована, ви повернетесь до 1.
ChrisF

Так, це якраз моя думка ... Я б переходив вище дисципліни в той момент ІМО. Якщо я перетворив свою відповідь на коментар перед видаленням, я міг би це все мати ... Я пропоную новий знак під назвою UberDiscip дисципліна для будь-якого видалення, яке змушує вас повернутися до нового статусу користувача. :)
Кіт Лейн

3

Ви не збираєтесь помічати ті самі речі, що і всі інші. Я думаю, що це просто факт життя, з яким нам доводиться жити. Багато чого зводиться до вашого пасивного навчання та розумових моделей, які ви розробили в результаті їх.

Я знаю деяких дуже розумних та компетентних програмістів, яким доводилося навчати закону DeMorgan у школі, перш ніж вони могли це робити послідовно. Мені довелося самостійно розібратися з Алгоритмом Дейкстри (і я повинен визнати, що я трохи пишаюся цим), але це пройшло у мене дуже багато часу, поки я навіть не міг зрозуміти сортування бульбашок.

Більше відомо, що Ейнштейн, який, на вашу думку, може бути знавцем теорії вузлів, не міг пов'язати власні шнурки, поки йому не виповнилося десять років.

Цілком ймовірно, що ви несвідомо винаходили багато речей, чого багато інших ніколи б не зрозуміли, якби не вчити їх явно.


3

Я прошу відрізнятись від того, що говорить більшість відповідей. Хоча я не очікував, що програміст будь-якого рівня зможе самостійно придумати алгоритм Діккстри, я, безумовно, сподівався, що він придумає будь-який спосіб (ефективний чи ні) для вирішення проблеми.

Наприклад, ви сказали в якості побічного коментаря, що вам вдалося придумати сортування міхурів самостійно. Я знаю, що це найсміливіші алгоритми сортування, але ви знайшли спосіб вирішити проблему, і саме це я очікую, що програмісти зможуть: знайти спосіб вирішити проблеми.

Звичайно, дослідження та пошук рішень, здійснених іншими, також працюють, але крайність цього пункту - це хлопець, який не думає про себе і програми якого є складовою пошукових запитів Google.

Я думаю, що я звучу суворіше, ніж я насправді хочу, але моя думка: я б очікував, що програміст буде достатньо креативним, щоб прийти до вирішення проблеми, навіть якщо рішення неприємне чи безладне.


Отже, повертаючись до вашої справи, я не думаю, що вам не доведеться придумати алгоритм Дейкстри, але якщо у вас є можливість написати алгоритм, щоб випробувати кілька можливостей і знайти найкоротший шлях, не закінчуючи нескінченний цикл, то ти отримав моє схвалення.

(BTW мій дозвіл вважається таким же порядком важливості, що і купон на безкоштовну автомийку.)


3
Я погоджуюся, що так, грамотний програміст повинен мати можливість придумати сортування бульбашок або його аналог. Це може бути навіть продуктивне використання часу, щоб реально його реалізувати та спробувати, можливо, просто, щоб краще зрозуміти проблему. Але я думаю, що потрібно сказати, що жоден грамотний програміст не продовжував і фактично використовував це у виробничому коді. Це робить те, що змушує ваших клієнтів повернутися в наступному році і скаржитися, що тепер, коли вони мають більше даних для обробки, ваш алгоритм O (n!) Потребуватиме завершення удвічі більше, ніж у Всесвіті ...
Томас Падрон-Маккарті

Кому байдуже, чи можна вигадувати алгоритми, якщо ви навіть не можете розпізнати, коли він смокче? Самокритика так само важлива для програміста, як і творчість. Я вважаю за краще працювати з програмістом, який швидко визнати, коли вони знають, що їхнє власне рішення забирає занадто довго або навряд чи буде найкращим, ніж із програмістом, який хоче винаходити кожне колесо, оскільки це пошкоджує його его, чинити інакше.
Rei Miyasaka

Я погоджуюся в обох точках, але я думаю, що ми вимірюємо дві різні речі. Один - це можливість програміста вирішувати проблеми (те, що я вважаю важливим). Інше - це самокритика (я вважаю це важливим, але не для програмування: для життя) та здатність судити про код (дуже бажано). Я також хотів би сказати, що рішення, які приймаються назавжди, насправді не є рішеннями, чи не так? ;)
Альфа

2

Так, він / вона повинен.

Це може бути моральний еквівалент сортування бульбашок, але я думаю, що хороший програміст повинен мати можливість придумати хоча б щось, що працює, як би неефективно це не було.

Потрібно сказати, що якщо ця конкретна проблема виникне, хороший програміст спочатку подивиться, чи є бібліотека для цього, або які опубліковані алгоритми це роблять і їх легко реалізувати.

Звичайно, багато завдань програмування набагато менш складні, і не кожному потрібно вміти вирішувати такі важкі проблеми. Але ви хочете мати когось із таким розумом у вашій команді, тому що у вас можуть виникнути складні проблеми, специфічні для проекту, де ви не можете розраховувати на навантаження попередніх наукових досліджень.


1

Не хвилюйся

Як програміст Perl, я майже ніколи не винаходив колесо. Це робота CPAN. Якщо є простий, добре підтримуваний алгоритм або модуль, ми використовуємо його. Якщо не хороший модуль, то ми винайшли колесо. Це одна з найбільших речей про Perl.

Тому я говорю це:

  1. Я не рекомендую винаходити колесо, але коли ви це зробите ...
  2. Намагайтеся не повністю винаходити це і ...
  3. Не хвилюйтесь, якщо ви не можете цього зробити. Ось чому у нас є спільнота програмування :-).

Мова не про винахід, а про вирішення проблем загалом. Якщо ви не намагаєтесь вигадувати речі самостійно, ви ніколи не вдосконалитеся.
Нілс

0

Теорія графіків та алгоритми, що застосовуються до нього, виглядають просто на поверхні, але, як правило, далеко від нього. Ви можете подумати, що, на перший погляд, формування непересічних (планарних) графіків є простим. Минулого року я детально розглядав цю проблему (планарність через усунення підграфів Куратовського). З цього досвіду я можу сказати, що люди, які пишуть ці алгоритми, зазвичай проводять тривалість докторантури, роблячи це, а іноді дослідження проводяться в командах. І як дослідники , це єдина їх робоча спрямованість протягом цього періоду часу. Нерозумно думати, що ми на місцях інженери можемо очікувати того самого. Як справедливо сказав хтось тут, його сліпо очевидно, коли рішення стоїть перед вами. Це завжди здається так!


0

Це така річ, яку хороший програміст повинен мати можливість «винаходити» за пару годин, чи я нереальний?

Я б сказала, що якщо ви зможете самостійно винайти алгоритм для відомої проблеми, як найкоротший шлях, ви будете поганим програмістом.

Це означатиме, що ви ігноруєте досить історію проблеми найкоротшого шляху , переходячи від алгоритму O (| V | ^ 4), опублікованого в 1955 році, до алгоритму O (E + V log V), опублікованого в 1984 році (що є Dijkstra алгоритм з деревами Фібоначчі). Ви майже гарантовано зробите гірше, ніж вже розроблені алгоритми. Що ще гірше, є великий шанс, що ваш алгоритм має прогалини або помилки, роблячи його неправильним. Крім того, ви майже напевно витратите набагато більше часу на продумування свого алгоритму, його реалізацію та тестування, ніж час, який знадобиться для повторного використання існуючого алгоритму.

Залиште розробку алгоритмів розробникам алгоритмів. Програмісти - споживачі їх результатів. Програмісти поєднують алгоритми і ставлять їх для роботи над реальними завданнями. Поліцейському не потрібно вміти винаходити закон, щоб мати можливість працювати чи бути хорошим офіцером.

Я навіть закликаю вас використовувати реалізації, зроблені експертами, а не впроваджувати алгоритми самостійно для будь-яких помірно складних алгоритмів. Це вірогідніше, що це правильно, швидше за все, це зробить це швидше, ніж ви коли-небудь, і це економить вам багато часу. Це особливо вірно для криптографічних алгоритмів, тому що ви отримаєте додатковий попит безпеки, які , як правило , тільки фахівці можуть надати вам.


Криптографічні алгоритми легко перевірити реалізацію; відомі правильні тестові вектори - це десяток десятка для будь-якого загальнодоступного алгоритму, і це правильно чи ні. (Ви можете отримати неоптимальну продуктивність із власною реалізацією, але якщо це тільки правильно, над цим можна працювати.) Важкою частиною криптографії є ​​такі речі, як генерація випадкових чисел, правильне поводження із нераціональними ключами та таблицями розширення ключів у пам'яті, власне обробка введених даних користувачів (засолювання тощо), зберігання чогось, щоб ви могли з'ясувати, чи є дешифровані дані дійсними тощо.
CVn

Я думав більше по лінії синхронних атак тощо, про які майже ніхто не знає програміста. Це не завжди питання, але все-таки важливе. Крім того, поєднання криптографічних примітивів зазвичай не працює так, як очікується, це також є важкою частиною безпеки.
Алекс десять Бринк

Хоча тимчасові атаки тощо, безумовно, є важливою проблемою (і не тільки в криптографії), я б стверджував, що сприйнятливість програми до таких не впливає на її правильність . І є багато, багато способів помилитися з криптографічним способом більше, ніж просто вмикати тайм-атаки. Брюс Шнайер використовував для запуску своєї серії Doghouse ; Я нещодавно в цьому нічого не бачив, але є багато застережних прикладів. google.com/search?q=site%3Aschneier.com+%22the+doghouse%22
CVn
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.