Open harukaki opened 1 year ago
We follow the observation design of [Lockhart+20] , OpenSpiel.
more details #889 |
Index | Description |
---|---|---|
obs[0, 4] |
Vulnerability | |
obs[4, 8] |
Per player, did this player pass before the opening bid? | |
obs[8, 20] |
Per player played bid, double, redouble against 1♧ | |
... | ... | |
obs[416, 428] |
Per player played bid, double, redouble against 7NT | |
obs[428, 480] |
13-hot vector indicating the cards we hold |
それぞれのaction {0, ..., 37} が{ Pass, Double, Redouble, 1♧, 1♢, 1♡, 1♤, 1NT, ..., 7♧, 7♢, 7♡, 7♤, 7NT} を表す |
Index | Description |
---|---|---|
0 |
Pass |
|
1 |
Double |
|
2 |
Redouble |
|
3, ..., 7 |
1♧, 1♢, 1♡, 1♤, 1NT |
|
... | ... | |
33, ..., 37 |
7♧, 7♢, 7♡, 7♤, 7NT |
Bridge AIの先行研究[Rong+19], [Gong+19], [Tian+20], [Lockhart+20]
にならい、BridgeBidding
はContract BridgeのBiddingフェーズのみに着目した環境である。そのためdds (Double Dummy Solver)
の結果を使用することで、BridgeのPlaying部分を近似している。これを実現するにあたり、本環境では[Tian+20]
にならい、生成したhandの配り方に対して事前にdds
の結果を計算したdatasetを読み込む実装となっている。
handの配り方とdds
の結果を組みにしたdatasetをhash tableとして保存し、使用する。
デフォルトの設定では、カレントディレクトリ内のdds_hash_table.npy
にhash tableを配置する必要がある。
import pgx
env = pgx.make("bridge_bidding) # You need to place the hash table in `dds_hash_table.npy`.
また、BridgeBidding
を直接呼び出すことで自由にhash tableのpathを指定できる
from pgx.bridge_bidding import BridgeBidding
env = BridgeBidding("path") # You can place a hash table on any path
また、hash tableの詳細は以下である。
hash tableはnpyファイルで保存されたものであり、hash_keys
とhash_values
のTupleになっている。hash_keys
がhandの配り方を、hash_values
がそれに対するddsの結果を格納したものである。hash_keys
、hash_values
の各要素key
とvalue
はそれぞれ4次元のjnp.int32
配列で表現されている。
そのため、handとddsの結果の組み合わせの個数をN
とするとhash_keys = (N, 4)
、hash_values = (N, 4)
のjnp.int32
の配列となる。
key
は各Suit{♤, ♡, ♢, ♧}
において各Cardが{N, E, S, W}
のどのPositionに配られたかを表した整数列を13桁の4進数とみなし、各Suitにおいて10進数変換した4つの整数を持つ配列である。
value
は各Position{N, E, S, W}
において、dds
で計算した各Denomination {♧, ♢, ♡, ♤, NT}
でとれるTrick数(0以上13以下)の整数列を5桁の16進数と見なし、各Positionにおいて10進数変換した4つの整数を持つ配列である。
hash tableの例がpgx/tests/asset
内のcontractbridge-ddstable-sample100.csv
とdds_hash_table.npy
にある。
contractbridge-ddstable-sample100.csv
100個のhandの配り方とddsの結果の組み合わせが保存。ファイルの内容は以下の表である。 |
Index | Description | Format |
---|---|---|---|
0 |
handの配り方 | PBN format |
|
1, ..., 20 |
dds results | N (♧, ♢, ♡, ♤, NT) E (♧, ♢, ♡, ♤, NT) S(♧, ♢, ♡, ♤, NT) W (♧, ♢, ♡, ♤, NT) |
dds_hash_table.npy
上記のdatasetから作成したhash table
例えば、contractbridge-ddstable-sample100.csv 、dds_hash_table.npy の先頭データは以下となる。 |
Description | Content |
---|---|---|
csv data | N:J92.J76.K72.9432 AKQ6.84.J863.T65 87543.KQ9532..K7 T.AT.AQT954.AQJ8,1,1,6,4,1,11,12,6,8,9,1,1,7,5,1,10,12,6,8,9 |
|
hash key | [19556549 61212362 52381660 50424958] |
|
hash value | [ 71233 771721 71505 706185] |
また、BridgeBidding.init
では指定したhash tableからランダムに一つのデータが使用される。
https://github.com/sotetsuk/pgx/blob/b7009f9ea9a9c1cd9257073b53bb59f9b71b77a1/pgx/bridge_bidding.py#L111-L113
我々が用意したdds resultsのdatasetならびにhash tableをGoogle Driveで公開している。以下のurlからダウンロードできる。 https://drive.google.com/file/d/1eQAsgJVyiTSSOK78L51UL09YI6Z2jI-3/view?usp=share_link dds_results.zip (202 MB) の内容は以下。 | File Name | Description | Size |
---|---|---|---|
bridge_bidding_dds_results_2500000.csv |
Dataset of 3,000,000 combined hand and dds results | 337 MB | |
dds_hash_table_2000000.npy |
Hash table with the first 2,500,000 of the above data set for training | 80 MB | |
dds_hash_table_500000.npy |
Hash table with the last 500,000 of the above data set for evaluation | 16 MB |
ダウンロードしたnpyファイルはBridgeBidding
クラスにそのまま読み込ませることができる。
ランダムに各Position (NESW)に対するhandの配り方を生成し、それに対するddsの結果を計算する。ddsの計算には以下を使用することができる
handの配り方からkey
を作成する
handの配り方から各Cardが{N, E, S, W} のどのPositionに配られたかを表す52次元の配列を作成する。 |
Name | Symbol | Int |
---|---|---|---|
Card | {♤A, ♤2, ..., ♤J, ♤Q, ♤K, ♡A, ..., ♡K, ♢A, ..., ♢K, ♧A, ..., ♧K} |
{0, ..., 52} |
|
Position | {N, E, S, W} |
{0, 1, 2, 3} |
np.int32
配列に保存する。Example
Phase | Content |
---|---|
hand | N:J92.J76.K72.9432 AKQ6.84.J863.T65 87543.KQ9532..K7 T.AT.AQT954.AQJ8 |
i | [1 0 2 2 2 1 2 2 0 3 0 1 1 3 2 2 1 2 0 0 1 2 3 0 2 2 3 0 1 3 3 1 0 1 3 3 1 3 0 3 0 0 0 1 1 2 3 0 1 3 3 2] |
ii | [[1 0 2 2 2 1 2 2 0 3 0 1 1] [3 2 2 1 2 0 0 1 2 3 0 2 2] [3 0 1 3 3 1 0 1 3 3 1 3 0] [3 0 0 0 1 1 2 3 0 1 3 3 2]] |
iii | [19556549 61212362 52381660 50424958] |
ddsの結果からvalue
を作成する
np.int32
配列に保存する。Example
Phase | Content |
---|---|
dds results | 1,1,6,4,1,11,12,6,8,9,1,1,7,5,1,10,12,6,8,9 |
i | [[ 1 1 6 4 1] [11 12 6 8 9] [ 1 1 7 5 1] [10 12 6 8 9]] |
ii | [ 71233 771721 71505 706185] |
datasetの全てのデータから作成したkey
、value
をそれぞれ結合したhash_keys
、hash_values
のtupleをnpyファイルに保存する。
保存したファイルをBridgeBidding
クラスに読み込ませる
コントラクトブリッジでは手札の配り方による不公平をなくすためduplicate matchと呼ばれる対戦方式がある。duplicate matchでは一度対戦した後、同じ手札の配り方に対してPositionを入れ替えて再度対戦する。
BridgeBIdding
環境を用いてduplicate matchを行うための実装をpgx.experimenatal.bridge_bidding
内のduplicate_step
で提供する。duplicate_step
をBridgeBidding.step
の代わりに使用することでduplicate matchを実現できる。ただし、いくつか注意点がある。
duplicate_step
にはBridgeBidding.step
にはなかった引数・返り値がある。
has_duplicate_result
: 最初の対戦が終了したか記憶しておく配列table_a_reward
: 最初の対戦のrewardを記憶しておく配列duplicate_step
では2つの対戦が終了した時に、state.reward
が変更される。rewardは二つの対戦結果から計算されるIMP
が与えられる。import pgx
from pgx.experimental.bridge_bidding import duplicate_step
env = pgx.make("bridge_bidding")
init = jax.jit(jax.vmap(env.init))
duplicate_step = jax.jit(jax.vmap(duplicate_step))
N = # You need to determine the number of games to run in parallel
key = jax.random.PRNGKey(0)
key, subkey = jax.random.split(key)
keys = jax.random.split(subkey, N)
state: pgx.State = init(keys)
has_duplicate_result = jnp.zeros(N, dtype=jnp.bool_) # Array to remember if the first match is over
table_a_reward = state.rewards # Array to store the reward of the first match
while not state.terminated.all():
key, subkey = jax.random.split(key)
action = # You need to implement which actions you take
state, table_a_reward, has_duplicate_result = duplicate_step(
state, action, table_a_reward, has_duplicate_result
)
[Rong+19]
"Competitive Bridge Bidding with Deep Neural Networks"[Gong+19]
"Simple is Better: Training an End-to-end Contract Bridge Bidding Agent without Human Knowledge"[Tian+20]
"Joint Policy Search for Multi-agent Collaboration with Imperfect Information"[Lockhart+20]
"human-agent cooperation in bridge bidding"Double Dummy Solver
http://privat.bahnhof.se/wb758135/PBN format
https://www.tistis.nl/pbn/ IMP
https://en.wikipedia.org/wiki/International_Match_PointsあとはActionの説明もほしいです! @harukaki
@sotetsuk 一応ざっと書いてみました。レビューお願いします!
だいたいいい感じだとおもいます!
デフォルトのinitの挙動(どのddsの結果を使うのか)を書いてください!
Driveのリンクを加えて、そのデータの説明(サイズなど)も加えて下さい!
Ddsのデータの作り方も書いてください!
Ddsハッシュテーブルは、確か小さいテスト用のやつもありと思うのでそれへのリンクや一部抜粋も貼って説明して下さい!(具体例がないとわからない)
Actionもテーブルにしてください!(途中略してもいいので)
@sotetsuk コメント箇所手直ししました!レビューお願いします!
observation
, action
変更しました
datasetの作成方法
日本語でブリッジの説明文を書く
707
192
771