loading...

競技プログラミングで、日本を高度IT人材大国に!No.1

本当に不足しているIT人材を知るために、本当に必要なもの

2019/10/03

2030年には高度IT人材が数十万人不足するといわれていますが、実は、日本にはプログラミング能力が世界トップレベルの高度IT人材が多数いることを知っていますか?

本連載では、企業の業績を左右するほど重要になった高度IT人材の採用と育成について、競技プログラミングコンテストAtCoderの高橋直大代表に解説いただきます。自身も世界トップクラスのプログラマーである高橋氏から見た、日本の高度IT人材事情とは? 

「従来型IT人材」は余る?本当に必要となるIT人材とは?

こんにちは、AtCoderの高橋です。AI産業に注目が集まっていて、各企業が優秀なエンジニアを集めていることは、皆さんご承知の通りでしょう。あらゆる仕事をAIに置き換えていく流れを考えると、AI人材はIT企業だけではなく、あらゆる企業に求められ始めています。日本ではAI人材、高度IT人材が今後数十万人不足するといわれており、人材の育成が急務となっています。

一方で、従来型IT人材は今後余る、という発表も政府から出ており、どういった人材が求められているのか分かりにくい状況となっています。今必要なのは、「AI人材とは何か」「高度IT人材とは何か」を、経営者や人事担当者、またはその周辺の人々が、きちんと考えられるだけの素養を持つことでしょう。

…といったことを本連載では書いていく予定なのですが、しかし今回はその前段として、基本中の基本として「そもそもプログラミングとは何か」を、表面的な理解だけでなく、ある程度深いところまで理解してもらおうと思います。

実はみんなよく分かっていない。プログラミングって何?

世の中のコンピューターは、全てプログラミング言語によって書かれたプログラムにより動いています。ウェブページの検索サイトも、スマートフォンを操作する画面も、全てのソフトウエアが、プログラミングによって動いています。

しかし、プログラミングとは具体的にどういうものか、というのは、知らない人が圧倒的に多い。その状態で、「AI」「アルゴリズム」「ディープラーニング」のような単語を並べても、正しい理解にたどり着くのは難しいです。

まずは、プログラミングとはどのようなものか、簡単にイメージできるようにしましょう。

プログラミング1

これは、C#というプログラミング言語で書かれたプログラムの一部で、「Hello Worldと画面に出してね!」という意味です。この文字列を、コンパイルという作業を通じてプログラムに変換し、実行すると、以下のような画面が出てきます。

画像1

プログラミングとは、このように、コンピューターにやって欲しいことを記述すると、その通りにコンピューターが実行してくれる、というものです。今回は簡単でしたが、複雑なプログラムになればなるほど、記述する量が増えていきます。

cord2

少し複雑なソースコードになりました。ソースコードというのは、プログラミング言語で記述された文章を指します。この記事はプログラミング講座ではないので、プログラミング言語C#の文法や書き方は学ぶ必要はありません。日本語部分だけ読んだ上で、それがプログラムと一対一対応している、ということだけ認識してくれれば問題ありません。

画面2


こちらが実行画面です。Startとまず表示され、その後5回の繰り返しに入ります。現在の繰り返し回数がそれぞれ偶数であるかどうかを判定し、偶数であればEven、そうでなければoddと表示する、というプログラムです。最後にEndと表示されて終わります。ソースコードの注釈で書かれた日本語と、プログラムを実行された際に表示された文章が、一致していることが分かってもらえればよいと思います。

このように、プログラミングというのは、「繰り返し」(今回の場合は5回繰り返した処理)や「条件分岐」(今回の場合は、偶数であるかどうかを判定する処理)を組み合わせて、コンピューターにやってほしいことを、順番に記述していくものです。

今回お見せしたのは画面に文字を表示するだけのプログラムでしたが、実際のプログラミングでは画像を表示したり、クリックできるボタンを表示したり、その表示位置を指定したり、ネットワークにつないだりと、さまざまな処理をするための「関数」と呼ばれるものが用意されています。

それらを組み合わせて、何千行、何万行ものソースコードを書くことによって、皆さんが使っているようなソフトウエアが完成するわけです。

プログラムの肝となる「アルゴリズム」って何?

さて、プログラミングがどういうものかは分かったところですが、ここまでの話だと、「ソースコードは長くなるかもしれないけど、結局やりたいことを順番に書いていくだけじゃないの?」という疑問を抱く人がいるかもしれません。

しかし、同じ目的のプログラムでも、「アルゴリズム」によって、プログラムの速度や正確さが、大幅に変わってしまうところがあるのが、プログラミングの難しい点の一つです。

アルゴリズムとは、日本語にすると「算法」となり、プログラムを実現する具体的手順や根拠のことを指します。…と言われてもイメージが湧かないと思うので、数当てゲームを題材にして、アルゴリズムとは何かを理解していきましょう。

数当てゲームとは、以下のようなものです。

① Aさんが、1から1000までの好きな整数をイメージする
② Bさんは、Aさんのイメージした数を予想する
③ Aさんは、Bさんの予想した数が、正解しているか、大きいか、小さいかを答える
④ 正解するまで②、③を繰り返す。

Aさんは、数をイメージした後に行うことは機械的に決まってしまいます。Aさんの行動をプログラムで書くと、以下のような感じでしょうか?プログラムはどんどん難しくなってくるので、ここでは日本語の部分だけ分かれば問題ありません!

cord2

さて、こんな感じとした時に、「Bさんがどう予想していくか」を考えてみましょう。

最も簡単な方法は、1、2、3…と、小さい方から聞いていくことです。一つずつ予想する数を増やしていくことで、確実に正解にたどり着くことができます。プログラムにするとこんな感じでしょうか? 

cord3

非常にシンプルで、分かりやすいソースコードになりました。しかし、本当にこのプログラムで良いのでしょうか?

もちろん、これはとても悪い方法です。理由は簡単で、最初に「1」と予想するより、「500」と予想した方が、ずっと予想回数を減らすことができるからです。

1と予想して外れた場合、Aさんのイメージした値は「2~1000の間にある」ことになります。1回の予想で減った範囲は、1だけです。

それに対し、500と予想して外れた場合は、「1~499の間にある」か、「501~1000の間にある」かの、どちらかが分かります。500より「大きい」にせよ「小さい」にせよ、減った範囲は501であり、一つの質問で、Aさんのイメージしている可能性のある値の範囲を、半分にできました。

こうして、1回の質問ごとに、範囲を半分にしていくような予想を繰り返すことで、非常に早く的中させることができるようになるわけです。

従来の方法:
イメージ画像1
今回の方法:
イメージ画像2

プログラムにすると以下のような感じになりますが、もうプログラマー以外には、理解しにくい、複雑なものになっているかと思います。理解ができなくても気にする必要はありません。

cord4

さて、この二つのプログラムで、どれだけの差が出るのでしょうか?最初に示した方法では、最悪1000回の予想が必要になりますが、今回の方法では、最悪でも10回の予想だけで、必ず当てることができます。

今回は予想する値の範囲が1~1000なので、たった100倍の差で済んでいますが、これが100万回になれば、5万倍の差となりますし、1兆までなら 250億倍の差です。

長々と説明しましたが、これが「アルゴリズムの違いによって生まれる差」です。

どちらのプログラムも、目的は同じく、Aさんの想像した値を予想する、というものでした。ですが、その過程のアプローチが違うため、プログラムの効率もソースコードの内容も大きく違うものになりました。

まとめると、「目的を達成するために、どのようなアプローチを取るか」という部分がアルゴリズムです。

アルゴリズムと現実の問題は関係ある?

数当てゲームを見て、「これとAIと何が関係あるのだろう?」と思った人は、正直たくさんいるでしょう。講演などでこの話をしても、ただのゲームの話、として捉えてしまう人が多いです。

アルゴリズムというのは、それ自体を知っていたとしても、それを活用するまでに習熟することは非常に難しいのです。

先程の「真ん中から予想していく」というアルゴリズムは、「二分探索」という有名なアルゴリズムなのですが、それを実世界でどのように使っていくか、というのを答えられる人は多くありません。

しかし、こういったアルゴリズムの恩恵を受けているからこそ、僕たちはコンピューターやインターネットを快適に活用できている、というのが実態です。

例えば、以下のような英文があったとします。

“The word algorithm has its roots in Latinizing the name of Muhammad ibn Musa al-Khwarizmi in a first step to algorismus.”

ここから、”name”という文字列が含まれる箇所を探そうと思ったら、どうすればよいでしょうか?

普通に考えたら、頭から順番に、「Theはnameじゃない」「wordはnameじゃない…」と見て行き、nameにたどり着いたタイミングで、「ここにあった!」となるでしょう。

文字列の検索というのは、大体このように、「頭から見ていく」アルゴリズムで作られています。しかし、この文字列が非常に長かったらどうでしょう?長ければ長いほど、検索するのが大変になるのは、想像に難くないかと思います。

さて、ここで、先程の英文が、こんな構造で与えられていたらどうでしょう?

【A】
a[17], al-Khwarizmi[15], algorismus[21], algorithm[3], ibn[13], in[7], in[16], its[5], first[18], has[4], Latinizing[8], Muhammad[12], Musa[14], name[10], of[11], roots[6], step[19], The[1], the[9], to[20], word[2]

これだけ見ても訳が分からないと思うので、もう少し解説します。まず、先程の英文の単語ごとに、「この単語が何文字目か」を書き足してあげます。

【B】
The[1] word[2] algorithm[3] has[4] its[5] roots[6] in[7] Latinizing[8] the[9] name[10] of[11] Muhammad[12] ibn[13] Musa[14] al-Khwarizmi[15] in[16] a[17] first[18] step[19] to[20] algorismus[21]

この後に、各単語を、辞書順(辞書で早く出てくる順)に並び替えてあげると、先ほどの【A】のようになります。

さて、このように、単語を辞書順に並べておくと、何が起こるでしょうか?実は、先ほどの数当てゲームと、全く同じ構造になるのです!

この文章は21個の単語があるので、二分探索のためには中央、つまり11個目の単語に注目します。【A】で11番目にあるのは”Latinizing”で 、これは探したい対象である”name”よりも辞書順(ABC順)で「先」に出てくる単語です。つまり、この文章に”name”が含まれているとしたら、中央よりも「後ろ」、つまり12~21番目の単語しかあり得ない、と言えるわけです。

こうしたアルゴリズムを、単語数を億単位に増やしたシステムこそ、皆さんがいつも使っているGoogle検索のような検索システムです。世の中に散らばっている無数の文章を、あらかじめ整列させておくことにより、全ての文章について調べることなく、高速に検索することができるわけです。

もちろん、Google検索が、このアルゴリズムだけでできているわけではありません。実際に動いているサービスは、これより更に複雑な工夫が大量になされており、ここで語りきれるようなものではありません。ですが、数当てゲームのような考え方が、実際のプログラムにも役に立っている、というのが、イメージできたのではないでしょうか?

こうしたアルゴリズムの考え方は、プログラミング言語などに左右されず、必ず必要となるものです。コードの書き方や、開発手法などは、時代の流れとともにすぐに風化してしまいますが、このような「ロジックを考える」という作業は、時代が変わっても絶対に必要となります。もちろん、数学的な工夫、アルゴリズムの工夫が要求されるかどうかは状況によりますが、さまざまな要素がIT化していく昨今において、必要性はどんどん増していくでしょう。

次回は、AI人材とアルゴリズムの関連性や日本人プログラマーのレベルについてお話しします。