helloworlds

not a noun, it's a verb

#2 【アルゴリズム】頭の体操! 0やロジカルシンキングについて再入門

#2 のテーマは、頭の体操です笑

と、いっても数学の領域全体ですと、扱いきれないほど覚えることがあるので、

ここでは、エンジニアとして重要な考え方などを取り扱っていきます。

実用的な数学を解説するというよりか、考え方寄りのお話になってくると思います。

実践的な数学は、各アルゴリズムをみていくときに一緒に解説できたらと思っています。

なので、それまでに頭を柔らかくするためのものか〜くらいに思って頂けると嬉しいです!

※数学得意!って方向けではありませんのでご了承のほど。 

参考にするのは、こちらの本。

プログラマの数学第2版

また、このブログのシリーズの目次は以下。

o21o21.hatenablog.jp

前提

この記事でいう数学の体操とは、

プログラマ、エンジニアには数学が必要か?」とか

加減乗除は前提で、線形代数微分積分などが必要」とか

そういったことではありません。

どちらかというと、こういう見方で数字をみてみよう!みたいなノリです。

説明に不足してしまう部分もありますが、ご了承のほどよろしくお願い致します!

ロジカルシンキング

嫌というほど見聞きするであろう、ロジカルシンキング(論理的思考/論理思考)

「筋道が立っている、筋が通っている考え方」

主にこういうふうに理解されているはずです。

わたしは、小さい頃から「なんで?なんで?」と両親に言い過ぎて叱られた記憶しかないですw

疑問を持って、ある問題から分岐した問題をさらに深堀りしていき、道筋を追い、適切な根拠付けを行うことは重要です。

また、数学的/エンジニア的な側面でどのように活かすのか考えてみます。

MECE

数学の問題(数学でなくともなにかの問題でも可)、出題された問題では、まず問題を理解することが重要です。

すなわち、述べられている事実を正確に読み解くことが重要だと思います。

問題を考えているうちに、余計なことを考えてしまうと、解決に至るまでの時間が長くなってしまったりします。

なので、正確に問題を表現する手法として、MECE(Mutually Exclusive and Collectively Exhaustive)という考え方が存在します。(ミースと読むらしい)

難しい単語が出てきましが、まったく難しくありません。むしろ日頃からやっているかもしれません。

要は、"重複なく・漏れなく" という意味です。

言葉だとイメージがわかないので、コードで例をみてみます。

age = 20

if age >= 20:
    print('OK, U can drink!!')
else:
    print('Sorry, U can not drink...')

これを実行すると、"OK, U can drink!!'"と出力されます。

なんてことないですね!20歳以上になれば、お酒飲めますよーって単純なことです。

こんな単純な例ですが、ここで考えたいのでは、重複漏れになります。

人間の年齢というのは、19歳と20歳同時になっている瞬間というのはありません(= 1人の人間は年齢の重複はない)。

これは年齢単位でグルーピングしていることになります。

しかし、この例は日本に限る話であり、世界の国々では飲酒できる年齢は様々です。

例えば、アメリカでは飲酒できる年齢は、州ごとに違います。また、ブラジルでは18歳からの飲酒がOKです。

一旦、表にしてみます。

country 飲酒できる年齢
日本 20歳以上
アメリ 州によって異なる
ブラジル 18歳以上

2つ国が増えたことで、先程のコードは適用できなくなりますね。

集合を使う?

例えば、先程のコードで、修正するとしたらifand 条件をたす方法もあるかもしれませんね。

こんなかんじに。

if age >= 20 and country == 'Japan': 

あるときはこれでいいかもしれません。

でも、あるときはこれではバグを生む原因になりかねません。

ここで推したいのは、何回もいいますが、重複と漏れです。

例えば仕様の変更で、扱う国が増えたら大幅なコードの修正になるかもしれません。

また、条件が足された場合も、考慮する点が増えてきます。

なので、まず落ち着いて関係性を表現してみます。

どういう風に表現するかというと、集合(ベン図)です。

学生のときに散々みた、これです。(この図は、例を表してはいません。)

f:id:o21o21:20190918165929p:plain:w400

ちょっと手間かもしれませんが、このベン図を利用して考え方を固めていきます。

ちょっと例を参考に問題っぽいのを。

とあるエンジニア100人に飲酒・喫煙アンケートをとりました。
日本人のエンジニアで喫煙は10人、飲酒は20人。
アメリカ人のエンジニアで喫煙は7人、飲酒は30人。
また、両方と答えたのは、日本人は4人、アメリカ人は2人。
両方しないのは、何人でしょうか?

色々と数字が出てきましが、ベン図にしてみればシンプルに。

ちょっとみにくいですが、、

f:id:o21o21:20190918174322p:plain:w400

ここで以下のような式がたてられますね!

日本人: (10 + 20) - 4

アメリカ人: (7 + 30) - 2

26 + 35 + x = 100
26 + 35 -100  = x
61 = x
x = 61

一気に集合の話になってしましましたが、

個々の関係を(排他的(Exclusive)に)確認するということが大事です。

進法

ちょっとテーマを変えます。

コンピュータでは、基本的に2進数が使われています。

2進数は、01で表現されています。

人間が主に使用しているのは、10進数ですね。

進数(進法)について詳しく知りたい方は、以下の過去記事にて参考にしてみてください!

o21o21.hatenablog.jp

どうして進数について記述するのかというと、0(ゼロ)の認識について簡単に説明したいからです。

0とは?

私自身、改めて0に対しての気づきがありましたので、是非ここでその気付きを記述したいと思います。

※ この本(プログラマの数学第2版)を参考にしています。

エンジニアとして0は特に馴染みのある数字だと思います。

0からはじまるのが当たり前ですよね。

また、日常的に0は何もないことを表現するのに使いますね。

間違ってはいませんし、これからもそうだと思います。

ですが、少し見方を変えてみようと思います。

102

これは10の2乗ですね。(累乗an)

102 = 100 ですね。

では、これはどうでしょう?

100

101は、10です。

指数が0の場合は?

学校で累乗を習う場合、10をn回掛けたのが答えという風に考えるかもしれません。

間違ってはいませんが、指数が0や-1となった場合、少々シンプルに物事が考えられないかもしれません。

先に答えを。

100 = 1 となります。

どういう風に考えるかというと、

1/10(10分の1)ずつ増減する」ということです。

指数が-1でも、10-1 = 1/10と即答えを見つけ出すことが可能です。

場所を確保する

さて、0の話をしているのに累乗や進法の話になりました。

意味のない話ではありません。

10進数で、1051という数字があったとします。

百の位は0です。百に位はないと表現していますが、実はこれ

「千の位が落ちてこないように支えている」という認識にしてみましょう。

0が"ない"という意味であれば、1051ではなく、151と表してもいいことになってしまいます。

つまり、「0は、場所を確保している」という見方をしてみてください。

もう少しイメージをエンジニアらしく掘り下げていきます。

(例えが下手で申し訳ないです、、、笑)

お酒を飲むのが大好きな人がいたとします。

でも、毎日飲んでいては健康に悪いので、5日に1回は休肝日を設けるようにお医者さんに言われてしまいました。

5日に1回のサイクルを繰り返しているのは、お酒好きには大変です。

なので、奥さんがノンアルビールを用意したのです。

これで、5日1回を気にせず、毎日飲むというシンプルなルールになりました。

(ノンアルビールはビールと違う!というのはさておきw)

つまりは、パターンのシンプル化を行えるということに着目して下さい!笑

0は、ノンアルビール同様、あるパターンをシンプル化する要素を持ち合わせているんだって頭の片隅に覚えておけばいいでしょう。

まとめ

簡単にはなってしまいますが、少し頭の体操になれば幸いです。

まだ、定性的なお話が多いですが、次回は #1 であげたアルゴリズムの中から1つだけ例にとってコード化してみたいと思います。

わたし自身もまだまだ勉強不足、、勉強しながらということで、シリーズに前後あるかもしれませんが、ご了承願いますm( )m

以上

o21o21.hatenablog.jp

前回の記事

o21o21.hatenablog.jp