TIM Labs

問題

前回はオセロの対戦AIを原始モンテカルロ法で作成しました。実際に対戦してみると「角は優先して取るべき」等といったオセロのノウハウを全く知らない乱択ベースとは思えないそれなりの強さでした。

試行回数が200回/手とはいえそれなりの強さだったのですから、試行回数を増やせばもっと強くなるはずです。 しかし単純に試行回数を400回/手、800回/手......等と増やしていくと問題が出てきます。

  • 序盤や終盤は着手可能な場所が限られているものの、中盤になると数が膨大になります。試行回数をn回/手にしてるとAIの思考(試行)完了待ち時間が長くなってストレスフルです。
  • 試行方法を「全体でN回試行する」「各手についてNを等分して試行する」ことにすれば中盤のストレスは減りますが、これは中盤の各手の試行回数を減らしている為、中盤の手筋は質が下がって弱くなります。

そもそも、 着手可能な手を平等に試行する必要はあるのでしょうか? ある程度試行すれば各手の大雑把な勝率が得られますから、 勝率(大雑把)が悪そうな手について試行するよりも 勝率(大雑把)が良さそうな手について試行回数を重点的に割り振った方が効率が良いですよね。

しかし、これは少々の試行回数で割り出した勝率(大雑把)なので、 勝率(真)とはかけ離れている可能性はあります。 勝率(大雑把)が悪いからといって早々に切り捨ててしまうと、それが本当に良い手だった時に困ります。

つまり、

  • 勝率の良さそうな手を重点的に試行する
  • 実はもっと勝率の良さそうな手があるかも知れないので他の手も調べる

という2点を上手いことバランスを取って試行を行えば、 原始モンテカルロ法よりも少ない試行回数で効率良く精度の高い勝率を叩き出せそうですね。 でもこの2点、どう考えても矛盾してます。どうやって最適なバランスを取ればいいのでしょう?

早速だが、コードを見てほしい。ネットワークデータを一旦ローカルの一時ファイルに受け取り、後でゆっくり読み書きしよう、という意図のコードだ。呼び出し元はファイルハンドルを受けとり、シークを含めた読み書きができる、というか、したい。

def create_tempfile(*)
  network_source = ... # 省略
  Tempfile.new("example").binmode.tap do |file|
    IO.copy_stream(network_source, file)
    file.rewind
  end
end

ところが、このコードには問題がある。普段何も問題なく動くのに、時折このメソッドから受け取るファイルに対して操作をしようとしたら IOError が発生することがある。しかもこのエラーは環境や時間、扱うデータによって発生したりしなかったりするし、スタックトレースはなにやら所謂ライブラリ類の奥深く。そもそも問題の原因がここであることを突き止めるにも一苦労があったわけだが、えーっと、現場の苦労話はさておきだ、とにかく「問題の原因はこのコード」、「発生している例外が持つメッセージは "closed stream"」である。

どう直せば解決するか、分かっただろうか?

問題

以前、オセロの対戦AIの作成しましたが、そこでは実装を簡略化する為に盤面の価値を

  • 盤面の価値 = 自分の石の数 - 相手の石の数

という単純な方法で決めていました。 でも、これには問題があります。

  • 同じ石でも配置場所によって価値は異なるはずです(例: 角は最強)。それが考慮されていません。
  • ゲーム終盤になってくると石の数が重要になってきます。でも序盤から石の数を重視するのは方向性としておかしいです。

という訳で、

  • 序盤から中盤では石の配置場所を重視する
  • 終盤では石の数を重視する

形で盤面の価値を算出すれば、結構良さそうなAIになりそうです。

しかし、今度は

  • 「序盤」「中盤」「終盤」をどのように区別するのか?
  • 石の配置場所の強弱はどう決めるのか?
  • 同じ配置場所でも周囲の状況次第で強弱が異なるのでは?

という問題が出てきます。これは作るのが面倒臭そうです。

どうにかしてお手軽かつそこそこ強そうなAIを作れないものでしょうか?

今回のあらすじ

SICP3.5 Streams を最初からバリバリ読んで、 Exercise 3.52 まで解くことにしましょう。

試行錯誤してる図

問題

git rebase は便利ですが、時々コンフリクトが起きて停止します:

$ git rebase master
Applying: Add GeneratedColumn
Applying: Add EnumerateGeneratedColumns
Applying: Use EnumerateGeneratedColumns to CreateQuery
Using index info to reconstruct a base tree...
M       AAA/BBB/Summary.cs
Falling back to patching base and 3-way merge...
Auto-merging AAA/BBB/Summary.cs
CONFLICT (content): Merge conflict in AAA/BBB/Summary.cs
Failed to merge in the changes.
Patch failed at 0037 Use EnumerateGeneratedColumns to CreateQuery
The copy of the patch that failed is found in:
   c:/Users/VimWizard/projects/SecretProject/.git/rebase-apply/patch

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".

まず何が影響してるか、 git statusgit diff で確認しますよね。 あれこれ端末内で情報を表示して状況を確認した結果、コンフリクトの解決に取り掛かる訳ですが、 解決するには元々 何のコミットをapplyしようとしてコンフリクトしたのか という情報も重要です。 この情報自体は上記の git rebase からのメッセージに含まれています。 が、しかし、

  • git statusgit diff を何回も実行しているので git rebase のメッセージは流れています。 あのメッセージがどこにあったのかスクロールして探すのは面倒です。
  • 仮に端末内の出力を検索したとしても、 git rebase はコンフリクトしたコミットのコミットメッセージは表示してくれているものの、 コミットIDは表示してくれないので、結局問題のコミットにおける変更点だけを見るには不向きです。

どうにかして一発でapplyし損ねたコミットを表示できないものでしょうか。

今回のあらすじ

SICP3.4.2 Mechanisms for Controlling ConcurrencyDeadlock からラストの Concurrency, time, and communication までバリバリ読んで、残った問題をバッサバッサと解きまくります。

Let over Lambdaの図

Moodle でプラグインやテーマをインストールするには、zip で固めたモジュールを scp などでアップロードするなどの昔ながらの方法 (?) も使えますが、Web の GUI を経由してインストールすることもできます。最近の WordPress みたいなもの−−とかいってもよいのでしょうか。

moodleaddoninstall1.jpg

操作としては、管理権限のあるアカウントで、上の図のように、「サイト管理」>「プラグイン」>「アドオンをインストールする」をメニューから選びます。

少し前の話になるのですが、MariaDB Galera Cluster を、Azure 仮想マシンの Ubuntu 14.04 にインストールしてみたときの手順を備忘録として。完全同期型でどのサーバーもマスターになるというのに心惹かれて導入してみました。

結論からいえば、参考にした「Installing MariaDB Galera Cluster on Debian/Ubuntu」のページに記載されている手順を、そのままコピペでいけたのですけれど、あちらは Ubuntu 12.04 使用だし、日本語のテキストも少し需要があるかもしれないということで、このブログにアップしてみます。

まず、Azure 上に Ubuntu 14.04 の仮想マシンを 2 台、仮想ネットワーク (今回の例では 172.16.  のアドレス設定) 内に新規作成します。以下、1 台目の内部アドレスは 172.16.0.4 で、2 台目は 172.16.0.5 です。作成時点では SSH のポート以外は開けていません。

また、Web サーバーになる予定の仮想マシンも Ubuntu 14.04 で作成しておきます。これのアドレスは 172.16.0.6 です。


問題

以前、 JavaScript でオセロを実装 していたのですが、 この実装には一つ大きな問題がありました。

AI相手にゲームをするのは、それはそれで楽しいものの、 やはりこの手のゲームは人間同士で対戦したくなるものです。 一応、あの実装は人間同士で対戦できると言えばできるのですが、 同じPCの前に座って交代しながら操作する形になので、色々と不便です。

インターネット全盛のこの時代、やはりネット対戦できるようにしたいですよね。 しかしプレイヤー間の通信やプレイ中のゲームの状態の共有は一体どうすれば良いのやら。 オセロのようなターン制の単純なゲームでさえネット対戦対応するには課題が山盛りです。

どうにかして簡単にサクサクっとネット対戦できるようにできないものでしょうか。

今回のあらすじ

SICP3.4.2 Mechanisms for Controlling ConcurrencyImplementing serializers をバリバリ読んで Exercise 3.47 まで解きます。

正常に動かないサンプル実装を眺める図

最近のコメント