*All archives* |  *Admin*

<<08  2017/09  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30  10>>
floodgate for mahjong へ参戦その11・スタックオーバーフロー撃退
ここのところ集中してAI製作の作業をやってました。
頑張った結果ちょっと前進しました。

やったこと
・スタックオーバーフロー対策で、再帰関数を使わず自前のスタック管理をするためにコード全体を大幅改変。
・他家からのロン和了を考慮するコードをそれに合わせて書く。
・それに対するバグ大量発生のお祭りを収束させる。なんとかそれっぽい数値は出てきた。

テストの風景はこんな感じ。
入力手牌は"2p2p3p3p5p5p6p6p7p8p5s6s6s7s"で(ウザク本Q18より)、
(捨て牌を適当に設定するのがめんどうだったので)親の1巡目。
170515-05.png
他家からのロンを込みでの一人麻雀の再帰計算だと本の解答通り打8pが最も局収支がいいとAIは返してきました。

途中でエラーで途中終了することも和了率800%局収支8万とかいう意味不明な結果を返すこともなく、順当な結果になってくれました。
毎度のことながらバグ取り大変だった…。参照型の配列に対して値を代入することで他のところの数値も変わっちゃうみたいなバグとか。

ただですねぇ、結果が出るまですげー時間がかかるのです。
170515-04.png
最初は45秒とかかかってたのですが、ちょこちょこと涙ぐましい節約の努力をして(ほとんど時間の短縮にならなかった改良も多かったですが、)34秒まで短縮しました。
30秒とか40秒って…。打牌候補が多くて複雑な牌姿とはいえ、一打で何十秒も食ってたら試合にならんですぞ。

パーツごとにばらして計算時間を測定すると、ボトルネックになってるところが複数個所にばらけてるので、一筋縄ではいかなさそうです。

処理時間が長いところから順番に、

・5…和了処理
この部分だけstring型を使用しているので一番遅くなっています。
手牌のうち副露部分と和了牌の情報を加えた文字列で、和了点数の記憶情報にアクセスしてる分です。
和了牌はともかく、副露部分についてもうまいこと(できればビット演算で)長整数型とかに変換して、
副露以外手牌のLong型と副露部分のLong型の組を構造体(orクラス)で宣言して…とか。
うまい変換関数を作る必要があります。

・12…他家から出る率計算
立直者情報とか見えてる切れてる枚数とかカベ効果等などが複数の関数を組み込んでいるので、ここが時間を食ってしまうのはしょうがない…、と諦めてしまっては他のところでいくら節約しようとどうしようもないので頑張らないといけないです。
ここに限らず、Integer型配列でごまかしてるところが多いので、これもうまいことビット演算で長整数型にして、関数を一から作り直しにするとか。
とりあえず広範囲の見直しでしんどいことだけはわかった。

・16…分岐後諸計算
各打牌候補について手牌を1枚減らして、捨て牌に1枚加えて、みたいな変数(だいたいInteger型配列)への代入とか複製とかでなんかよくわからんけどつもりつもって4秒とか食っていやがる。
おそらく、再帰を使わない→参照型のInteger型配列を直接操作する→連動することがないように複製(clone)を逐一用意する、のところで時間を食ってると思われる。
cloneにしたせいで時間がかかるっぽいし、かといって同じ処理をループで回すのももっと時間がかかって論外だし、直代入だと連動バグが発生するし。
この件もあるからあらゆるInteger型配列をLong型変換しないといけないとか。
参照型、嫌い。もはやトラウマです。
7と11も同じく。

・10…先頭ハッシュ関数計算
巡目とリーチ等状態と残り手替わり回数から加算乗算でハッシュ値を計算しているパート。
整数型の乗算ならいけるだろうとたかをくくっていたら、呼び出される回数が多いせいか、けっこう時間を食ってる。
これもビット演算に置き換えるか…。

一難去ってまた一難ですなぁ。
スポンサーサイト

コメントの投稿

Secret
(非公開コメント受付中)

コメント

プロフィール

nisi5028

Author:nisi5028
FC2ブログへようこそ!

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
FC2カウンター
フリーエリア
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード