Upload 2 files
Browse files- dreamteam.py +201 -0
- main.py +56 -0
dreamteam.py
ADDED
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python3
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
"""
|
4 |
+
Created on Sat Apr 20 02:58:47 2019
|
5 |
+
|
6 |
+
@author: ManishChalana
|
7 |
+
"""
|
8 |
+
|
9 |
+
import numpy as np
|
10 |
+
import collections
|
11 |
+
import pandas as pd
|
12 |
+
|
13 |
+
|
14 |
+
|
15 |
+
class Team:
|
16 |
+
def __init__(self, players, teams):
|
17 |
+
self.players = players
|
18 |
+
self.team1 = teams[0]
|
19 |
+
self.team2 = teams[1]
|
20 |
+
numPlayers = collections.Counter([player['team'] for player in self.players])
|
21 |
+
assert list(numPlayers.values())==[11,11], "Invalid combination! Number of players in " + self.team1 + ": " + str(numPlayers[self.team1]) + "," + self.team2 + ": " + str(numPlayers[self.team2])
|
22 |
+
|
23 |
+
|
24 |
+
class Dream11(Team):
|
25 |
+
|
26 |
+
def __init__(self, players, teams):
|
27 |
+
super().__init__(players, teams)
|
28 |
+
self.teamParams = {'min':4, 'max':7}
|
29 |
+
self.maxPoints = 100
|
30 |
+
self.combinations = [[1,3,2,5], [1,3,3,4], [1,4,1,5], [1,4,2,4], [1,4,3,3], [1,5,1,4], [1,5,2,3]]
|
31 |
+
# self.combinationsProb = [0.14]*6 + [0.16]
|
32 |
+
# self.combinationsProb = [0.1,0.2,0.05,0.2,0.3,0.05,0.1]
|
33 |
+
self.playerNames = [p['name'] for p in players]
|
34 |
+
self.playerPointMap = {p['name']:p['points'] for p in self.players}
|
35 |
+
self.playerTeamMap = {p['name']:p['team'] for p in self.players}
|
36 |
+
self.playerTypeMap = {p['name']:p['type'] for p in self.players}
|
37 |
+
self.playerTypeCount = collections.Counter(self.playerTypeMap.values())
|
38 |
+
|
39 |
+
@staticmethod
|
40 |
+
def getSoftmaxProbabilities(points, toneDownMultiplier=1):
|
41 |
+
if len(points) == 0:
|
42 |
+
return []
|
43 |
+
points = [toneDownMultiplier*point for point in points]
|
44 |
+
denom = np.sum([np.exp(point) for point in points])
|
45 |
+
softMax = [np.exp(point)/denom for point in points]
|
46 |
+
return softMax
|
47 |
+
|
48 |
+
|
49 |
+
def sample(self, players, req):
|
50 |
+
numStars = np.sum([p['star'] for p in players])
|
51 |
+
|
52 |
+
availableStars = [p['name'] for p in players if p['star']==1]
|
53 |
+
availableStarsPoints = [p['points'] for p in players if p['star']==1]
|
54 |
+
availableStarsSoftMax = Dream11.getSoftmaxProbabilities(availableStarsPoints)
|
55 |
+
|
56 |
+
availableNonStars = [p['name'] for p in players if not(p['star']==1)]
|
57 |
+
availableNonStarsPoints = [p['points'] for p in players if not(p['star']==1)]
|
58 |
+
availableNonStarsSoftMax = Dream11.getSoftmaxProbabilities(availableNonStarsPoints)
|
59 |
+
|
60 |
+
if numStars >= req:
|
61 |
+
return ([] if len(availableStars)==0 else list(np.random.choice(availableStars, size = req, p=availableStarsSoftMax, replace=False)))
|
62 |
+
else:
|
63 |
+
return availableStars + list(np.random.choice(availableNonStars, size = req - numStars, p=availableNonStarsSoftMax, replace=False))
|
64 |
+
|
65 |
+
def calculateTeamVector(self, team):
|
66 |
+
teamVector = [player['points'] if (player['name'] in team) else 0 for player in self.players]
|
67 |
+
return teamVector
|
68 |
+
|
69 |
+
def checkUniqueTeamCriteria(self, sampledTeam, selectedTeams):
|
70 |
+
return (np.sum([set(team)==set(sampledTeam) for team in selectedTeams]) == 0)
|
71 |
+
|
72 |
+
def checkMinPlayersTeamCriteria(self, teamDemography):
|
73 |
+
return (teamDemography[self.team1]>=self.teamParams['min']) and (teamDemography[self.team2]>=self.teamParams['min'])
|
74 |
+
|
75 |
+
def checkMaxPlayersTeamCriteria(self, teamDemography):
|
76 |
+
return (teamDemography[self.team1]<=self.teamParams['max']) and (teamDemography[self.team2]<=self.teamParams['max'])
|
77 |
+
|
78 |
+
def checkMaxTeamPointsCriteria(self, sampledTeam):
|
79 |
+
totalPoints = np.sum([self.playerPointMap[player] for player in sampledTeam])
|
80 |
+
return (totalPoints <= self.maxPoints)
|
81 |
+
|
82 |
+
def checkSimilarityIndexCriteria(self, sampledTeam, selectedTeams, selected, thresh=24):
|
83 |
+
|
84 |
+
similarityIndexCriteria = False
|
85 |
+
similarityIndices = []
|
86 |
+
|
87 |
+
if selected>0:
|
88 |
+
similarityIndices = [np.sqrt(np.sum(np.square(np.array(self.calculateTeamVector(sampledTeam)) - np.array(self.calculateTeamVector(team))))) for team in selectedTeams]
|
89 |
+
if np.min(similarityIndices) > thresh:
|
90 |
+
similarityIndexCriteria = True
|
91 |
+
else:
|
92 |
+
similarityIndexCriteria = True
|
93 |
+
return similarityIndices, similarityIndexCriteria
|
94 |
+
|
95 |
+
def chooseCaptain(self, sampledTeam, captain):
|
96 |
+
[c, vc] = ['', '']
|
97 |
+
if captain:
|
98 |
+
sampledTeamSoftmax = [self.playerPointMap[name] for name in sampledTeam]
|
99 |
+
[c, vc] = np.random.choice(sampledTeam, size=2, replace=False, p=Dream11.getSoftmaxProbabilities(sampledTeamSoftmax, toneDownMultiplier=0.75))
|
100 |
+
|
101 |
+
return [c, vc]
|
102 |
+
|
103 |
+
def updateSelectedTeams(self, sampledTeam, selectedTeams, selected, captain):
|
104 |
+
#Finding the numbers of wks, bats, ar and bowls in the sampled team
|
105 |
+
teamDemography = collections.Counter([self.playerTeamMap[player] for player in sampledTeam])
|
106 |
+
|
107 |
+
# Finding the total number of points spent in selecting the sampled team and ensuring that it is less than maximum available points
|
108 |
+
pointsCriteria = self.checkMaxTeamPointsCriteria(sampledTeam)
|
109 |
+
|
110 |
+
# Ensuring that sampled team is not same as one of the previously selected teams
|
111 |
+
uniqueTeamCriteria = self.checkUniqueTeamCriteria(sampledTeam, selectedTeams)
|
112 |
+
|
113 |
+
# Making sure that minimum required players are selected in sampled team from each of the two parent teams
|
114 |
+
minPlayersCriteria = self.checkMinPlayersTeamCriteria(teamDemography)
|
115 |
+
|
116 |
+
# Making sure that maximum required players are selected in sampled team from each of the two parent teams
|
117 |
+
maxPlayersCriteria = self.checkMaxPlayersTeamCriteria(teamDemography)
|
118 |
+
|
119 |
+
# Calculating the similarity index of the sampled team with the already selected teams to ensure dissimilarity
|
120 |
+
similarityIndices, similarityIndexCriteria = self.checkSimilarityIndexCriteria(sampledTeam, selectedTeams, selected)
|
121 |
+
|
122 |
+
# Choosing a captain and vice captain
|
123 |
+
[c, vc] = self.chooseCaptain(sampledTeam, captain)
|
124 |
+
|
125 |
+
if pointsCriteria and uniqueTeamCriteria and minPlayersCriteria and maxPlayersCriteria and similarityIndexCriteria:
|
126 |
+
|
127 |
+
# When all criterias are fulfilled by the team, append the sampled team to list of already selected teams
|
128 |
+
selectedTeams.append(sampledTeam)
|
129 |
+
selected = selected + 1
|
130 |
+
|
131 |
+
self.printTeamDetails(sampledTeam, selected, c, vc, similarityIndices)
|
132 |
+
|
133 |
+
# Finding the attributes of the selected team
|
134 |
+
|
135 |
+
return selectedTeams, selected
|
136 |
+
|
137 |
+
|
138 |
+
def printTeamDetails(self, sampledTeam, index, c, vc, similarityIndices):
|
139 |
+
|
140 |
+
selectedPlayersNames = [name.upper() for name in sampledTeam]
|
141 |
+
selectedPlayersPoints = [[p for p in self.players if p['name']==name][0]['points'] for name in sampledTeam]
|
142 |
+
selectedPlayersTeams = [[p for p in self.players if p['name']==name][0]['team'].upper() for name in sampledTeam]
|
143 |
+
selectedPlayersTypes = [[p for p in self.players if p['name']==name][0]['type'] for name in sampledTeam]
|
144 |
+
selectedPlayersCVC = ['c' if name==c else 'vc' if name==vc else ' ' for name in sampledTeam ]
|
145 |
+
selectedPlayersTypesCounter = collections.Counter(selectedPlayersTypes)
|
146 |
+
selectedPlayersTeamsCounter = collections.Counter(selectedPlayersTeams)
|
147 |
+
|
148 |
+
# Defining a dataframe containing the details of sampled team
|
149 |
+
teamDf = pd.DataFrame({'Player': selectedPlayersNames, 'C/VC': selectedPlayersCVC, 'Points':selectedPlayersPoints, 'Team':selectedPlayersTeams, 'Type':selectedPlayersTypes}, index=range(1,12))[['Player', 'C/VC', 'Team', 'Type', 'Points']]
|
150 |
+
teamDf = pd.concat([teamDf[teamDf['Type']==playType].sort_values(['Points'], ascending=False) for playType in ['wk', 'bat', 'ar', 'bowl']])
|
151 |
+
teamDf.index = range(1,12)
|
152 |
+
|
153 |
+
# Printing the team on console
|
154 |
+
print("------------ Team", index, "------------\n")
|
155 |
+
print(teamDf)
|
156 |
+
print("\nTotal points invested:", np.sum(teamDf['Points']))
|
157 |
+
print("Wicket-keepers:", selectedPlayersTypesCounter['wk'], ", Batsman:", selectedPlayersTypesCounter['bat'], ", All-rounders:", selectedPlayersTypesCounter['ar'], " Bowlers:", selectedPlayersTypesCounter['bowl'])
|
158 |
+
print(self.team1.upper(), ":", selectedPlayersTeamsCounter[self.team1.upper()], self.team2.upper(), ":", selectedPlayersTeamsCounter[self.team2.upper()])
|
159 |
+
print("Similarity indices:", similarityIndices)
|
160 |
+
print('\n')
|
161 |
+
|
162 |
+
|
163 |
+
|
164 |
+
|
165 |
+
def generateTeams(self, numTeams, captain=False):
|
166 |
+
selectedTeams = []
|
167 |
+
selected = 0
|
168 |
+
|
169 |
+
while selected < numTeams:
|
170 |
+
# Choose a random combination of number of wicket-keepers, batsman, all-rounders and bowlers
|
171 |
+
while True:
|
172 |
+
[numWks, numBats, numArs, numBowls] = self.combinations[np.random.choice(len(self.combinations), size=1)[0]]
|
173 |
+
if (numWks <= self.playerTypeCount['wk']) and (numBats <=self.playerTypeCount['bat']) and (numArs <=self.playerTypeCount['ar']) and (numBowls<=self.playerTypeCount['bowl']):
|
174 |
+
break
|
175 |
+
|
176 |
+
# Choose Keepers
|
177 |
+
wks = self.sample([p for p in self.players if p['type']=='wk'], numWks)
|
178 |
+
|
179 |
+
# Choose batsman
|
180 |
+
bats = self.sample([p for p in self.players if p['type']=='bat'], numBats)
|
181 |
+
|
182 |
+
# Choose all-rounders
|
183 |
+
ars = self.sample([p for p in self.players if p['type']=='ar'], numArs)
|
184 |
+
|
185 |
+
# Choose bowlers
|
186 |
+
bowls = self.sample([p for p in self.players if p['type']=='bowl'], numBowls)
|
187 |
+
|
188 |
+
# Chosen team
|
189 |
+
sampledTeam = wks + bats + ars + bowls
|
190 |
+
|
191 |
+
# Update selected teams list based on whether the sampled team fulfills all eligibility criteria
|
192 |
+
selectedTeams, selected = self.updateSelectedTeams(sampledTeam, selectedTeams, selected, captain)
|
193 |
+
|
194 |
+
|
195 |
+
|
196 |
+
|
197 |
+
|
198 |
+
|
199 |
+
|
200 |
+
|
201 |
+
|
main.py
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
|
3 |
+
|
4 |
+
|
5 |
+
|
6 |
+
bat = 'bat'
|
7 |
+
bowl = 'bowl'
|
8 |
+
wk = 'wk'
|
9 |
+
ar = 'ar'
|
10 |
+
|
11 |
+
|
12 |
+
t1 = 'srh'
|
13 |
+
t2 = 'kkr'
|
14 |
+
numOfTeams = 8
|
15 |
+
|
16 |
+
# ('player name', 'player role', 'player points in dream11 app', 'player team', 'star player i.e. identifier to denote whether must be included in the team or not (if star =1, player will be included in the team)')
|
17 |
+
|
18 |
+
p1 = {'name': 'J Bairstow', 'type':wk, 'points':10 , 'team': t1, 'star':1}#
|
19 |
+
p2 = {'name': 'D Warner', 'type':bat, 'points': 11, 'team': t1, 'star':1}#
|
20 |
+
p3 = {'name': 'Y Pathan', 'type':bat, 'points': 8, 'team': t1, 'star':0}#
|
21 |
+
p4 = {'name': 'M Pandey', 'type':bat, 'points': 8.5, 'team': t1, 'star':0}#
|
22 |
+
p5 = {'name': 'V Shankar', 'type':ar, 'points': 8.5, 'team': t1, 'star':0}#
|
23 |
+
p6 = {'name': 'S Al Hasan', 'type':ar, 'points': 8.5, 'team': t1, 'star':0}#
|
24 |
+
p7 = {'name': 'D Hooda', 'type':bat, 'points': 8, 'team': t1, 'star':0}#
|
25 |
+
p8 = {'name': 'Rashid Khan', 'type':bowl, 'points': 9, 'team': t1, 'star':0}#
|
26 |
+
p9 = {'name': 'Bhuvi', 'type':bowl, 'points': 8.5, 'team': t1, 'star':0}#
|
27 |
+
p10 = {'name': 'S Sharma', 'type':bowl, 'points': 8.5, 'team': t1, 'star':0}#
|
28 |
+
p11 = {'name': 'S Kaul', 'type':bowl, 'points': 8.5, 'team': t1, 'star':0}#
|
29 |
+
|
30 |
+
|
31 |
+
p12 = {'name': 'C lynn', 'type':bat, 'points': 9.5, 'team': t2, 'star':0}#
|
32 |
+
p13 = {'name': 'N Rana', 'type':bat, 'points': 9, 'team': t2, 'star':0}#
|
33 |
+
p14 = {'name': 'R Uthappa', 'type':bat, 'points': 9, 'team': t2, 'star':0}#
|
34 |
+
p15 = {'name': 'D Karthik', 'type':wk, 'points': 9, 'team': t2, 'star':0}#
|
35 |
+
p16 = {'name': 'S Gill', 'type':bat, 'points': 8, 'team': t2, 'star':0}#
|
36 |
+
p17 = {'name': 'S Narine', 'type':ar, 'points': 9, 'team': t2, 'star':0}#
|
37 |
+
p18 = {'name': 'A Russell', 'type':ar, 'points': 10.5, 'team': t2, 'star':1}#
|
38 |
+
p19 = {'name': 'P Chawla', 'type':bowl, 'points': 8.5, 'team': t2, 'star':0}#
|
39 |
+
p20 = {'name': 'K Yadav', 'type':bowl, 'points': 8.5, 'team': t2, 'star':0}#
|
40 |
+
p21 = {'name': 'L Ferguson', 'type':bowl, 'points': 8.5, 'team': t2, 'star':0}#
|
41 |
+
p22 = {'name': 'P Krishna', 'type':bowl, 'points': 8, 'team': t2, 'star':0}#
|
42 |
+
|
43 |
+
players = [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
|
44 |
+
p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22]
|
45 |
+
teams = [t1, t2]
|
46 |
+
|
47 |
+
from dreamteam import Dream11
|
48 |
+
|
49 |
+
|
50 |
+
if __name__ == '__main__':
|
51 |
+
Dream11(players, teams).generateTeams(numOfTeams, captain=True)
|
52 |
+
|
53 |
+
|
54 |
+
|
55 |
+
|
56 |
+
|