<p>我认为这是处理马尔可夫链的一个好方法。看一看<a href="https://www.datacamp.com/community/tutorials/markov-chains-python-tutorial" rel="nofollow noreferrer">here</a></p>
<p>其基本思想是,对于每个当前状态,都有可能进入下一个状态。您可以创建当前状态的概率矩阵,以及下一个状态的概率。然后使用这些权重从<code>random.choices</code>中拉出。你想怎么复杂就怎么复杂。关键是从简单开始,让它开始工作,然后你可以添加更多并修饰它(例如,我要添加3分未命中和3分命中的状态,(你还必须包括2分未命中、2分命中的概率……或者你可以将其作为投篮未命中和投篮命中的扩展),但我想我会把这留给你去处理,然后加上。你也可以加上进攻和防守犯规,如果是防守投篮犯规,如果射门有助攻的概率,等等。)</p>
<p>这只是一个问题,然后设置一些功能,以保持跟踪的一切和“发挥”了占有</p>
<p>下面是我的例子:</p>
<p><strong>1。为每个团队创建概率矩阵。索引将是当前状态,列是下一个状态。</strong></p>
<p><strong>注意:您希望每行的总和为1</strong></p>
<pre><code>import pandas as pd
import random
prob_matrix_A = pd.DataFrame([
[0, 0.05, 0.1, 0.375, 0.475, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 1],
[0, 0.02, 0, 0, 0, 0.19, 0.79, 0],
[0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0]],
columns = ['Possession', 'Unforced Turnover','Steal','Miss Shot','Made Shot','Off Reb','Def Rebound', 'Change Possession'],
index = ['Possession', 'Unforced Turnover','Steal','Miss Shot','Made Shot','Off Reb','Def Rebound', 'Change Possession'])
prob_matrix_B = pd.DataFrame([
[0, 0.05, 0.1, 0.475, 0.375, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 1],
[0, 0.02, 0, 0, 0, 0.09, 0.89, 0],
[0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0]],
columns = ['Possession', 'Unforced Turnover','Steal','Miss Shot','Made Shot','Off Reb','Def Rebound', 'Change Possession'],
index = ['Possession', 'Unforced Turnover','Steal','Miss Shot','Made Shot','Off Reb','Def Rebound', 'Change Possession'])
</code></pre>
<p>这是A队的概率矩阵:</p>
<pre><code>print (prob_matrix_A.to_string())
Possession Unforced Turnover Steal Miss Shot Made Shot Off Reb Def Rebound Change Possession
Possession 0 0.05 0.1 0.375 0.475 0.00 0.00 0
Unforced Turnover 0 0.00 0.0 0.000 0.000 0.00 0.00 1
Steal 0 0.00 0.0 0.000 0.000 0.00 0.00 1
Miss Shot 0 0.02 0.0 0.000 0.000 0.19 0.79 0
Made Shot 0 0.00 0.0 0.000 0.000 0.00 0.00 1
Off Reb 1 0.00 0.0 0.000 0.000 0.00 0.00 0
Def Rebound 0 0.00 0.0 0.000 0.000 0.00 0.00 1
Change Possession 0 0.00 0.0 0.000 0.000 0.00 0.00 0
</code></pre>
<p><strong>2。设置如何跟踪得分以及哪个队有球:</strong></p>
<pre><code>team_score_limit = 25
# game setup
game_dict = {'team_a':{'score':0, 'possession':False, 'prob_matrix': prob_matrix_A},
'team_b':{'score':0, 'possession':False, 'prob_matrix': prob_matrix_B},
'score_limit':team_score_limit}
# Do a jump ball to see who starts with ball
# Lets say team_a has 55% of getting the jump, and team_b 45%
wins_jump = random.choices(['team_a','team_b'], weights=[.55,.45], k=1)[0]
game_dict[wins_jump]['possession'] = True
print('%s: Wins the jump ball' %wins_jump)
</code></pre>
<p><strong>3。创建功能以确定谁拥有控球权(即谁处于进攻、防守状态):</strong></p>
<pre><code># Function to return who has possession
def possession(game_dict):
for k, v in game_dict.items():
if type(v) == dict:
if v['possession'] == True:
offense_team = k
if v['possession'] == False:
defense_team = k
return offense_team, defense_team
</code></pre>
<p><strong>4。创建函数,根据概率播放控球:</strong></p>
<pre><code>def play(current_state, game_dict):
# Determine who has possession and get their prob matrix
offense, defense = possession(game_dict)
prob_matrix = game_dict[offense]['prob_matrix']
states_list = prob_matrix.columns.tolist()
weights = prob_matrix.loc[current_state,:].tolist()
# Based on current state weights, get the next state
new_state = random.choices(states_list, weights=weights, k=1)[0]
if 'Possession' not in new_state:
if new_state in ['Def Rebound', 'Steal']:
print ('%s: %s by %s' %(offense, new_state, defense))
else:
print ('%s: %s' %(offense, new_state))
current_state = new_state
if current_state == 'Made Shot':
game_dict[offense]['score'] += 2
# if team_a score reached the limit, we'll return False to stop the game
if game_dict['team_a']['score'] >= game_dict['score_limit']:
return False
# if it's a change of possession, we'll update our game_dict
if new_state == 'Change Possession':
game_dict[offense]['possession'] = False
game_dict[defense]['possession'] = True
# else the team who currently possess the ball didn't change from the previous outcome (Ie. Offensive rebound), then they get another possession play
else:
play(current_state, game_dict)
</code></pre>
<p><strong>5。设置初始<code>current_state</code>以开始“游戏”并将其玩完:</strong></p>
<pre><code># Play the first quarter
current_state = 'Possession'
continue_play = True
while continue_play != False:
continue_play = play(current_state, game_dict)
print ('\nEnd of 1st Quarter!\n')
print ('**************************')
print ('team_a: %s\tteam_b: %s' %(game_dict['team_a']['score'],game_dict['team_b']['score']))
</code></pre>
<p><strong>输出:</strong></p>
<pre><code>runfile('test.py', wdir='C:/test')
team_a: Wins the jump ball
team_a: Made Shot
team_b: Miss Shot
team_b: Off Reb
team_b: Made Shot
team_a: Made Shot
team_b: Made Shot
team_a: Miss Shot
team_a: Def Rebound by team_b
team_b: Miss Shot
team_b: Def Rebound by team_a
team_a: Steal by team_b
team_b: Miss Shot
team_b: Def Rebound by team_a
team_a: Miss Shot
team_a: Def Rebound by team_b
team_b: Made Shot
team_a: Miss Shot
team_a: Def Rebound by team_b
team_b: Steal by team_a
team_a: Made Shot
team_b: Made Shot
team_a: Made Shot
team_b: Made Shot
team_a: Made Shot
team_b: Steal by team_a
team_a: Made Shot
team_b: Miss Shot
team_b: Def Rebound by team_a
team_a: Unforced Turnover
team_b: Made Shot
team_a: Steal by team_b
team_b: Made Shot
team_a: Unforced Turnover
team_b: Steal by team_a
team_a: Made Shot
team_b: Unforced Turnover
team_a: Miss Shot
team_a: Off Reb
team_a: Made Shot
team_b: Miss Shot
team_b: Def Rebound by team_a
team_a: Made Shot
team_b: Miss Shot
team_b: Def Rebound by team_a
team_a: Made Shot
team_b: Made Shot
team_a: Made Shot
team_b: Miss Shot
team_b: Def Rebound by team_a
team_a: Miss Shot
team_a: Off Reb
team_a: Made Shot
team_b: Miss Shot
team_b: Def Rebound by team_a
team_a: Made Shot
End of 1st Quarter!
**************************
team_a: 26 team_b: 16
</code></pre>