いものやま。

雑多な知識の寄せ集め

強化学習について学んでみた。(その15)

昨日はモンテカルロ-ES法による方策の評価と改善を説明した。

今日は、モンテカルロ-ES法で実際にプログラムを書いてみる。

ブラックジャック

本で例として挙げられているブラックシャックのAIをモンテカルロ-ES法で実装してみる。

ブラックシャックはカジノで定番のゲームで、以下のようなルール。

  • ルールの概要
    • トランプを使用する。
    • トランプは無限デッキあると仮定する。(=カードの出る確率は変化しない)
    • Aは1もしくは11として扱う。
    • 2〜10は数字通り扱う。
    • J, Q, Kは10として扱う。
    • カードの合計が21を越えず、出来るだけ21に近い方が勝ち。(同じなら引き分け)
  • プレイの流れ
    1. ユーザーにカードが2枚オープンで配られる。
    2. ディーラーにカードが1枚はオープン、もう1枚はクローズで配られる。
    3. プレイヤーは以下の行動が出来る。
      • ヒット(カードをもう1枚引く)
      • スタンド(カードを引くのを止める)
    4. カードの合計が21を越えたら、その時点でプレイヤーの負け。
      スタンドするか21を越えるまでは、何度でもヒット出来る。
    5. プレイヤーがスタンドを選択したら、ディーラーは伏せていたカードをオープンにし、カードの合計が17以上になるまでカードを引く。
      カードの合計が21を越えたら、その時点でプレイヤーの勝ち。
    6. ディーラーのカードの合計が21以下の場合、カードの合計を比べる。
      カードの合計が21に近い方の勝ち。
      同じなら引き分け。

状態や行動、報酬は、次のように与えることにする。

  • 状態は、以下のプレイヤーの状態とディーラーの見えているカードの組合せ
    • プレイヤーの状態は、(12, 利用可能なAあり)〜(21, 利用可能なAあり)、(12, 利用可能なAなし)〜(21, 利用可能なAなし)。
      これは、11以下であればバーストすることはないので、常にヒットを要求するため。
      なお、「利用可能なA」とは、その値を11として計算しているAのこと。
    • ディーラーの見えているカードは、A, 2〜10
  • 各状態でプレイヤーの選択出来る行動は、以下のいずれか:
    • ヒット
    • スタンド
  • 報酬は以下の通り:
    • 勝ちなら+1
    • 引き分けなら0
    • 負けなら-1

Rubyによる実装

Blackjackクラス

まずは、Blackjackを遊べるようにするクラスから。

#!/usr/bin/env ruby

#====================
# blackjack.rb
#====================

class Blackjack

  # カードとその価値
  # Aceについては、21を越えない限り11として計算する
  CARD = %w(A 2 3 4 5 6 7 8 9 10 J Q K).freeze
  CARD_VALUE = {
    'A'  => 11, '2'  =>  2, '3'  =>  3, '4'  =>  4, '5'  =>  5,
    '6'  =>  6, '7'  =>  7, '8'  =>  8, '9'  =>  9, '10' => 10,
    'J'  => 10, 'Q'  => 10, 'K'  => 10}.freeze

  def initialize
    @player_cards = Array.new
    @player_ace = 0
    @player_total = 0

    @dealer_cards = Array.new
    @dealer_ace = 0
    @dealer_total = 0

    while @player_total < 12
      player_draw
    end

    2.times do
      dealer_draw
    end

    @finish = false
  end

  attr_reader :player_total

  def player_has_ace?
    @player_ace > 0
  end

  def dealer_face_value
    CARD_VALUE[@dealer_cards[0]]
  end

  def player_hit
    raise "Game has finished." if @finish
    player_draw
    @finish = @player_total > 21
  end

  def player_stand
    raise "Game has finished." if @finish
    dealer_draw_all
    @finish = true
  end

  def finish?
    @finish
  end

  # ゲームの結果を返す。
  # +1: プレイヤーの勝ち
  #  0: 引き分け
  # -1: プレイヤーの負け
  def result
    raise "Game hasn't finished." unless @finish
    ret = 0
    if @player_total > 21
      ret = -1
    elsif @dealer_total > 21
      ret = 1
    elsif @player_total > @dealer_total
      ret = 1
    elsif @player_total < @dealer_total
      ret = -1
    else
      ret = 0
    end
    return ret
  end

  def print
    puts "-" * 20
    puts "Player (total: #{@player_total}) [#{@player_cards.map{|c| sprintf("%2s", c)}.join(', ')}]"
    if @finish
      puts "Dealer (total: #{@dealer_total}) [#{@dealer_cards.map{|c| sprintf("%2s", c)}.join(', ')}]"
    else
      puts "Dealer (total: ??) [#{sprintf "%2s", @dealer_cards[0]}, ??]"
    end
    puts "-" * 20
  end

  private

  def draw_card
    return CARD.sample
  end

  def player_draw
    card = draw_card
    @player_cards.push(card)
    @player_ace += 1 if card == 'A'
    @player_total += CARD_VALUE[card]
    if (@player_total > 21) && (@player_ace > 0)
      @player_total -= 10
      @player_ace -=1
    end
  end

  def dealer_draw
    card = draw_card
    @dealer_cards.push(card)
    @dealer_ace += 1 if card == 'A'
    @dealer_total += CARD_VALUE[card]
    if (@dealer_total > 21) && (@dealer_ace > 0)
      @dealer_total -= 10
      @dealer_ace -=1
    end
  end

  def dealer_draw_all
    while @dealer_total < 17
      dealer_draw
    end
  end
end

if __FILE__ == $PROGRAM_NAME
  game = Blackjack.new
  loop do
    game.print
    puts "select..."
    puts "[h] hit"
    puts "[s] stand"
    puts "[q] quit"

    input = STDIN.gets[0]
    case input
    when 'h'
      game.player_hit
    when 's'
      game.player_stand
    when 'q'
      exit
    else
      puts "wrong input!"
    end

    if game.finish?
      break
    end
  end

  game.print
  result = game.result
  if result > 0
    puts "Player win!"
  elsif result < 0
    puts "Player lose!"
  else
    puts "Draw."
  end
end

これを実行すると、例えば次のような感じ。

$ ./blackjack.rb
--------------------
Player (total: 13) [ 7,  6]
Dealer (total: ??) [ 4, ??]
--------------------
select...
[h] hit
[s] stand
[q] quit
h
--------------------
Player (total: 23) [ 7,  6,  Q]
Dealer (total: 13) [ 4,  9]
--------------------
Player lose!
$ ./blackjack.rb
--------------------
Player (total: 19) [ 9,  Q]
Dealer (total: ??) [ 6, ??]
--------------------
select...
[h] hit
[s] stand
[q] quit
s
--------------------
Player (total: 19) [ 9,  Q]
Dealer (total: 26) [ 6,  J,  J]
--------------------
Player win!
$ ./blackjack.rb
--------------------
Player (total: 12) [ 3,  9]
Dealer (total: ??) [ 7, ??]
--------------------
select...
[h] hit
[s] stand
[q] quit
h
--------------------
Player (total: 15) [ 3,  9,  3]
Dealer (total: ??) [ 7, ??]
--------------------
select...
[h] hit
[s] stand
[q] quit
h
--------------------
Player (total: 19) [ 3,  9,  3,  4]
Dealer (total: ??) [ 7, ??]
--------------------
select...
[h] hit
[s] stand
[q] quit
s
--------------------
Player (total: 19) [ 3,  9,  3,  4]
Dealer (total: 17) [ 7,  K]
--------------------
Player win!

行動価値

次に、行動価値。

#====================
# action_value.rb
#====================

require './blackjack'

class ActionValue
  def initialize
    @value = Array.new(2) do
      Hash.new do |player, total|
        player[total] = Hash.new do |dealer, face|
          dealer[face] = Array.new(2, 0.0)
        end
      end
    end
    @count = Array.new(2) do
      Hash.new do |player, total|
        player[total] = Hash.new do |dealer, face|
          dealer[face] = Array.new(2, 0)
        end
      end
    end
  end

  def get(player_total, player_has_ace, dealer_face_value, player_hit)
    ace_index = player_has_ace ? 0 : 1
    action_index = player_hit ? 0 : 1
    @value[ace_index][player_total][dealer_face_value][action_index]
  end

  def update(player_total, player_has_ace, dealer_face_value, player_hit, reward)
    ace_index = player_has_ace ? 0 : 1
    action_index = player_hit ? 0 : 1

    count = @count[ace_index][player_total][dealer_face_value][action_index]
    count += 1
    @count[ace_index][player_total][dealer_face_value][action_index] = count

    value = @value[ace_index][player_total][dealer_face_value][action_index]
    value += (1.0 / count) * (reward - value)
    @value[ace_index][player_total][dealer_face_value][action_index] = value
  end

  @@print_bar    = "---"  + "------------" * (12..21).size
  @@print_header = "  |"  + sprintf("   %2d(h/s)  " * (12..21).size, *((12..21).to_a))
  @@print_format = "%2d|" + " % 4.2f/% 4.2f" * (12..21).size + "\n"

  def print
    puts @@print_bar.sub("-" * "[ace]".size, "[ace]")
    puts @@print_header
    puts @@print_bar
    (2..11).each do |dealer_face_value|
      printf @@print_format, 
        dealer_face_value,
        *(
          (12..21).map do |player_total|
            [
              get(player_total, true, dealer_face_value, true),
              get(player_total, true, dealer_face_value, false)
            ]
          end.flatten
        )
    end
    puts @@print_bar

    puts @@print_bar.sub("-" * "[no ace]".size, "[no ace]")
    puts @@print_header
    puts @@print_bar
    (2..11).each do |dealer_face_value|
      printf @@print_format, 
        dealer_face_value,
        *(
          (12..21).map do |player_total|
            [
              get(player_total, false, dealer_face_value, true),
              get(player_total, false, dealer_face_value, false)
            ]
          end.flatten
        )
    end
    puts @@print_bar
  end
end

方策

そして、方策。

#====================
# policy.rb
#====================

require './blackjack'

class Policy
  def initialize
    @policy = Array.new(2) do
      Hash.new do |player, total|
        player[total] = Hash.new do |dealer, face|
          dealer[face] = true
        end
      end
    end
  end

  def hit?(player_total, player_has_ace, dealer_face_value)
    ace_index = player_has_ace ? 0 : 1
    @policy[ace_index][player_total][dealer_face_value]
  end

  def set(player_total, player_has_ace, dealer_face_value, hit)
    ace_index = player_has_ace ? 0 : 1
    @policy[ace_index][player_total][dealer_face_value] = hit
  end

  @@print_bar    = "---"  + "------" * (12..21).size
  @@print_header = "  |"  + sprintf("    %2d" * (12..21).size, *((12..21).to_a))
  @@print_format = "%2d|" + " %5s" * (12..21).size + "\n"

  def print
    puts @@print_bar.sub("-" * "[ace]".size, "[ace]")
    puts @@print_header
    puts @@print_bar
    (2..11).each do |dealer_face_value|
      printf @@print_format, 
        dealer_face_value,
        *((12..21).map{|player_total| hit?(player_total, true, dealer_face_value) ? 'hit' : 'stand'})
    end
    puts @@print_bar

    puts @@print_bar.sub("-" * "[no ace]".size, "[no ace]")
    puts @@print_header
    puts @@print_bar
    (2..11).each do |dealer_face_value|
      printf @@print_format, 
        dealer_face_value,
        *((12..21).map{|player_total| hit?(player_total, false, dealer_face_value) ? 'hit' : 'stand'})
    end
    puts @@print_bar
  end
end

モンテカルロ-ES法

最後に、モンテカルロ-ES法。

#!/usr/bin/env ruby

#====================
# mces_method.rb
#====================

require './blackjack'
require './action_value'
require './policy'

# モンテカルロ-ES法
class MCESMethod

  def initialize(action_value, policy)
    @action_value = action_value
    @policy = policy
  end

  attr_reader :action_value, :policy

  # 1ゲーム行い、価値関数と方策を更新する
  def simulate(verbose=false)
    game = Blackjack.new
    game.print if verbose

    player_total_queue = Array.new
    player_has_ace_queue = Array.new
    player_hit_queue = Array.new
    dealer_face_value = game.dealer_face_value

    # エピソード生成
    loop do
      player_total = game.player_total
      player_has_ace = game.player_has_ace?

      # 一番最初の行動は、開始点探査の仮定を満たすために、
      # ランダムに選択する
      if player_hit_queue.empty?
        player_hit = [true, false].sample
      else
        player_hit = @policy.hit?(player_total, player_has_ace, dealer_face_value)
      end

      player_total_queue.push(player_total)
      player_has_ace_queue.push(player_has_ace)
      player_hit_queue.push(player_hit)

      if player_hit
        game.player_hit
        game.print if verbose
        break if game.finish?
      else
        game.player_stand
        game.print if verbose
        break
      end
    end

    # 価値関数の更新
    result = game.result
    player_total_queue.zip(player_has_ace_queue, player_hit_queue) do |player_total, player_has_ace, player_hit|
      @action_value.update(player_total, player_has_ace, dealer_face_value, player_hit, result)
    end

    # 方策の更新
    player_total_queue.zip(player_has_ace_queue) do |player_total, player_has_ace|
      hit_value = @action_value.get(player_total, player_has_ace, dealer_face_value, true)
      stand_value = @action_value.get(player_total, player_has_ace, dealer_face_value, false)
      if hit_value > stand_value
        @policy.set(player_total, player_has_ace, dealer_face_value, true)
      elsif hit_value < stand_value
        @policy.set(player_total, player_has_ace, dealer_face_value, false)
      end
    end
  end

end

if __FILE__ == $PROGRAM_NAME
  value = ActionValue.new
  policy = Policy.new
  mces = MCESMethod.new(value, policy)
  (1..10).each do |i|
    100000.times do
      mces.simulate
    end
    puts "[#{i * 100000}]"
    mces.action_value.print
    mces.policy.print
  end
end

このファイルを実行ファイルとして実行した場合には、10万回シミュレーションを行うごとに行動価値と方策の状態を出力させ、それを10回繰り返すようにしている。

そして、実行結果は以下。
(実行時間が分かるように、timeを使ってる)

$ time ./mces_method.rb
[100000]
[ace]----------------------------------------------------------------------------------------------------------------------
  |   12(h/s)     13(h/s)     14(h/s)     15(h/s)     16(h/s)     17(h/s)     18(h/s)     19(h/s)     20(h/s)     21(h/s)
---------------------------------------------------------------------------------------------------------------------------
 2|  0.05/-0.36  0.04/-0.36  0.07/-0.57  0.08/-0.39  0.08/-0.35 -0.05/-0.18  0.29/ 0.18  0.02/ 0.29  0.36/ 0.65  0.31/ 0.90
 3| -0.00/-0.35  0.04/-0.10  0.04/-0.22 -0.08/-0.24 -0.03/-0.52 -0.19/-0.08  0.17/ 0.39  0.19/ 0.29  0.39/ 0.76  0.26/ 0.92
 4| -0.07/-0.28  0.06/-0.29  0.21/-0.12  0.09/-0.02  0.14/-0.15  0.04/-0.31  0.00/-0.26  0.13/ 0.53  0.00/ 0.77  0.23/ 0.88
 5| -0.00/-0.05  0.05/-0.06  0.28/-0.12 -0.06/ 0.03 -0.08/-0.24  0.11/ 0.12 -0.00/ 0.12  0.15/ 0.40  0.36/ 0.69  0.25/ 0.89
 6|  0.10/-0.15  0.07/-0.12  0.27/-0.19  0.07/-0.19 -0.06/-0.38  0.12/ 0.12  0.39/ 0.34  0.39/ 0.50  0.16/ 0.71  0.27/ 0.90
 7|  0.11/-0.58  0.26/-0.58  0.00/-0.38  0.03/-0.50 -0.09/-0.56  0.23/-0.13  0.26/ 0.65  0.38/ 0.60  0.42/ 0.82  0.30/ 0.94
 8| -0.09/-0.62  0.18/-0.79 -0.21/-0.50 -0.10/-0.48 -0.19/-0.37 -0.13/-0.53 -0.07/ 0.18  0.12/ 0.64  0.37/ 0.79  0.18/ 0.93
 9|  0.33/-0.43 -0.07/-0.27 -0.04/-0.45 -0.04/-0.35 -0.13/-0.52 -0.39/-0.47 -0.05/-0.20 -0.21/ 0.25  0.05/ 0.74  0.08/ 0.96
10| -0.10/-0.46 -0.09/-0.60 -0.21/-0.52 -0.24/-0.57 -0.35/-0.53 -0.23/-0.36 -0.16/-0.21 -0.15/ 0.03 -0.12/ 0.37  0.04/ 0.89
11| -0.23/-0.90 -0.35/-0.82 -0.23/-0.66 -0.36/-0.65 -0.46/-0.80 -0.25/-0.55 -0.21/-0.45 -0.24/-0.04 -0.29/ 0.15 -0.13/ 0.64
---------------------------------------------------------------------------------------------------------------------------
[no ace]-------------------------------------------------------------------------------------------------------------------
  |   12(h/s)     13(h/s)     14(h/s)     15(h/s)     16(h/s)     17(h/s)     18(h/s)     19(h/s)     20(h/s)     21(h/s)
---------------------------------------------------------------------------------------------------------------------------
 2| -0.27/-0.26 -0.30/-0.33 -0.40/-0.28 -0.42/-0.26 -0.49/-0.32 -0.51/-0.09 -0.68/ 0.12 -0.71/ 0.39 -0.85/ 0.58 -1.00/ 0.90
 3| -0.22/-0.26 -0.28/-0.28 -0.36/-0.30 -0.43/-0.25 -0.41/-0.20 -0.58/-0.07 -0.54/ 0.15 -0.67/ 0.41 -0.87/ 0.63 -1.00/ 0.90
 4| -0.18/-0.20 -0.24/-0.25 -0.30/-0.19 -0.41/-0.25 -0.46/-0.11 -0.46/-0.08 -0.61/ 0.18 -0.73/ 0.42 -0.87/ 0.68 -1.00/ 0.88
 5| -0.32/-0.13 -0.21/-0.14 -0.35/-0.19 -0.34/-0.16 -0.55/-0.17 -0.49/-0.10 -0.68/ 0.16 -0.72/ 0.42 -0.87/ 0.67 -1.00/ 0.90
 6| -0.21/-0.16 -0.35/-0.18 -0.29/-0.17 -0.33/-0.15 -0.42/-0.18 -0.54/-0.03 -0.64/ 0.28 -0.68/ 0.51 -0.85/ 0.74 -1.00/ 0.90
 7| -0.27/-0.43 -0.31/-0.40 -0.32/-0.46 -0.39/-0.53 -0.45/-0.42 -0.45/-0.13 -0.54/ 0.40 -0.75/ 0.59 -0.85/ 0.81 -1.00/ 0.90
 8| -0.32/-0.48 -0.43/-0.54 -0.39/-0.58 -0.46/-0.53 -0.37/-0.39 -0.49/-0.38 -0.60/ 0.05 -0.73/ 0.55 -0.83/ 0.82 -1.00/ 0.92
 9| -0.37/-0.54 -0.36/-0.57 -0.55/-0.54 -0.51/-0.54 -0.52/-0.52 -0.54/-0.40 -0.62/-0.23 -0.67/ 0.26 -0.90/ 0.73 -1.00/ 0.93
10| -0.44/-0.57 -0.47/-0.58 -0.46/-0.59 -0.54/-0.58 -0.55/-0.60 -0.60/-0.47 -0.68/-0.26 -0.77/ 0.00 -0.86/ 0.44 -1.00/ 0.89
11| -0.53/-0.75 -0.56/-0.77 -0.65/-0.76 -0.62/-0.78 -0.62/-0.75 -0.60/-0.61 -0.78/-0.38 -0.84/-0.09 -0.86/ 0.15 -1.00/ 0.62
---------------------------------------------------------------------------------------------------------------------------
[ace]----------------------------------------------------------
  |    12    13    14    15    16    17    18    19    20    21
---------------------------------------------------------------
 2|   hit   hit   hit   hit   hit   hit   hit stand stand stand
 3|   hit   hit   hit   hit   hit stand stand stand stand stand
 4|   hit   hit   hit   hit   hit   hit   hit stand stand stand
 5|   hit   hit   hit stand   hit stand stand stand stand stand
 6|   hit   hit   hit   hit   hit   hit   hit stand stand stand
 7|   hit   hit   hit   hit   hit   hit stand stand stand stand
 8|   hit   hit   hit   hit   hit   hit stand stand stand stand
 9|   hit   hit   hit   hit   hit   hit   hit stand stand stand
10|   hit   hit   hit   hit   hit   hit   hit stand stand stand
11|   hit   hit   hit   hit   hit   hit   hit stand stand stand
---------------------------------------------------------------
[no ace]-------------------------------------------------------
  |    12    13    14    15    16    17    18    19    20    21
---------------------------------------------------------------
 2| stand   hit stand stand stand stand stand stand stand stand
 3|   hit stand stand stand stand stand stand stand stand stand
 4|   hit   hit stand stand stand stand stand stand stand stand
 5| stand stand stand stand stand stand stand stand stand stand
 6| stand stand stand stand stand stand stand stand stand stand
 7|   hit   hit   hit   hit stand stand stand stand stand stand
 8|   hit   hit   hit   hit   hit stand stand stand stand stand
 9|   hit   hit stand   hit   hit stand stand stand stand stand
10|   hit   hit   hit   hit   hit stand stand stand stand stand
11|   hit   hit   hit   hit   hit   hit stand stand stand stand
---------------------------------------------------------------
[200000]
[ace]----------------------------------------------------------------------------------------------------------------------
  |   12(h/s)     13(h/s)     14(h/s)     15(h/s)     16(h/s)     17(h/s)     18(h/s)     19(h/s)     20(h/s)     21(h/s)
---------------------------------------------------------------------------------------------------------------------------
 2|  0.05/-0.25  0.18/-0.29  0.05/-0.45  0.07/-0.48 -0.01/-0.29 -0.11/-0.19  0.16/ 0.23  0.08/ 0.32  0.31/ 0.61  0.25/ 0.89
 3|  0.07/-0.22  0.04/-0.18  0.10/-0.24 -0.09/-0.06 -0.03/-0.24 -0.09/-0.11  0.09/ 0.25  0.21/ 0.30  0.40/ 0.64  0.22/ 0.91
 4| -0.04/-0.17  0.04/-0.40 -0.00/-0.29  0.06/-0.15  0.09/-0.11  0.03/-0.23 -0.01/-0.15  0.14/ 0.48  0.11/ 0.69  0.21/ 0.89
 5| -0.03/ 0.02  0.03/-0.10  0.17/-0.16 -0.07/-0.10  0.05/-0.28  0.03/-0.04  0.08/ 0.19 -0.02/ 0.35  0.33/ 0.69  0.27/ 0.89
 6|  0.20/-0.33  0.21/-0.18  0.12/-0.14  0.02/-0.27  0.02/-0.17  0.14/-0.05  0.28/ 0.33  0.38/ 0.46  0.23/ 0.70  0.28/ 0.91
 7|  0.33/-0.50  0.09/-0.49  0.06/-0.48  0.09/-0.39 -0.04/-0.43  0.11/-0.11  0.19/ 0.51  0.27/ 0.61  0.29/ 0.84  0.30/ 0.94
 8| -0.10/-0.64  0.00/-0.67 -0.23/-0.52 -0.04/-0.50 -0.08/-0.47 -0.19/-0.45  0.15/ 0.19  0.08/ 0.59  0.40/ 0.80  0.16/ 0.93
 9|  0.35/-0.14 -0.17/-0.38 -0.12/-0.50 -0.11/-0.42 -0.07/-0.57 -0.22/-0.36 -0.11/-0.21 -0.13/ 0.35 -0.01/ 0.70  0.08/ 0.94
10| -0.12/-0.53 -0.16/-0.62 -0.20/-0.57 -0.22/-0.58 -0.33/-0.58 -0.26/-0.43 -0.19/-0.22 -0.11/ 0.02 -0.12/ 0.36  0.01/ 0.89
11| -0.17/-0.79 -0.34/-0.77 -0.24/-0.73 -0.33/-0.75 -0.43/-0.73 -0.33/-0.63 -0.18/-0.44 -0.32/-0.05 -0.35/ 0.17 -0.12/ 0.65
---------------------------------------------------------------------------------------------------------------------------
[no ace]-------------------------------------------------------------------------------------------------------------------
  |   12(h/s)     13(h/s)     14(h/s)     15(h/s)     16(h/s)     17(h/s)     18(h/s)     19(h/s)     20(h/s)     21(h/s)
---------------------------------------------------------------------------------------------------------------------------
 2| -0.26/-0.26 -0.26/-0.37 -0.39/-0.25 -0.41/-0.24 -0.47/-0.29 -0.52/-0.13 -0.65/ 0.13 -0.70/ 0.40 -0.87/ 0.61 -1.00/ 0.89
 3| -0.22/-0.29 -0.28/-0.28 -0.35/-0.30 -0.44/-0.21 -0.41/-0.23 -0.55/-0.06 -0.61/ 0.14 -0.72/ 0.42 -0.85/ 0.64 -1.00/ 0.90
 4| -0.22/-0.25 -0.25/-0.20 -0.31/-0.24 -0.39/-0.23 -0.47/-0.14 -0.50/-0.09 -0.62/ 0.21 -0.75/ 0.46 -0.87/ 0.67 -1.00/ 0.90
 5| -0.27/-0.14 -0.26/-0.15 -0.33/-0.19 -0.35/-0.16 -0.52/-0.18 -0.51/-0.09 -0.63/ 0.17 -0.76/ 0.42 -0.86/ 0.66 -1.00/ 0.90
 6| -0.17/-0.13 -0.26/-0.17 -0.33/-0.16 -0.30/-0.18 -0.42/-0.15 -0.50/-0.01 -0.61/ 0.29 -0.72/ 0.50 -0.84/ 0.74 -1.00/ 0.91
 7| -0.22/-0.48 -0.31/-0.45 -0.34/-0.43 -0.37/-0.48 -0.43/-0.42 -0.47/-0.15 -0.61/ 0.43 -0.75/ 0.59 -0.84/ 0.78 -1.00/ 0.91
 8| -0.29/-0.50 -0.41/-0.49 -0.36/-0.59 -0.44/-0.48 -0.38/-0.46 -0.50/-0.37 -0.56/ 0.08 -0.72/ 0.56 -0.83/ 0.83 -1.00/ 0.92
 9| -0.32/-0.54 -0.34/-0.51 -0.49/-0.54 -0.49/-0.55 -0.48/-0.50 -0.55/-0.43 -0.61/-0.21 -0.70/ 0.25 -0.87/ 0.75 -1.00/ 0.94
10| -0.43/-0.58 -0.48/-0.58 -0.47/-0.58 -0.54/-0.56 -0.57/-0.60 -0.60/-0.48 -0.66/-0.24 -0.77/-0.03 -0.84/ 0.44 -1.00/ 0.89
11| -0.51/-0.77 -0.56/-0.78 -0.65/-0.77 -0.58/-0.80 -0.59/-0.76 -0.65/-0.61 -0.73/-0.34 -0.81/-0.10 -0.86/ 0.14 -1.00/ 0.62
---------------------------------------------------------------------------------------------------------------------------
[ace]----------------------------------------------------------
  |    12    13    14    15    16    17    18    19    20    21
---------------------------------------------------------------
 2|   hit   hit   hit   hit   hit   hit stand stand stand stand
 3|   hit   hit   hit stand   hit   hit stand stand stand stand
 4|   hit   hit   hit   hit   hit   hit   hit stand stand stand
 5| stand   hit   hit   hit   hit   hit stand stand stand stand
 6|   hit   hit   hit   hit   hit   hit stand stand stand stand
 7|   hit   hit   hit   hit   hit   hit stand stand stand stand
 8|   hit   hit   hit   hit   hit   hit stand stand stand stand
 9|   hit   hit   hit   hit   hit   hit   hit stand stand stand
10|   hit   hit   hit   hit   hit   hit   hit stand stand stand
11|   hit   hit   hit   hit   hit   hit   hit stand stand stand
---------------------------------------------------------------
[no ace]-------------------------------------------------------
  |    12    13    14    15    16    17    18    19    20    21
---------------------------------------------------------------
 2| stand   hit stand stand stand stand stand stand stand stand
 3|   hit   hit stand stand stand stand stand stand stand stand
 4|   hit stand stand stand stand stand stand stand stand stand
 5| stand stand stand stand stand stand stand stand stand stand
 6| stand stand stand stand stand stand stand stand stand stand
 7|   hit   hit   hit   hit stand stand stand stand stand stand
 8|   hit   hit   hit   hit   hit stand stand stand stand stand
 9|   hit   hit   hit   hit   hit stand stand stand stand stand
10|   hit   hit   hit   hit   hit stand stand stand stand stand
11|   hit   hit   hit   hit   hit stand stand stand stand stand
---------------------------------------------------------------

〜省略〜

[900000]
[ace]----------------------------------------------------------------------------------------------------------------------
  |   12(h/s)     13(h/s)     14(h/s)     15(h/s)     16(h/s)     17(h/s)     18(h/s)     19(h/s)     20(h/s)     21(h/s)
---------------------------------------------------------------------------------------------------------------------------
 2|  0.02/-0.30  0.04/-0.26 -0.05/-0.38 -0.10/-0.26 -0.04/-0.28 -0.05/-0.17  0.09/ 0.09  0.20/ 0.35  0.20/ 0.65  0.19/ 0.89
 3|  0.10/-0.23  0.03/-0.27  0.04/-0.26  0.02/-0.17  0.03/-0.22  0.01/-0.15  0.14/ 0.20  0.16/ 0.38  0.27/ 0.63  0.21/ 0.90
 4|  0.01/-0.32  0.06/-0.17  0.02/-0.25  0.07/-0.15  0.06/-0.17  0.04/-0.14  0.11/ 0.09  0.16/ 0.45  0.15/ 0.67  0.26/ 0.90
 5|  0.29/-0.06  0.13/-0.22  0.13/-0.17  0.01/-0.22  0.07/-0.17  0.07/-0.04  0.12/ 0.18  0.18/ 0.40  0.24/ 0.70  0.25/ 0.89
 6|  0.26/-0.24  0.21/-0.12  0.17/-0.16  0.11/-0.20  0.12/-0.12  0.12/ 0.01  0.22/ 0.20  0.25/ 0.50  0.34/ 0.70  0.26/ 0.90
 7|  0.27/-0.40  0.12/-0.53  0.11/-0.47  0.06/-0.41 -0.02/-0.39  0.05/-0.08  0.14/ 0.43  0.20/ 0.65  0.31/ 0.81  0.22/ 0.94
 8|  0.09/-0.58  0.04/-0.48 -0.03/-0.50 -0.04/-0.53 -0.12/-0.50 -0.09/-0.40  0.01/ 0.11  0.14/ 0.62  0.21/ 0.81  0.17/ 0.93
 9| -0.04/-0.44 -0.12/-0.50 -0.10/-0.53 -0.18/-0.50 -0.13/-0.57 -0.22/-0.42 -0.12/-0.16 -0.00/ 0.33  0.07/ 0.75  0.08/ 0.94
10| -0.11/-0.54 -0.16/-0.57 -0.17/-0.58 -0.21/-0.58 -0.25/-0.60 -0.22/-0.46 -0.18/-0.22 -0.12/ 0.00 -0.07/ 0.42  0.04/ 0.89
11| -0.29/-0.74 -0.33/-0.75 -0.28/-0.69 -0.29/-0.78 -0.35/-0.79 -0.41/-0.62 -0.29/-0.35 -0.28/-0.15 -0.27/ 0.15 -0.14/ 0.64
---------------------------------------------------------------------------------------------------------------------------
[no ace]-------------------------------------------------------------------------------------------------------------------
  |   12(h/s)     13(h/s)     14(h/s)     15(h/s)     16(h/s)     17(h/s)     18(h/s)     19(h/s)     20(h/s)     21(h/s)
---------------------------------------------------------------------------------------------------------------------------
 2| -0.24/-0.30 -0.29/-0.28 -0.37/-0.26 -0.43/-0.29 -0.49/-0.29 -0.52/-0.14 -0.65/ 0.14 -0.71/ 0.38 -0.85/ 0.63 -1.00/ 0.88
 3| -0.23/-0.24 -0.28/-0.26 -0.37/-0.25 -0.40/-0.23 -0.46/-0.26 -0.53/-0.12 -0.64/ 0.16 -0.74/ 0.42 -0.86/ 0.64 -1.00/ 0.89
 4| -0.22/-0.22 -0.28/-0.21 -0.31/-0.24 -0.39/-0.22 -0.45/-0.19 -0.54/-0.07 -0.63/ 0.20 -0.71/ 0.42 -0.86/ 0.66 -1.00/ 0.88
 5| -0.20/-0.16 -0.25/-0.17 -0.33/-0.18 -0.39/-0.16 -0.47/-0.16 -0.52/-0.05 -0.62/ 0.19 -0.75/ 0.43 -0.85/ 0.67 -1.00/ 0.89
 6| -0.16/-0.14 -0.26/-0.16 -0.32/-0.13 -0.37/-0.14 -0.43/-0.17 -0.51/-0.00 -0.60/ 0.28 -0.74/ 0.50 -0.87/ 0.71 -1.00/ 0.90
 7| -0.20/-0.47 -0.30/-0.49 -0.33/-0.44 -0.36/-0.46 -0.43/-0.44 -0.46/-0.11 -0.57/ 0.40 -0.71/ 0.60 -0.86/ 0.77 -1.00/ 0.92
 8| -0.27/-0.50 -0.35/-0.52 -0.37/-0.52 -0.44/-0.50 -0.48/-0.48 -0.55/-0.38 -0.59/ 0.09 -0.71/ 0.58 -0.85/ 0.80 -1.00/ 0.94
 9| -0.34/-0.53 -0.39/-0.54 -0.47/-0.56 -0.48/-0.53 -0.51/-0.56 -0.54/-0.43 -0.63/-0.20 -0.71/ 0.27 -0.85/ 0.76 -1.00/ 0.94
10| -0.43/-0.57 -0.47/-0.57 -0.49/-0.59 -0.55/-0.57 -0.57/-0.58 -0.60/-0.46 -0.66/-0.24 -0.75/-0.02 -0.86/ 0.44 -1.00/ 0.89
11| -0.51/-0.75 -0.54/-0.76 -0.58/-0.77 -0.62/-0.76 -0.63/-0.78 -0.68/-0.63 -0.71/-0.37 -0.78/-0.11 -0.87/ 0.14 -1.00/ 0.64
---------------------------------------------------------------------------------------------------------------------------
[ace]----------------------------------------------------------
  |    12    13    14    15    16    17    18    19    20    21
---------------------------------------------------------------
 2|   hit   hit   hit   hit   hit   hit   hit stand stand stand
 3|   hit   hit   hit   hit   hit   hit stand stand stand stand
 4|   hit   hit   hit   hit   hit   hit   hit stand stand stand
 5|   hit   hit   hit   hit   hit   hit stand stand stand stand
 6|   hit   hit   hit   hit   hit   hit   hit stand stand stand
 7|   hit   hit   hit   hit   hit   hit stand stand stand stand
 8|   hit   hit   hit   hit   hit   hit stand stand stand stand
 9|   hit   hit   hit   hit   hit   hit   hit stand stand stand
10|   hit   hit   hit   hit   hit   hit   hit stand stand stand
11|   hit   hit   hit   hit   hit   hit   hit stand stand stand
---------------------------------------------------------------
[no ace]-------------------------------------------------------
  |    12    13    14    15    16    17    18    19    20    21
---------------------------------------------------------------
 2|   hit stand stand stand stand stand stand stand stand stand
 3|   hit stand stand stand stand stand stand stand stand stand
 4| stand stand stand stand stand stand stand stand stand stand
 5| stand stand stand stand stand stand stand stand stand stand
 6| stand stand stand stand stand stand stand stand stand stand
 7|   hit   hit   hit   hit   hit stand stand stand stand stand
 8|   hit   hit   hit   hit   hit stand stand stand stand stand
 9|   hit   hit   hit   hit   hit stand stand stand stand stand
10|   hit   hit   hit   hit   hit stand stand stand stand stand
11|   hit   hit   hit   hit   hit stand stand stand stand stand
---------------------------------------------------------------
[1000000]
[ace]----------------------------------------------------------------------------------------------------------------------
  |   12(h/s)     13(h/s)     14(h/s)     15(h/s)     16(h/s)     17(h/s)     18(h/s)     19(h/s)     20(h/s)     21(h/s)
---------------------------------------------------------------------------------------------------------------------------
 2|  0.02/-0.29  0.03/-0.27 -0.06/-0.37 -0.10/-0.25 -0.06/-0.26 -0.03/-0.18  0.07/ 0.11  0.20/ 0.35  0.20/ 0.65  0.19/ 0.88
 3|  0.10/-0.23  0.04/-0.27  0.04/-0.25  0.04/-0.18  0.03/-0.23  0.01/-0.13  0.15/ 0.19  0.14/ 0.38  0.26/ 0.63  0.21/ 0.90
 4|  0.03/-0.27  0.07/-0.19  0.02/-0.25  0.07/-0.17  0.07/-0.17  0.05/-0.15  0.09/ 0.08  0.17/ 0.45  0.17/ 0.67  0.26/ 0.90
 5|  0.27/-0.10  0.10/-0.24  0.13/-0.18  0.03/-0.21  0.08/-0.16  0.08/-0.05  0.11/ 0.18  0.17/ 0.41  0.25/ 0.69  0.25/ 0.89
 6|  0.28/-0.24  0.21/-0.15  0.17/-0.17  0.12/-0.19  0.12/-0.15  0.14/-0.01  0.22/ 0.21  0.27/ 0.50  0.34/ 0.70  0.26/ 0.90
 7|  0.28/-0.37  0.12/-0.52  0.10/-0.48  0.05/-0.42 -0.03/-0.39  0.05/-0.08  0.14/ 0.43  0.22/ 0.66  0.30/ 0.80  0.23/ 0.94
 8|  0.08/-0.56  0.03/-0.47 -0.03/-0.50 -0.05/-0.53 -0.12/-0.50 -0.10/-0.38  0.02/ 0.10  0.13/ 0.61  0.20/ 0.81  0.19/ 0.93
 9| -0.03/-0.45 -0.13/-0.50 -0.07/-0.55 -0.19/-0.51 -0.14/-0.56 -0.22/-0.44 -0.14/-0.16 -0.01/ 0.32  0.06/ 0.75  0.09/ 0.94
10| -0.12/-0.55 -0.16/-0.58 -0.17/-0.58 -0.22/-0.59 -0.25/-0.60 -0.22/-0.46 -0.18/-0.23 -0.11/-0.00 -0.07/ 0.42  0.04/ 0.89
11| -0.31/-0.76 -0.30/-0.73 -0.28/-0.71 -0.29/-0.79 -0.33/-0.80 -0.40/-0.62 -0.30/-0.36 -0.28/-0.18 -0.26/ 0.17 -0.14/ 0.64
---------------------------------------------------------------------------------------------------------------------------
[no ace]-------------------------------------------------------------------------------------------------------------------
  |   12(h/s)     13(h/s)     14(h/s)     15(h/s)     16(h/s)     17(h/s)     18(h/s)     19(h/s)     20(h/s)     21(h/s)
---------------------------------------------------------------------------------------------------------------------------
 2| -0.24/-0.30 -0.29/-0.28 -0.38/-0.26 -0.43/-0.29 -0.48/-0.30 -0.52/-0.13 -0.64/ 0.14 -0.71/ 0.38 -0.85/ 0.63 -1.00/ 0.88
 3| -0.23/-0.24 -0.28/-0.26 -0.36/-0.26 -0.40/-0.24 -0.46/-0.26 -0.53/-0.12 -0.64/ 0.16 -0.74/ 0.42 -0.86/ 0.64 -1.00/ 0.89
 4| -0.23/-0.22 -0.28/-0.21 -0.31/-0.23 -0.40/-0.21 -0.45/-0.19 -0.53/-0.08 -0.64/ 0.19 -0.72/ 0.43 -0.86/ 0.66 -1.00/ 0.88
 5| -0.20/-0.16 -0.24/-0.17 -0.32/-0.18 -0.39/-0.16 -0.47/-0.16 -0.52/-0.05 -0.62/ 0.19 -0.74/ 0.42 -0.86/ 0.66 -1.00/ 0.89
 6| -0.15/-0.14 -0.26/-0.16 -0.31/-0.13 -0.37/-0.13 -0.43/-0.17 -0.51/-0.00 -0.60/ 0.28 -0.74/ 0.49 -0.87/ 0.71 -1.00/ 0.90
 7| -0.21/-0.48 -0.30/-0.49 -0.33/-0.44 -0.36/-0.46 -0.42/-0.44 -0.45/-0.11 -0.57/ 0.39 -0.71/ 0.60 -0.85/ 0.77 -1.00/ 0.93
 8| -0.28/-0.50 -0.34/-0.52 -0.37/-0.52 -0.43/-0.50 -0.48/-0.49 -0.55/-0.38 -0.59/ 0.09 -0.71/ 0.58 -0.85/ 0.80 -1.00/ 0.93
 9| -0.34/-0.54 -0.39/-0.54 -0.46/-0.56 -0.48/-0.53 -0.52/-0.56 -0.54/-0.43 -0.63/-0.21 -0.72/ 0.27 -0.85/ 0.76 -1.00/ 0.94
10| -0.43/-0.57 -0.47/-0.58 -0.49/-0.59 -0.55/-0.57 -0.57/-0.58 -0.60/-0.46 -0.67/-0.24 -0.75/-0.03 -0.86/ 0.44 -1.00/ 0.89
11| -0.52/-0.76 -0.54/-0.76 -0.58/-0.77 -0.62/-0.76 -0.63/-0.77 -0.67/-0.63 -0.72/-0.37 -0.79/-0.11 -0.87/ 0.14 -1.00/ 0.64
---------------------------------------------------------------------------------------------------------------------------
[ace]----------------------------------------------------------
  |    12    13    14    15    16    17    18    19    20    21
---------------------------------------------------------------
 2|   hit   hit   hit   hit   hit   hit stand stand stand stand
 3|   hit   hit   hit   hit   hit   hit stand stand stand stand
 4|   hit   hit   hit   hit   hit   hit   hit stand stand stand
 5|   hit   hit   hit   hit   hit   hit stand stand stand stand
 6|   hit   hit   hit   hit   hit   hit   hit stand stand stand
 7|   hit   hit   hit   hit   hit   hit stand stand stand stand
 8|   hit   hit   hit   hit   hit   hit stand stand stand stand
 9|   hit   hit   hit   hit   hit   hit   hit stand stand stand
10|   hit   hit   hit   hit   hit   hit   hit stand stand stand
11|   hit   hit   hit   hit   hit   hit   hit stand stand stand
---------------------------------------------------------------
[no ace]-------------------------------------------------------
  |    12    13    14    15    16    17    18    19    20    21
---------------------------------------------------------------
 2|   hit stand stand stand stand stand stand stand stand stand
 3|   hit stand stand stand stand stand stand stand stand stand
 4| stand stand stand stand stand stand stand stand stand stand
 5| stand stand stand stand stand stand stand stand stand stand
 6| stand stand stand stand stand stand stand stand stand stand
 7|   hit   hit   hit   hit   hit stand stand stand stand stand
 8|   hit   hit   hit   hit   hit stand stand stand stand stand
 9|   hit   hit   hit   hit   hit stand stand stand stand stand
10|   hit   hit   hit   hit   hit stand stand stand stand stand
11|   hit   hit   hit   hit   hit stand stand stand stand stand
---------------------------------------------------------------

real    0m6.368s
user    0m6.229s
sys     0m0.017s

なお、行動価値のテーブルの見方は、行がディーラーの見えているカード、列がプレイヤーのカードの合計で、ヒットを選択したときの価値とスタンドを選択したときの価値がスラッシュで区切られて書かれている。

最終的な結果を本に書かれている表と見比べると、プレイヤーの合計が18で利用可能なAを持っていて、ディーラーの見えているカードが4, 6のときだけ違う結果になっているけど、ほぼ同じ結果になっている。
(そして、その違っている部分についても、さらに試行を繰り返せば同じになると思われる)

それと、最終的に100万回シミュレーションを繰り返しているけれど、6秒程度で終わってる。
これは、アルゴリズムがシンプルで、状態や行動の種類も少なく、1回のシミュレーションが軽いというのが大きい。

今日はここまで!

強化学習

強化学習

  • 作者: Richard S.Sutton,Andrew G.Barto,三上貞芳,皆川雅章
  • 出版社/メーカー: 森北出版
  • 発売日: 2000/12/01
  • メディア: 単行本(ソフトカバー)
  • 購入: 5人 クリック: 76回
  • この商品を含むブログ (29件) を見る