負数の剰余

shunirr.hatenablog.jp

 

随分久しぶりに地雷を踏んだ。

CおよびC++では

-5 % 3 = -2

 5 % -3 = 2

RubyおよびPythonでは

-5 % 3 = 1

 5 % -3 = -1

 

そもそも商が違うのだ。

CおよびC++では

-5 / 3 = -1

 5 / -3 = -1

Pythonでは

-5 // 3 = -2

 5 // -3 = -2

つまり,商を0側に丸めるかマイナス側に丸めるかの違い。

  

複数言語またいでテストコード書くと色々分かる。

 

温故知新(2)

学生さんの卒論もあった色々と過去の調べ物をしている。

手に入る情報だけで追っかけて調査しているので,当時詳しい方には是非間違っている点があったら是非指摘していただきたい。

 

floodgateの長手数の将棋に関して

2011年,2012年辺りは稲庭将棋による長手数将棋が多数。

2016年には前年比で256手引き分け局が激増しているが,これは600-10Fというフィッシャークロックルールへの変更が原因と思われる。

同年末には300-10Fへと変更したため翌年以降は引き分け局はやや減少。

他に可能性としては技巧の公開など。

 

floodgateの入玉宣言勝ちに関して

2013年は前後年に比べて相当に入玉宣言局が多い。これらの大半はBlunderによる。

恐らく下山さんが時代を先どって相当対策を施したと思われる。

2017年より劇的に入玉宣言局が増えている。これはelmoの公開およびelmo絞りの公開による類似評価関数の作成によるものと思われる。

但し,対局数の0.4%に満たない程度。

 

稲庭将棋について

公開されているソースをベースに探索深さ制限などを相当緩和してリビルドしてみた。

ソースはれっさ改に追加で千行程度。上記私の自作ソフトよりやや多いw

定跡・定型駒組などのパターンマッチングのデータではなく,条件分岐コードで実装されている。

対局はオリジナルより終盤しつこくなる。

現行の強豪ソフトは敵陣突破の前にmate17や19を出して楽勝。シングルスレッドでも問題ない。

手持ちの自作ソフトはやや勝ち越すくらい。(ただしHefeweizen評価関数)

評価関数が駒得のみであるやねうら王マテリアルでは大半引き分けるが,偶然敵陣を突破可能な布陣が形成されると圧勝。

駒得だけで稲庭に勝つのは相当高難易度のようだ。

逆に飛角銀桂を適当に配置できれば突破前にmateを入れることができることが分かった。

温故知新

 ふと,一昨年はじめたコンピュータ将棋にどっぷりです。

まぁ,学生の卒論ネタもあって関連書籍を可能な限り集めてみたついでに,私も歴史を学んでみることにしました。

比較的古いのから紹介します。

 

コンピュータ将棋―あなたも挑戦してみませんか (Information & Computing)

コンピュータ将棋―あなたも挑戦してみませんか (Information & Computing)

 

  

33ページには枝狩りなしでは深さ4が限界,82ページには簡単な攻めを読むにも深さ5程度は必要だが膨大な数で全幅探索はできないとあります。PC9801のMS-DOS環境です。

 

書籍の発行年次が1990年ですが,2019年のPCでは私が戯れに作った探索部で100knpsでるので枝狩り無くても秒のオーダーで探索可能となります。恐ろしいですね。

ちなみにこれくらいの探索部にSEE(静的駒交換評価)を加えると,あの稲庭将棋を葬れます。(稲庭将棋の悪夢については最近知りました。)

 

www.vector.co.jp

 

さらに,この書籍124ページには将棋とニューラルネットは相性が良いはずだとか,プロ級の強さになるには20年とかそういった結構勘のいいコメントも記されております。

当時からアイデアマンが揃ったジャンルだったのですね。

今年の選手権の話でも

第29回世界コンピュータ将棋選手権にエントリーしました。

恥ずかしながら昨年王者第一シードで御座います。

 

www.apply.computer-shogi.org

 

一昨年が電王トーナメント準優勝。

昨年が世界選手権優勝。

どちらも初参加ですが,相当雰囲気が違います。

電王トーナメントのときはそれこそ出張ついでで目立たないように逃げてたのですが,昨年の選手権ではチーム体制で一応そこそこ勝つことを目標にして参加しました。

まぁ,個人は気楽ですが色々と機材管理から飲食物調達など大変なのでサポート要員は居る方が楽ですね。荷物は電王トーナメントのトロフィーとかその他出張の邪魔なので翌日には宅配便で自宅に送ったくらいです。選手権の時は両手に紙袋とかわんさと下げて新幹線に乗りました。電王トーナメント唯一の切れ負けはインタビューの最中でしたし,予備のUSBメモリは自宅玄関で待機してましたし,耳栓はスタッフの方に買いに行って頂きました。そういうことでチーム体制が色々安心安全です。ただ,チーム体制にすればそれなりにチームの方向性を決めておく必要があるので,昨年の目標は予選通過ってお題目で意志統一してました。作業分野的に丁度手分けできたのは特に計算してやったことじゃないです。意外かもしれませんがw

 

で,今年はどうよってことですわ。

酒の肴的には「連覇」なんですが,そんなことは少ししか思ってません。

一応電王トーナメントのときにできなかった焼肉打上をあわよくば実現したいと思ってます。とはいえ優勝した翌年予選落ちのelmoの例がありますので気を引き締めて準備しときたいですね。ちなみに実は未だelmoとの対局がありません。今年こそお手合わせ願いたいです。

まぁ,なんやかんや考えてもルール的にも一次予選免除くらいの利点しかないので普通の参加者として昨年同様に参ります。(前日入りの必要がないので会場設営にはいくかどうかは未定)

 

具体的な準備としてはネタ的に考えていたのを順番に実装してテストしてる最中ですが,今のところノーヒットです。特に探索部の改造の是非は非常に難しいです。唯一PythonをGo言語に書き換えた部分は確実に高速化してるくらいでしょうか。複雑な制御を追加しても遅延等問題なさそうです。他当たりそうなアイデアはあるのですが実装力が追い付かない感じで情けない限りです。個人的な得意分野としてマルチコア・クラスタなどは上手に使っていきたいと思います。

 

気になるのは他チームの動向です。個人的に気にしているのが昨年のうちの戦略を他チームがどれくらい取り込んでくるかってことです。コム将の間では真似されるのが誇りでありますので色々と真似していただければ幸いです。ただ,MultiPonder同士が当たるとどんなことになるのか手元でもリソース不足で実験できていません。

それにディープラーニング勢ですね。最右翼はもちろんdlshogiの山岡さんですが,フランスのRemiさんがガチ宣言入ってますし,保木先生が何故か新人扱いでディープラーニング勢の闘気が漂うトリオで参戦されています。池さんも何故か新人枠ですw

忘れていけないのが,やね師匠ですね。新人賞候補とか卑怯な感じしかしません。Yorkieの石田さんもエントリーされてますのでお会いできるのが楽しみです。大将軍には唯一負け越してますので今年中に五分に戻したいです。平岡さんも開発言語にRustしか書いてないのでお会いした時には是非話を聞きたいと思ってます。う~む,個別に書き出すときりがないですねwww

 

夕飯の準備もあるので今日はこの辺で 

シングルスレッド性能が速いのが欲しいときがある

Pythonで色々処理してると多コアが全く役に立たないことが多い。

自前で用意したシミュレーション系ツールも並列化してないと同様。

つまりシングルスレッド性能でしか生かされない。

 

そういうこともあろうかと,Skylake世代でKプロセッサを仕入れてたんだけど,これがシングルスレッド時のターボブーストで4.2GHz。

近頃は9900Kとか8086Kとかが5GHzで動くらしい。

 

ふと手持ちのモバイル機器を確認してみたら8550Uが4GHzで8750Hが4.1GHzだそうな。

嗚呼,シングルスレッド性能がモバイルに追いつかれてしまった。

 

コム将で例えると山岡さんのpython-dlshogiが結構pythonに足を引っ張られてて,GPUは1050クラスでも1080クラスでもさほど影響ないが,シングルスレッド性能に結構依存しててクロック比に近いnpsが出る。

つまり,ウチではDELLのG3が8750Hの4.1GHzで最強。

 

5GHzのやつが急に一個欲しくなったって話。

合法手の話

その昔,"指し手生成祭"という祭があったようです。(詳しくはググってください。)

将棋の局面で反則にならない手が何種類あるかってのをリストにする速度を競ってたそうです。私は先日Go言語で組んだのだとざっくり200kくらいが最高値でした。たぶん一桁負けてますね。

これが何に有効かというと速度の問題ももちろんですが,探索の枝の生成になります。コンピュータ将棋の本質は木探索なので枝の数とかその性質とかが重要ですね。

 

  

枝の数が気になるってことで,python-shogiでざっと棋譜読んで数えさせてみました。

こういうときはカジュアルなライブラリが便利です。

 

bleu48.hatenablog.com

 

まぁ,こんな感じで簡単に数えられますね。

kifフォルダ以下のkifファイルを全部読んで全局面の合法手生成をしますのでちょっと時間かかります。

 

import shogi.KIF
import os

def find_all_files(directory):
for root, dirs, files in os.walk(directory):
  for file in files:
    yield os.path.join(root, file)
num_board=0
sum_moves=0
for filepath in find_all_files("kif"):
  kif = shogi.KIF.Parser.parse_file(filepath)[0]
  board = shogi.Board()
  for move in kif['moves']:
    board.push_usi(move)
    moves=[]
    for m in board.legal_moves:
      moves.append(m)
    sum_moves += len(moves)
    num_board += 1
print("局面数",num_board,"総合法手数",sum_moves,"局面当たりの平均合法手数",sum_moves/num_board)

  

沢山やると遅いので,うちの選手権棋譜24局だけですが

局面数 3920 総合法手数 387904 局面当たりの平均合法手数 98.95510204081633

ってことで,割と手が広いようです。 

皆さんも手持ちの棋譜で調べてみてください。