කුන්පෝකර් මතප්රතිවිරුද්ධ කනගාටුව අවම කිරීම (සීඑෆ්ආර්)

මෙයකුහ්න් පෝකර් වෙත ප්රතිවිරුද්ධ කනගාටුව අවම කිරීම (CFR) අදාළ වේ.

කුන් පෝකර් යනු ක්රීඩක 3-කාඩ් ඔට්ටු ඇල්ලීමේ ක්රීඩාවකි. ක්රීඩකයන්ට Ace, King සහ Queen (ඇඳුම් කට්ටල නොමැත) අතරින් එක් කාඩ්පතක් බැගින් ගනුදෙනු කරනු ලැබේ. ඇසුරුමේ ඇත්තේ කාඩ්පත් තුනක් පමණක් බැවින් එක් කාඩ්පතක් ඉතිරි වේ. ඒස් කිං සහ රැජින සහ කිං රැජිනට පහර දෙයි - සාමාන්ය කාඩ්පත් ශ්රේණිගත කිරීමේදී මෙන්.

ක්රීඩකයන්දෙදෙනාම චිප් පෙර (අන්ධ ලෙස ඔට්ටු චිපය). කාඩ්පත් දෙස බැලීමෙන් පසු, පළමු ක්රීඩකයාට චිපය සමත් හෝ ඔට්ටු තැබිය හැකිය. පළමු ක්රීඩකයා සමත් වුවහොත්, ඉහළ කාඩ්පතක් ඇති ක්රීඩකයා බඳුන ජය ගනී. පළමු ක්රීඩකයා ඔට්ටු නම්, දෙවන තරගය ඔට්ටු හැකි (i.e. අමතන්න) චිප් හෝ සමත් (i.e. නමන්න). දෙවන ක්රීඩකයා ඔට්ටු ඇල්ලුවහොත් සහ ඉහළ කාඩ්පත ඇති ක්රීඩකයා බඳුන ජය ගනී. දෙවන ක්රීඩකයා සමත් වුවහොත් (එනම් නැමීම්) පළමු ක්රීඩකයා බඳුන ලබා ගනී. මෙම ක්රීඩාව නැවත නැවතත් ක්රීඩා කරන අතර හොඳ උපාය මාර්ගයක් දිගු කාලීන උපයෝගීතාව (හෝ ජයග්රහණ) සඳහා ප්රශස්තිකරණය කරනු ඇත.

මෙන්නඋදාහරණ ක්රීඩා කිහිපයක්:

  • KAp - ක්රීඩකයා 1 කේ. ක්රීඩකයා 2 ලබා ගනී A. ක්රීඩකයා 1 සමත් වේ. ක්රීඩකයා 2 ඔට්ටු ඇල්ලීමේ අවස්ථාවක් නොලැබෙන අතර ක්රීඩකයා 2 චිප්ස් බඳුන දිනා ගනී.
  • QKbp - ක්රීඩකයා 1 ලබා ගනී Q. ප්ලේයර් 2 කේ ප්ලේයර් 1 චිපයක් ඔට්ටු දමයි. ක්රීඩකයා 2 සමත් වේ (නැමීම්). ක්රීඩකයා 1 නිසා Player 2 නැවී ඇති බඳුනක් ලැබෙන.
  • QAbb - ක්රීඩකයා 1 Q Player 2 ලබා ගනී A. ක්රීඩකයා 1 චිපයක් ඔට්ටු ඇල්ලීම. ක්රීඩකයා 2 ද ඔට්ටු (ඇමතුම්). ක්රීඩකයා 2 බඳුන ජය ගනී .

ඔහුඅපි කුන් පෝකර් විශේෂතා __init__.py සමඟ අර්ථ දක්වා ඇති InfoSet History පන්තිය සහ පන්තිය දීර් extend කරමු.

Open In Colab View Run

38from typing import List, cast, Dict
39
40import numpy as np
41
42from labml import experiment
43from labml.configs import option
44from labml_nn.cfr import History as _History, InfoSet as _InfoSet, Action, Player, CFRConfigs
45from labml_nn.cfr.infoset_saver import InfoSetSaver

කූන්පෝකර් ක්රියාවන් සමත් වේ (p ) හෝ ඔට්ටු (b )

48ACTIONS = cast(List[Action], ['p', 'b'])

නාට්යයේකාඩ්පත් තුන වන්නේ ඒස්, කිං සහ රැජින

50CHANCES = cast(List[Action], ['A', 'K', 'Q'])

ක්රීඩකයන්දෙදෙනෙක් සිටිති

52PLAYERS = cast(List[Player], [0, 1])
55class InfoSet(_InfoSet):

ඉතිරිකිරීමට/බරට සහාය නොදක්වයි

60    @staticmethod
61    def from_dict(data: Dict[str, any]) -> 'InfoSet':
63        pass

ක්රියාලැයිස්තුව ආපසු ලබා දෙන්න. පර්යන්ත තත්වයන් හසුරුවනු ලබන්නේ History පන්තිය විසිනි.

65    def actions(self) -> List[Action]:
69        return ACTIONS

මානවකියවිය හැකි නූල් නිරූපණය - එය ඔට්ටු ඇල්ලීමේ සම්භාවිතාව ලබා දෙයි

71    def __repr__(self):
75        total = sum(self.cumulative_strategy.values())
76        total = max(total, 1e-6)
77        bet = self.cumulative_strategy[cast(Action, 'b')] / total
78        return f'{bet * 100: .1f}%'

ඉතිහාසය

ක්රීඩාවක්අවසන් වූ විට මෙය අර්ථ දක්වයි, උපයෝගීතාව සහ නියැදි අවස්ථා සිදුවීම් ගණනය කරයි (ගනුදෙනු කාඩ්පත්).

ඉතිහාසයවැලක් තුළ ගබඩා කර ඇත:

  • පළමුඅක්ෂර දෙක වන්නේ ක්රීඩකයා 1 සහ ක්රීඩකයා 2 වෙත ගනුදෙනු කරන ලද කාඩ්පත් ය
  • තෙවනචරිතය පළමු ක්රීඩකයාගේ ක්රියාවයි
  • සිව්වනචරිතය දෙවන ක්රීඩකයාගේ ක්රියාවයි
81class History(_History):

ඉතිහාසය

95    history: str

දීඇති ඉතිහාස නූලක් සමඟ ආරම්භ කරන්න

97    def __init__(self, history: str = ''):
101        self.history = history

ඉතිහාසයපර්යන්තය වේවා (ක්රීඩාව අවසන්).

103    def is_terminal(self):

ක්රීඩකයින්තවමත් ක්රියාමාර්ග ගෙන නොමැත

108        if len(self.history) <= 2:
109            return False

ක්රීඩාකිරීමට අවසන් ක්රීඩකයා සමත් විය (ක්රීඩාව අවසන්)

111        elif self.history[-1] == 'p':
112            return True

දෙකමක්රීඩකයන් කැඳවා (ඔට්ටු) (ක්රීඩාව අවසන්)

114        elif self.history[-2:] == 'bb':
115            return True

වෙනත්ඕනෑම සංයෝජනයක්

117        else:
118            return False

ක්රීඩකයාසඳහා පර්යන්ත උපයෝගීතාව ගණනය කරන්න ,

120    def _terminal_utility_p1(self) -> float:

ක්රීඩකයා 1 ට වඩා හොඳ කාඩ්පතක් තිබේ නම් සහ වෙනත් ආකාරයකින්

125        winner = -1 + 2 * (self.history[0] < self.history[1])

දෙවනක්රීඩකයා සමත් විය

128        if self.history[-2:] == 'bp':
129            return 1

ක්රීඩකයන්දෙදෙනාම කැඳවනු ලැබේ, වඩා හොඳ කාඩ්පතක් ඇති ක්රීඩකයා චිප්ස් දිනා ගනී

131        elif self.history[-2:] == 'bb':
132            return winner * 2

පළමුක්රීඩකයා සමත් විය, වඩා හොඳ කාඩ්පතක් ඇති ක්රීඩකයා චිපය දිනා ගනී

134        elif self.history[-1] == 'p':
135            return winner

ඉතිහාසයපර්යන්ත නොවන

137        else:
138            raise RuntimeError()

ක්රීඩකයාසඳහා පර්යන්ත උපයෝගීතාව ලබා ගන්න

140    def terminal_utility(self, i: Player) -> float:

ක්රීඩකයා නම් 1

145        if i == PLAYERS[0]:
146            return self._terminal_utility_p1()

එසේනොමැති නම්

148        else:
149            return -1 * self._terminal_utility_p1()

පළමුසිදුවීම් දෙක වන්නේ කාඩ්පත් ගනුදෙනු කිරීමයි; එනම් අහම්බෙන් සිදුවීම්

151    def is_chance(self) -> bool:
155        return len(self.history) < 2

ඉතිහාසයටක්රියාවක් එක් කර නව ඉතිහාසයක් නැවත ලබා දෙන්න

157    def __add__(self, other: Action):
161        return History(self.history + other)

වත්මන්ක්රීඩකයා

163    def player(self) -> Player:
167        return cast(Player, len(self.history) % 2)

අවස්ථාවක්ලබා ගන්න

169    def sample_chance(self) -> Action:
173        while True:

අහඹුලෙස කාඩ්පතක් තෝරන්න

175            r = np.random.randint(len(CHANCES))
176            chance = CHANCES[r]

කාඩ්පතකලින් ගනුදෙනු කර ඇත්දැයි බලන්න

178            for c in self.history:
179                if c == chance:
180                    chance = None
181                    break

පෙරගනුදෙනු නොකළේ නම් කාඩ්පත ආපසු ලබා දෙන්න

184            if chance is not None:
185                return cast(Action, chance)

මානවකියවිය හැකි නිරූපණය

187    def __repr__(self):
191        return repr(self.history)

තොරතුරුවත්මන් ඉතිහාසය සඳහා ප්රධාන කට්ටලයක්. මෙය වර්තමාන ක්රීඩකයාට පමණක් පෙනෙන ක්රියා වැලක් වේ.

193    def info_set_key(self) -> str:

වත්මන්ක්රීඩකයා ලබා ගන්න

199        i = self.player()

වත්මන්ක්රීඩකයා ඇගේ කාඩ්පත සහ ඔට්ටු ඇල්ලීමේ ක්රියාවන් දකී

201        return self.history[i] + self.history[2:]
203    def new_info_set(self) -> InfoSet:

නවතොරතුරු කට්ටලයක් වස්තුවක් සාදන්න

205        return InfoSet(self.info_set_key())

හිස්ඉතිහාස වස්තුවක් නිර්මාණය කිරීමේ කාර්යයක්

208def create_new_history():
210    return History()

වින්යාසයන්CFR වින්යාස කිරීමේ පන්තිය පුළුල් කරයි

213class Configs(CFRConfigs):
217    pass

කූන්පෝකර් සඳහා create_new_history ක්රමය සකසන්න

220@option(Configs.create_new_history)
221def _cnh():
225    return create_new_history

අත්හදාබැලීම ක්රියාත්මක කරන්න

228def main():

අත්හදාබැලීමක් සාදන්න, අපි ලියන්නේ දේවල් වේගවත් sqlite කිරීම සඳහා ලුහුබැඳීමේ තොරතුරු පමණි. ඇල්ගොරිතම වේගයෙන් පුනරාවර්තනය වන අතර අපි එක් එක් පුනරාවර්තනයේ දත්ත නිරීක්ෂණය කරන බැවින්, ටෙන්සෝර්බෝඩ් වැනි වෙනත් ගමනාන්ත වෙත ලිවීම සාපේක්ෂව කාලය ගත කළ හැකිය. SQLite අපගේ විශ්ලේෂණ සඳහා ප්රමාණවත් වේ.

237    experiment.create(name='kuhn_poker', writers={'sqlite'})

වින්යාසයආරම්භ කරන්න

239    conf = Configs()

පැටවීමවින්යාස

241    experiment.configs(conf)

ඉතිරිකිරීම සඳහා ආකෘති සකසන්න

243    experiment.add_model_savers({'info_sets': InfoSetSaver(conf.cfr.info_sets)})

අත්හදාබැලීම ආරම්භ කරන්න

245    with experiment.start():

නැවතආරම්භ කරන්න

247        conf.cfr.iterate()

251if __name__ == '__main__':
252    main()