アルゴリズム再考

今日はアルゴリズムについて考えてみようと思う。

なんとなくアルゴリズムを話題に出すとプログラミングのブログっぽさが増す。 茶化しているかもしれないが、アルゴリズムという単語は厄介で、この言葉をうまく扱える自信はない。 しかし、そうしてみようと思う。

アルゴリズムとは。

アルゴリズムは死生観と似ていて、この考えに取り憑かれたプログラマーは夜に眠れなくなる。

アルゴリズムは過去のものだという意見もある。 あるいはアルゴリズムは特定のライブラリを支える仕組みそのものだ。 近代的なプログラマーはアルゴリズムを意識せずとも言語そのものの機能や、ライブラリを経由して利用することができる。 蛇口をひねれば水が出てくるし、ガスコンロを捻れば火が出てくる。 その仕組みはブラックボックスのままでよい。

余談だが、学生時代にWindowsを利用していた頃はフリーソフトを必ずインストールするものだった。 私はこのソフトウェアたちがどうやって作られているか想像できなかった。 いくつかの例外はあるだろうが、大半は.Net Frameworkを利用していたり、何らかのCやC++で記述されたライブラリを組み込んだりしているだろう。 それは私が普段意識せずにNPMやRubyGemsを利用することに近い。

本質的には誰かが用意した関数を呼び出しているだけに過ぎない。 それを延々と繰り返している。 フリーソフトウェアとしてダウンロードする文化は廃れたが、クラウドになった時代でもそれは変わらない。

そう考えると普段からアルゴリズムそのものを意識する必要がないのだ。

また単純にアルゴリズムを(理解しようと思っても)理解することは難しい。

アルゴリズムを解説する書籍は本屋やAmazonでも見つけることができる。 見つけることはできるのだが、大抵はあるアルゴリズムについて解説しているものだろう。 確かに私もブログでソートを題材にして処理速度が改善したという投稿をした記憶もある。

そもそも論としてアルゴリズムは一冊の本による解説が必要なくらい難解である。 難解なアルゴリズムに時間をかけて理解できるようになったとして、何が得られるだろうか。 難解なアルゴリズムをビジュアル化して理解しやすくする試みもある。 JavaScriptとWebブラウザのおかげで文章だけでは想像がつかなかった挙動を体系的に理解できるようにもなった。

だが特定のソートについての知識を得たところで、現実の関心とかけはなれていることが多くある。 ウェブアプリケーションの実装はおよそ基本的なCRUDだけできればだいたい完結してしまう。 そうすれば必然的にアルゴリズムのことは意識する必要がない。 ゲームのプログラミングではループが非常に重要な概念ではあるが、同じプログラミングでもWebプログラミングでは繰り返しの表現くらいで、ループそのものについてはあまり気にかけない。

なのでおそらくアルゴリズムとは一定の距離を置いている(意識しないようにしている)プログラマーは一定数存在すると思う。 アルゴリズムについて調べるくらいなら新しいJavaScriptのフレームワークの使い方を調べたり、新たに追加されるEcmaScriptやTypeScriptの機能を調べる方がいくらか興味がもちやすい。 というよりは、そういった物事に追われて普遍的なアルゴリズムにまで興味が持てなかったりする。

ここまでは私が普段思っていることである。

What’s an algorithm? (アルゴリズムとは)

An algorithm is basically any piece of code that does an interesting task. (問題や課題を解決するための決まりや手順です)

So maybe it solves a problem that would take a lot of thought. (考えることが多い課題を解決できます)

このビデオではアルゴリズムの具体例で視力検査を行うアルゴリズムや次に見るべき動画を決定するものの紹介されている。

アルゴリズムに対する捉え方を変えると、実は一見ただの複雑なコードのかたまりが問題解決のためのヒントと捉えることができる。 今まではアルゴリズムを避ける理由だけを探してきたが、アルゴリズムに正面から立ち向かうことでようやく得られるものがある。 言うなれば誰かが用意した関数だけで問題が解決できるのが理想だが、普段からもっと低いレイヤーに対するアプローチも知っておく必要がある。 果たしてこのビデオではそこまで丁寧に説明してくれているわけではないが、私にはそのように聞こえた。

そのためにはやはり知識としてのアルゴリズムを理解していなければ、そもそも問題解決のきっかけすら得ることができない。

私は普段、今日みたいな休日は特にプログラミングをしている。 未だに何の変哲もないRailsでWebアプリケーションを作っている。 新しい言語で新しいフレームワークについて学習するのも興味があるのだが、大抵は新しい知識よりも単純なMVCで十分だ。 なにか新しい言語を知ったところで、WebアプリケーションはHTMLとSQLを組み合わせは変わらないのだから、既存の言語でもそこに対するアプローチを極めていったほうがよいというのがNode.JSでサーバーを書いていた頃に得た教訓である。 Rubyにはパフォーマンスの課題はよくつきまとうのだけれども、適切なプログラムを書いて遅いと感じた事は少ない。 それよりはリファレンスを延々調べ続けることの方がプログラムの実行速度より遅く感じる。

私のここ最近のコードは公開してこそいないが、デザインパターンを少しずつ取り入れることができていて、その分改善している気がする。 少なくとも安易に肥大しがちなRailsコードを完結に保つ工夫はできている。

おそらくアルゴリズムに対する興味もデザインパターンと同じだ。 うまく自分のアプリケーションに取り込むことができれば理解は進むだろう。 一口にアルゴリズムといっても、アルゴリズムにも様々な種類があることは言うまでもない。 それらのアルゴリズムを知っていれば、アプリケーションの機能として取り込むことができるかもしれない。 それはまさにプログラミングをする理由ではないだろうか。

ナップサック問題や巡回セールスマン問題のような目的がはっきりしたものであれば、そのようなユースケースが見つかるかはさておき、アルゴリズムを学習しておくモチベーションにはなる気がする。 複数の解決方法を組み合わせれば何かしら問題解決のヒントになり得るのだから。

ではこうした気づきを得て、果たして自分が今後どのようなプログラムを書くのかというと正直わからない。 1ヶ月後、1年後、あるいは今後一生変わらないかもしれない。 ビット演算子を初めて知ったときは同様の感覚に陥ったが、やはり極端に少ないメモリ環境でもない限りビット演算をする機会はない。 Enumという概念は利用するが、やはり大抵はBooleanのカラムのほうがわかりやすいし、Webアプリケーションにビット演算を必要とするケースが思いつかない。

アルゴリズムという単語が包括している概念は広いので、今後も題材にできるという意味ではブログで取り上げても尽きることはないだろう。 想定したよりもずいぶん長い文章になってしまったが、今後は具体的なアルゴリズムを題材にした投稿もしていきたい。