මෙයකුහ්න් පෝකර් වෙත ප්රතිවිරුද්ධ කනගාටුව අවම කිරීම (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 කරමු.
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}%'ක්රීඩාවක්අවසන් වූ විට මෙය අර්ථ දක්වයි, උපයෝගීතාව සහ නියැදි අවස්ථා සිදුවීම් ගණනය කරයි (ගනුදෙනු කාඩ්පත්).
ඉතිහාසයවැලක් තුළ ගබඩා කර ඇත:
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_history228def 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()