「アニマル、人工無脳」にて、オートマトンに触れました。人工無脳を題材するのは、対象としている年齢や、アンプラグドであることから、難しいかと思います。ですが、オートマトンのアイディアは題材に入れたいと考えています。 エアコンのリモコンでも、TVのリモコンでも、なにか操作をする際には、「まず、このボタンを押して、次にこのボタンを押して……」ということがあります。ここではウェブ・サイトを例にしてみます。 ウェブ・サイトの作りは、細かい話を除くと、次のような木構造と見ることも、場合によっては可能です。ここでは各要素が1つのページだと思ってください: もっとも、この図の横方向へのリンクもありますので、実際には次のようなグラフになります。この図の場合、左端の要素がトップ・ページだとして読んでください: このグラフの場合、真中に並ぶ4つのページの、左から3番目のページには、トップ・ページから直接は行けません。ということは、そこに到達するには、なんらかの条件があり、操作の順番があるということです。 とは言ってもウェブ・サイトという大まかな話だと、わかりにくいかもしれません。そこで、ウェブ・ページになにかを投稿するという場合を考えてみましょう。この場合、まずは投稿ページに入る必要があります。そして、投稿内容を書いたとします。続いて、投稿内容の確認ページがあるとします。この確認ページでは、投稿ページに戻ることも、投稿内容を確定することも可能だとします。投稿内容を確定したら、作業は終りです。これを図として描くと、次のようになります: このように、スマホにしても、エアコンのリモコンにしても、あるいは現在のデジタルTVにしても、ウェブ・ページにしても、その操作はオートマトンとして定義されています。題材としてなにを使うのがいいのかは悩むところですが、身近なものであるという意味では、オートマトンに触れるのも無駄ではないでしょう。 上のオートマトンは簡単なものでしたが、もっと複雑なものでもかまいません: これでもまだまだ簡単な方です。 なお、日本語の文節は、名詞の次には助詞がたぶん来るなど、オートマトンとして描くことが可能であることがわかっています。それを題材にすることもできないことはないかと思いますが、オートマトンに話を持って行くまでとか、日本語のコーパスの用意は必要とか、題材にするにはすこし難しいかもしれません。 このあたりで、プロップのファンクションを持ち出して、「物語生成オートマトン」などというものも題材にできたらとは思いますが、可能かどうかは疑問です。一応、元ネタにできそうな程度に簡略化し、すこしゲームっぽくしたものの手持ちがありますが…… ですが本企画の中で、一回は試してみたい題材でもあります。 興味を持たれましたら、ぜひご支援や、コメントをお願いいたします。 プロジェクトの本文や、活動報告についての感想、ご意見、ご質問を、ぜひコメントでお寄せいただければと思います。現在は支援募集期間中であり、本企画の実施期間ではないため、お寄せいただいた感想などについてはリターンとしてではなく、お返事や回答をさせていただきます。 また、私個人についてはこちらをご覧ください。
迷路の表わしかたには、どういうものがあるでしょうか? 『マイコンとパズルの世界 BASICプログラミング頭の体操』から拝借してですが、このような迷路があったとします: この迷路をコンピュータに解かせるには、どうにかしてこの迷路をコンピュータの中に再現してやる必要があります。どのように再現すればいいでしょうか? 一つには、次のようなかなり直接的な方法があります:######## ## # ## #### #### # # ## # ## # ## # ## ######## 壁を “#” で、通路を “ ” で書いたものです。これは、 “#” と “ ” ではなくてもよくて、数値として “1” と “0” でもかまいません。いずれの場合でも、2次元の配列で迷路を表わしています。この場合、探索して行き止まりだったというような部分には、 “X” とか “2” とか、迷路を描くのに使っていない記号や値を入れてやると、その箇所を再度探索するというような無駄が、直接的に省けます。 では、これ以外の方法はなにかあるでしょうか? 入口、分岐点、行き止まり、出口に、次のように番号を付けたとしましょう:########⑩## ③#⑨⑧ ## #### #### ② #⑦⑥#⑤## # ## # ## # ④ ##①######## この番号を、迷路を再現するように繋げてみると、次のようになります: なんか手抜き風のグラフになりましたが。このようにグラフとして現わすことも可能です。この図では矢印を使っていますが、迷路を行きつ戻りつするだろうことを考えると、矢印ではなくただのリンクにするか、あるいは矢印でもノード間に双方向の矢印として書いてもかまわないでしょう。 元の迷路の図とグラフではまったく見た目が違うと思われるかもしれません。ですが、先に上げた、入口、分岐点、行き止まり、出口に注目すると、同じであることがわかるかと思います。 また、このグラフだと入口から出口までが一直線になっていますが、それは私の手抜きによるものです。グラフで現したとしても、探索が必要なことに変わりはありません。 もっとも「ガジェット・コンピューティング」に挙げたスキャン画像の方に含まれる、紐を使ったものとしてグラフを表現するとします。すると、入口に対応する結びめを持って垂らしてやると、長さはともかく、出口が下のどれかに来ているはずです。ノードを結びめで現わしてやっていれば、入口から出口までにある結びめ、およびそれが対応するノードを読んでやれば、それで入口から出口までの経路もわかります。 あるいは、書き方をすこし変えてやると、いびつではありますが、次のように木構造でもあります: このように、データの表しかたにはいくつか(あるいは、いくつも)方法がありますし、どのデータ構造を採用するかで、問題の解き易さも変わってきます。そのあたりを考えるのも、プログラミングの楽しさであり、難しさでもあるかと思います。 なお、最初に「この迷路をコンピュータに解かせるには、どうにかしてこの迷路をコンピュータの中に再現してやる必要があります」と書きましたが、これはロボットを使う場合でも同じで、探索した経路をロボットに、あるいはロボットが繋がっているコンピュータに記録させてやる必要があります。それをやらないと、同じ行き止まりに何回も行くというようなことが起こりますので。それを避けるためには、ロボットを使う場合でも、やはりどういう形にしろ迷路を再現してやる必要があります。 興味を持たれましたら、ぜひご支援や、コメントをお願いいたします。 プロジェクトの本文や、活動報告についての感想、ご意見、ご質問を、ぜひコメントでお寄せいただければと思います。現在は支援募集期間中であり、本企画の実施期間ではないため、お寄せいただいた感想などについてはリターンとしてではなく、お返事や回答をさせていただきます。 また、私個人についてはこちらをご覧ください。
アニマルという対話ゲームがあります。その概要はこんなかんじです。まずユーザになにか動物を思い受かべてもらいます。また、コンピュータが持っている知識は、このような初期のものから出発します。 最初の「ワンと鳴きますか?」に “Yes” と答えると、「犬ですね?」と訊いてきます。ここでさらに “Yes” と答えれば、アニマルが当てたということで、ゲームは終ります。 また、最初の「ワンと鳴きますか?」に “No” と答えると、「猫ですね?」と訊いてきます。「ワン」と鳴かない動物はたくさんいますので、もしかしたら、ユーザはここでは “No” と答えるかもしれません。アニマルの面白いところはここからです。 ここで、アニマルは、「思い受かべた動物はなんですか?」という質問と、「どのような質問をすればいいですか?」という質問をしてきます。仮に思い受かべたものは「フェレット」であり、「胴長ですか?」という質問をすればいいと答えたします。すると、アニマルは、その知識を、先の木構造に組み込みます。たとえば次のように: このようにアニマルは、失敗すると、新たにユーザから知識を得て、自分が持っている知識を更新しえていきます。この、「フェレット」と、「胴長ですか?」に相当する知識は、元々「猫ですね?」があった位置に「胴長ですか?」を置き、それに対しての回答が “Yes” の場合には「フェレットですね?」を答え、 “No” の場合には、それに対しての答えの部分に「猫ですね?」を持っていきます。 かりに「ワンと鳴きますか?」に “Yes” と答えると、「犬ですね?」と訊いてきます。ですが、「ワン」と鳴く動物はほかにもいそうです。ここでも、「犬ですね?」という問いに “No” と答えた場合、アニマルは同じように新らしい知識を得ます。 アニマルでは、これらの知識の増やし方は、かならずこの形を取ります。 “Yes/No” の二分木であり、一番下の要素は推測する動物になります。ですので、11段の木があれば、11 - 1 = 10段が実質の深さになります。この二分木がキッチリと埋められている場合、2^10 = 1024個の動物を推測できることになります。 アニマルは、質問も答えも定型的であるという制限がありますが、知識を増やしていくという方法は、いわゆる人工無脳にも使えます。もちろん、人工無脳の場合、このような定型的なやりとりには限りませんので、単純な木構造では、その知識を現わせません。 話を簡単にするために、人工無脳において入力の形態素解析や統語解析はしないとしましょう。加えて、単語あるいは文節ごとに分かち書きをするものとします。その上で、ランダムでもなんでもいいので、ある単語や文節が現われたらこのように返事を返すという単純なものとしましょう。 これだけの場合、知識にアニマルのような階層構造は持たないため、二次元の配列、あるいは2要素のレコードの配列で実現できます。 ですが、ある言葉が入力されたら、常に同じ返事をするというのも面白くないでしょう。そうすると、2次元以上の要素を持つ配列ないしレコードの配列、あるいは二次元配列の応えの部分には、すくなくとも1階層の木を持たせることもできるでしょう。木の場合であれば、もしかしたら、どの応えを返すかについては確率もついているかもしれません。 これでもまだ単純すぎるかもしれません。そこで、入力に対して、どの応えを返して、さらにどういう入力が来たら、さらにどの応えを返すか…… というようなことを憶える必要があるかもしれません。 この場合、基本的なデータ構造としては、グラフを構成することになります: 実際には、入力と出力に対応するデータも持つので、オートマトンなどになるでしょう: 人工無脳を本企画の題材にするのは難しいかと思いますが、アニマルなら課題にできるかもしれません。 興味を持たれましたら、ぜひご支援や、コメントをお願いいたします。 プロジェクトの本文や、活動報告についての感想、ご意見、ご質問を、ぜひコメントでお寄せいただければと思います。現在は支援募集期間中であり、本企画の実施期間ではないため、お寄せいただいた感想などについてはリターンとしてではなく、お返事や回答をさせていただきます。 また、私個人についてはこちらをご覧ください。
「データ表現、データ圧縮2」で、大切なことを書き忘れていました。そちらにも、「データ表現、データ圧縮1」にもこういうものがありました: 値 回数 ビット列00 2 111111001 1 1111111080 1 11111111002 5 040 5 1004 5 11020 5 111008 3 1111010 3 1111101F 1 1111111110F8 1 11111111110 これを、回数、つまり頻度順に並べてみます:値 回数 ビット列02 5 040 5 1004 5 11020 5 111008 3 1111010 3 11111000 2 111111001 1 1111111080 1 1111111101F 1 1111111110F8 1 11111111110 この場合、元の8bitに対してのこれらの符号の平均長がどうなるのかを見てみましょう。計算は簡単で、「ビット列の長さ * 回数/32バイト」の総和となります:((1*(5/32)) + (2*(5/32)) + (3*(5/32)) + (4*(5/32)))+ ((5*(3/32)) + (6*(3//32)))+ (7*(2/32))+ ((8*(1/32)) + (9*(1/32)) + (10*(1/32)) + (11*(1/32)))= ((1*0.15625) + (2*0.15625) + (3*0.15625) + (4*0.15625)) + ((5*0.09375) + (6*0.09375)) + (7*0.06250) + ((8*0.03125) + (9*0.03125) + (10*0.03125) + (11*0.03125))= (0.15625 + 0.3125 + 0.46875 + 0.625) + (0.46875 + 0.5625) + (0.4375) + (0.25 + 0.28125 + 0.3125 + 0.34375)= (1.5625) + (1.03125) + (0.4375) + (1.1875)= 4.21875 このように、平均して元の8bitが4.21875bitになっています。元が32バイトですから、4.21875に32をかけると135bit、これを8で割ると16.875バイトとなります。「データ表現、データ圧縮2」では17バイトになっていましたので、いい感じです。 先の、出現回数1回のものはこれらでした:01 1 1111111080 1 1111111101F 1 1111111110F8 1 11111111110 これらは、いずれも8bit以上の長さになっています。そういうものがあっても、出現頻度が少ないなら、かまわないわけです。データ圧縮ができるということは、こんな感じによってです。 絵などをラン・レングスで表わしてみる、あるいはラン・レングスから絵を復元してみるというあたりが、本企画で扱う題材としては適当なものなのかもしれません。ですが、このあたりに関連して、「情報とはなにか」であるとか、「情報量」についての課題も組み込みたいところではあります。リボルバー拳銃でのロシアン・ルーレット (よく使われる例です)、あるいはそれと同じモデルで、条件付き確率として扱えないことはないかもしれません。ただし、あくまで条件付き確率であることを強調しておかないと、後で児童・生徒が混乱することになるかもしれません。そのあたりも含めて、検討が必要だと考えています。 興味を持たれましたら、ぜひご支援や、コメントをお願いいたします。 プロジェクトの本文や、活動報告についての感想、ご意見、ご質問を、ぜひコメントでお寄せいただければと思います。現在は支援募集期間中であり、本企画の実施期間ではないため、お寄せいただいた感想などについてはリターンとしてではなく、お返事や回答をさせていただきます。 また、私個人についてはこちらをご覧ください。
プロジェクトの本文や、活動報告についての感想、ご意見、ご質問を、ぜひコメントでお寄せいただければと思います。現在は支援募集期間中であり、本企画の実施期間ではないため、お寄せいただいた感想などについてはリターンとしてではなく、お返事や回答をさせていただきます。 また、私個人についてはこちらをご覧ください。 前回、『マイコンとパズルの世界 BASICプログラミング頭の体操』〔小谷 善行, 産報出版, 1981.〕を発掘したと書きました。本書には、例えば次のような内容があります (他にもあります):- 論理パズル- 虫食い算- 桂馬道の問題- 迷路パズル- しゃべる機械 これらは本企画で扱う題材にもなるかもしれません。「しゃべる機械」は、人工無脳の話です。これは本企画の題材としては扱い難いかと思いますが、次回にすこし触れたいと思います。 では本題です。 さて、オセロとチェッカー (あるいはドラフツ) ですが、プログラムの作りやすさは、おそらく同程度かと思います。対してゲームとしての難しさは、オセロよりもチェッカー (あるいはドラフツ) の方が難しいのではないかと思います。なお、チェッカーでは双方のプレイヤーが最善をつくした場合、必ず引き分けになることが証明されているそうです (ドラフツはすこしルールが違うので、どうなのかは私は知りませんが)。 ハノイの塔や迷路などのパズルと大きく違うのは、オセロやチェッカーなどは対戦ゲームであるということです。 パズルの場合であれば、手の探索をするとしても、普通の木構造になります: 対して、対戦ゲームの場合、プレイヤーが二人 (場合によってはそれ以上) いるという点が大きな違いになります: これらの図の根 (頂点) が現在の状態や盤面とし、そこから、まず自分の手番だとします。パズルだとそのまま自分の手番が続き、普通の木構造になります。 しかし対戦ゲームの場合、上の図だと赤い箇所ですが、相手の手番がだいたい存在します (ゲームによっては、相手にパスさせる手というのもありますが)。その相手の手番を考慮に入れて、次の自分の手番、あるいはもっと先の自分の手番をどうすればいいのかを計算してやる必要があります。 なお、これらの図の四角で描いてある要素ですが、棋譜のように手を記録するだけでもかまわないと言えばかまわないのですが、盤面を記録しておく方が面倒は少ないかと思います。その分、メモリは必要になりますが。 パズルの場合だと、状態を評価した値を良くしていくことを考えればいいのですが (一旦低くする必要があるという場合もありますが)、対戦ゲームの場合、相手の手はまずまちがいなく自分にとっての状態の評価を下げるように打たれてきます。その上で自分にとっての状態の評価を上げる手を選ばなければなりません。ですので、広い意味でのゲームとしての種類が違うと言えます。 ついでにと言えると思いますが、おおむねパズルよりも対戦ゲームの方が木が大きくなる傾向があります。そうすると、メモリの容量にしても計算にかかる時間にしても、「無駄な手は考慮しない」というような技術が必要になります。今どきなら、オセロではその必要はないかもしれませんし、チェッカーでももしかしたら必要ないかもしれませんが。だとしても、プログラミング教育としては、その技法を取り入れることは無駄ではないでしょう。その技法は、パズルでも、場合によっては必要かもしれません。 興味を持たれましたら、ぜひご支援や、コメントをお願いいたします。