# %% PROJECT_PATH = '/home/md/Work/ligalytics/leagues_stable/' import os, sys sys.path.insert(0, PROJECT_PATH) os.environ.setdefault("DJANGO_SETTINGS_MODULE", "leagues.settings") os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true" import random import time # XPRESS ENVIRONMENT os.environ['XPRESSDIR'] = "/opt/xpressmp_8.4" os.environ['XPRESS'] = "/opt/xpressmp_8.4/bin" os.environ['LD_LIBRARY_PATH'] = os.environ['XPRESSDIR']+"/lib:"+os.environ['LD_LIBRARY_PATH'] os.environ['DYLD_LIBRARY_PATH'] = os.environ['XPRESSDIR']+"/lib:" os.environ['SHLIB_PATH'] = os.environ['XPRESSDIR']+"/lib:" os.environ['LIBPATH'] = os.environ['XPRESSDIR']+"/lib:" # os.environ['PYTHONPATH'] =os.environ['XPRESSDIR']+"/lib:"+os.environ['PYTHONPATH'] os.environ['PYTHONPATH'] =os.environ['XPRESSDIR']+"/lib:" os.environ['CLASSPATH'] =os.environ['XPRESSDIR']+"/lib/xprs.jar:" os.environ['CLASSPATH'] =os.environ['XPRESSDIR']+"/lib/xprb.jar:"+os.environ['CLASSPATH'] os.environ['CLASSPATH'] =os.environ['XPRESSDIR']+"/lib/xprm.jar:"+os.environ['CLASSPATH'] os.environ['PATH'] =os.environ['XPRESSDIR']+"/bin:"+os.environ['PATH'] from leagues import settings settings.DATABASES['default']['NAME'] = PROJECT_PATH+'/db.sqlite3' import django django.setup() from scheduler.models import * from pulp import * import csv import numpy as np import xpress as xp xp.controls.outputlog = 0 scenario = Scenario.objects.get(id=59) # %% order = {} order['FC Bayern München'] = 1 order['Manchester City FC'] = 2 order['Liverpool FC'] = 3 order['Real Madrid CF'] = 4 order['Chelsea FC'] = 5 order['FC Barcelona'] = 6 order['Paris Saint-Germain'] = 7 order['Juventus'] = 8 order['Club Atlético de Madrid'] = 9 order['Sevilla FC'] = 10 order['RB Leipzig'] = 11 order['Tottenham Hotspur'] = 12 order['AFC Ajax'] = 13 order['FC Porto'] = 14 order['Arsenal FC'] = 15 order['Borussia Dortmund'] = 16 order['FC Salzburg'] = 17 order['FC Shakhtar Donetsk'] = 18 order['FC Internazionale Milano'] = 19 order['SSC Napoli'] = 20 order['Eintracht Frankfurt'] = 21 order['SL Benfica'] = 22 order['Sporting Clube de Portugal'] = 23 order['Bayer 04 Leverkusen'] = 24 order['Rangers FC'] = 25 order['GNK Dinamo'] = 26 order['FK Crvena zvezda'] = 27 order['Olympique de Marseille'] = 28 order['F.C. Copenhagen'] = 29 order['Club Brugge'] = 30 order['AC Milan'] = 31 order['PSV Eindhoven'] = 32 order['Celtic FC'] = 33 order['FC Viktoria Plzeň'] = 34 order['AS Monaco'] = 35 order['Maccabi Haifa FC'] = 36 # %% teams = Team.objects.filter(season=scenario.season,active=True).order_by('pot','country') countries = list(set(list(teams.values_list('country', flat=True)))) #print(countries) # %% getTeamByID = { t.id:t for t in teams } getPotByID = { t.id:t.pot for t in teams } getTeamByName = { t.name:t for t in teams } getCountryByTeamID = { t.id:t.country for t in teams } played_countries = { (t1, c):0 for c in countries for t1 in teams } stats = { (t1,t2):0 for t1 in teams for t2 in teams } random_stats = { (t1,t2):0 for t1 in teams for t2 in teams } pots = { t1:{ p:0 for p in range(1,5) } for t1 in teams } simulations_2c = 0 simulations_3c = 0 maxVal = 1 minVal = 99999999 maxCVal = 1 minCVal = 9999999 drawpositions = range(1,10) positions = range(8) nOpponents_3country = {} nConflicts_3country = {} for t in teams: for p in positions: for d in drawpositions: nOpponents_3country[(t.id,p,d)] = [] nConflicts_3country[(t.id,p,d)] = [] old_c = "START" with open('draw_options_noHA_3country.csv', newline='') as csvfile: # with open('verteilung_random.csv', newline='') as csvfile: reader = csv.reader(csvfile) next(reader, None) for row in reader: if int(row[0]) != old_c: old_c = int(row[0]) simulations_3c +=1 team = int(row[1]) drawpos = ((int(row[2])-1) % 9) + 1 pos = 0 for p in row[4].split(";"): if p != "None": nOpponents_3country[(team,pos,drawpos)].append(int(p)) else: nOpponents_3country[(team,pos,drawpos)].append(0) pos += 1 pos = 0 for p in row[5].split(";"): if p != "None" and len(nOpponents_3country[(team,pos,drawpos)]) > 0: nConflicts_3country[(team,pos,drawpos)].append(int(p)) else: nConflicts_3country[(team,pos,drawpos)].append(0) pos += 1 for key in nOpponents_3country.keys(): nOpponents_3country[key] = round(np.mean(nOpponents_3country[key]),2) if nOpponents_3country[key] else "---" for key in nConflicts_3country.keys(): if nOpponents_3country[key] == "---": nConflicts_3country[key] = "---" else: nConflicts_3country[key] = round(np.mean(nConflicts_3country[key])*100) if nConflicts_3country[key] else 0 nOpponents_2country = {} nConflicts_2country = {} for t in teams: for p in positions: for d in drawpositions: nOpponents_2country[(t.id,p,d)] = [] nConflicts_2country[(t.id,p,d)] = [] old_c = "START" with open('draw_options_noHA_2country.csv', newline='') as csvfile: # with open('verteilung_random.csv', newline='') as csvfile: reader = csv.reader(csvfile) next(reader, None) for row in reader: if int(row[0]) != old_c: old_c = int(row[0]) simulations_2c +=1 team = int(row[1]) drawpos = ((int(row[2])-1) % 9) + 1 pos = 0 for p in row[4].split(";"): if p != "None": nOpponents_2country[(team,pos,drawpos)].append(int(p)) else: nOpponents_2country[(team,pos,drawpos)].append(0) pos += 1 pos = 0 for p in row[5].split(";"): if p != "None" and len(nOpponents_2country[(team,pos,drawpos)]) > 0: nConflicts_2country[(team,pos,drawpos)].append(int(p)) else: nConflicts_2country[(team,pos,drawpos)].append(0) pos += 1 for key in nOpponents_2country.keys(): nOpponents_2country[key] = round(np.mean(nOpponents_2country[key]),2) if nOpponents_2country[key] else "---" for key in nConflicts_2country.keys(): if nOpponents_2country[key] == "---": nConflicts_2country[key] = "---" else: nConflicts_2country[key] = round(np.mean(nConflicts_2country[key])*100) if nConflicts_2country[key] else 0 # %% diff = {} mindval = 999999 maxdval = 0 for key in nOpponents_2country.keys(): diff[key] = nOpponents_2country[key] - nOpponents_3country[key] if diff[key] > maxdval: maxdval = diff[key] if diff[key] < mindval: mindval = diff[key] tmpdval = maxdval maxdval = -mindval mindval = -tmpdval diff2 = {} mind2val = 999999 maxd2val = 0 for key in nOpponents_2country.keys(): diff2[key] = nConflicts_2country[key] - nConflicts_3country[key] if diff2[key] > maxd2val: maxd2val = diff[key] if diff2[key] < mind2val: mind2val = diff2[key] maxd2val = 100 mind2val = 0 for key, val in stats.items(): if val > 0 and val < minVal: minVal = val print(maxd2val) print(mind2val) for key, val in played_countries.items(): if val > 0 and val < minCVal: minCVal = val # for t in pots: # print(t,pots[t]) def heatmap_color_for(value): if value <= 0.5: g = 256 r = 2 * max(0,value) * 256 if value > 0.5: g = 2*(1-min(1,value))*256 r = 256 return f"rgb({r},{g},{0})" sol = '' sol += " \ \ " sol += "" sol += "

Number of draw options - undirected

" sol += "Draw Principle: Pot by Pot teams are randomly selected and drawn against 2 opponents from each pot. The draw is undirected, that means home-/awaygames are assigned later during the calendar phase and not during the draw." sol += "During the draw it will happen, that a chosen team is already assigned for one or even two games from the same pot. In this case only as much opponents will be drawn until the team has two opponents from all pots.
" sol += "" sol += "Each options data is based on approximately 5000 random draws. The data is split into pots and into the order of when a team is chosen during the draw (#1 = first team during the draw, #9 = last team during the draw). " sol += "" sol += "
" sol += "

Table 1: At most 3 teams from same country

" sol += "\n" sol += "\n" sol += "" sol += "\n" sol += "" sol += "" sol += "" sol += "" sol += "" sol += "\n" sol += f"\n" # for o in order: for t in teams: sol += f"\n" sol += "\n" sol += "\n" for t in teams: sol += f"\n" sol += f"\n" sol += "\n" sol += "\n" sol += "\n" # for o1 in order: potMap = { 0: 'A', 2: 'B', 4: 'C', 6: 'D' } for pot in [0,2,4,6]: sol += "\n" sol += f"" for drawpos in drawpositions: # t1 = getTeamByName[o1] sol += f"" # for o2 in order: for t in teams: for r in range(2): color = 'white' sol += f"" # t2 = getTeamByName[o2] # color = heatmap_color_for((stats[t1,t2]-minVal)/(maxVal-minVal)) # if stats[t1,t2] == 0: # color = 'grey' # val = f"{round(round(stats[t1,t2]/simulations,2)*100)}%" # # val = stats[t1,t2] # sol += f"" sol += "\n" sol += "\n" sol += "\n" sol += "\n" sol += "
Pot#{t.shortname}
{potMap[pot]}{drawpos}{nOpponents_3country[(t.id,pot+r,drawpos)]}{val}
\n" sol += "
\n" sol += "
\n" sol += "
\n" sol += "
" sol += "

Table 2: At most 3 teams from same country

" sol += "\n" sol += "\n" sol += "" # sol += f"\n" sol += "\n" sol += "" sol += "" sol += "" sol += "" sol += "" sol += "\n" sol += f"\n" # for o in order: for t in teams: sol += f"\n" sol += "\n" sol += "\n" for t in teams: sol += f"\n" sol += f"\n" sol += "\n" sol += "\n" sol += "\n" # for o1 in order: potMap = { 0: 'A', 2: 'B', 4: 'C', 6: 'D' } for pot in [0,2,4,6]: sol += "\n" sol += f"" for drawpos in drawpositions: # t1 = getTeamByName[o1] sol += f"" # for o2 in order: for t in teams: for r in range(2): color = 'white' sol += f"" # t2 = getTeamByName[o2] # color = heatmap_color_for((stats[t1,t2]-minVal)/(maxVal-minVal)) # if stats[t1,t2] == 0: # color = 'grey' # val = f"{round(round(stats[t1,t2]/simulations,2)*100)}%" # # val = stats[t1,t2] # sol += f"" sol += "\n" sol += "\n" sol += "\n" sol += "\n" sol += "
Pot#{t.shortname}
{potMap[pot]}{drawpos}{nOpponents_2country[(t.id,pot+r,drawpos)]}{val}
\n" sol += "
\n" sol += "
\n" sol += "
\n" sol += "
" sol += "

Table 3: Difference (moving from 3 teams to 2 teams)

" sol += "A negative value means that there are less draw options for a team if only 2 teams from the same country are allowed. A positive value means the opposite." sol += "\n" sol += "\n" sol += "" # sol += f"\n" sol += "\n" sol += "" sol += "" sol += "" sol += "" sol += "" sol += "\n" sol += f"\n" # for o in order: for t in teams: sol += f"\n" sol += "\n" sol += "\n" for t in teams: sol += f"\n" sol += f"\n" sol += "\n" sol += "\n" sol += "\n" # for o1 in order: potMap = { 0: 'A', 2: 'B', 4: 'C', 6: 'D' } for pot in [0,2,4,6]: sol += "\n" sol += f"" for drawpos in drawpositions: # t1 = getTeamByName[o1] sol += f"" # for o2 in order: for t in teams: for r in range(2): color = 'white' tdiff = round(diff[(t.id,pot+r,drawpos)],2) color = heatmap_color_for((-2*tdiff-mindval)/(maxdval-mindval)) sol += f"" # t2 = getTeamByName[o2] # color = heatmap_color_for((stats[t1,t2]-minVal)/(maxVal-minVal)) # if stats[t1,t2] == 0: # color = 'grey' # val = f"{round(round(stats[t1,t2]/simulations,2)*100)}%" # # val = stats[t1,t2] # sol += f"" sol += "\n" sol += "\n" sol += "\n" sol += "\n" sol += "
Pot#{t.shortname}
{potMap[pot]}{drawpos}{tdiff}{val}
\n" # sol += "
\n" # sol += "
\n" # sol += "
\n" # sol += "

Probability of combinatorial clashes - at most 3 from same country

" # sol += "\n" # sol += "\n" # sol += "" # sol += "\n" # sol += "" # sol += "" # sol += "" # sol += "" # sol += "" # sol += "\n" # sol += f"\n" # # for o in order: # for t in teams: # sol += f"\n" # sol += "\n" # sol += "\n" # for t in teams: # sol += f"\n" # sol += f"\n" # sol += "\n" # sol += "\n" # sol += "\n" # # for o1 in order: # potMap = { # 0: 'A', # 2: 'B', # 4: 'C', # 6: 'D' # } # for pot in [0,2,4,6]: # sol += "\n" # sol += f"" # for drawpos in drawpositions: # # t1 = getTeamByName[o1] # sol += f"" # # for o2 in order: # for t in teams: # for r in range(2): # color = 'white' # if nConflicts_3country[(t.id,pot+r,drawpos)] != "---": # sol += f"" # else: # sol += f"" # # t2 = getTeamByName[o2] # # color = heatmap_color_for((stats[t1,t2]-minVal)/(maxVal-minVal)) # # if stats[t1,t2] == 0: # # color = 'grey' # # val = f"{round(round(stats[t1,t2]/simulations,2)*100)}%" # # # val = stats[t1,t2] # # sol += f"" # sol += "\n" # sol += "\n" # sol += "\n" # sol += "\n" # sol += "
Pot#{t.shortname}
{potMap[pot]}{drawpos}{nConflicts_3country[(t.id,pot+r,drawpos)]}%{nConflicts_3country[(t.id,pot+r,drawpos)]}{val}
\n" # sol += "
\n" # sol += "
\n" # sol += "
\n" # sol += "

Probability of combinatorial clashes - at most 2 from same country

" # sol += "\n" # sol += "\n" # sol += "" # sol += "\n" # sol += "" # sol += "" # sol += "" # sol += "" # sol += "" # sol += "\n" # sol += f"\n" # # for o in order: # for t in teams: # sol += f"\n" # sol += "\n" # sol += "\n" # for t in teams: # sol += f"\n" # sol += f"\n" # sol += "\n" # sol += "\n" # sol += "\n" # # for o1 in order: # potMap = { # 0: 'A', # 2: 'B', # 4: 'C', # 6: 'D' # } # for pot in [0,2,4,6]: # sol += "\n" # sol += f"" # for drawpos in drawpositions: # # t1 = getTeamByName[o1] # sol += f"" # # for o2 in order: # for t in teams: # for r in range(2): # color = 'white' # if nConflicts_2country[(t.id,pot+r,drawpos)] != "---": # sol += f"" # else: # sol += f"" # # t2 = getTeamByName[o2] # # color = heatmap_color_for((stats[t1,t2]-minVal)/(maxVal-minVal)) # # if stats[t1,t2] == 0: # # color = 'grey' # # val = f"{round(round(stats[t1,t2]/simulations,2)*100)}%" # # # val = stats[t1,t2] # # sol += f"" # sol += "\n" # sol += "\n" # sol += "\n" # sol += "\n" # sol += "
Pot#{t.shortname}
{potMap[pot]}{drawpos}{nConflicts_2country[(t.id,pot+r,drawpos)]}%{nConflicts_2country[(t.id,pot+r,drawpos)]}{val}
\n" # sol += "
\n" # sol += "
\n" # sol += "
\n" # sol += "

Probability of combinatorial clashes - Difference 2/3 from same country

" # sol += "\n" # sol += "\n" # sol += "" # sol += "\n" # sol += "" # sol += "" # sol += "" # sol += "" # sol += "" # sol += "\n" # sol += f"\n" # # for o in order: # for t in teams: # sol += f"\n" # sol += "\n" # sol += "\n" # for t in teams: # sol += f"\n" # sol += f"\n" # sol += "\n" # sol += "\n" # sol += "\n" # # for o1 in order: # potMap = { # 0: 'A', # 2: 'B', # 4: 'C', # 6: 'D' # } # for pot in [0,2,4,6]: # sol += "\n" # sol += f"" # for drawpos in drawpositions: # # t1 = getTeamByName[o1] # sol += f"" # # for o2 in order: # for t in teams: # for r in range(2): # color = 'white' # tdiff = round(diff2[(t.id,pot+r,drawpos)],2) # color = heatmap_color_for((tdiff-mind2val)/(maxd2val-mind2val)) # sol += f"" # # t2 = getTeamByName[o2] # # color = heatmap_color_for((stats[t1,t2]-minVal)/(maxVal-minVal)) # # if stats[t1,t2] == 0: # # color = 'grey' # # val = f"{round(round(stats[t1,t2]/simulations,2)*100)}%" # # # val = stats[t1,t2] # # sol += f"" # sol += "\n" # sol += "\n" # sol += "\n" # sol += "\n" # sol += "
Pot#{t.shortname}
{potMap[pot]}{drawpos}{tdiff}%{val}
\n" sol += "" with open(f'undirected_3_vs_2.html', 'w') as f: f.write(sol) # %%