# %%
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 += "- Table 1: Number of draw options if each team is allowed to play at most 3 teams from the same country
"
sol += "- Table 2: Number of draw options if each team is allowed to play at most 2 teams from the same country
"
sol += "- Table 3: Difference of draw options if the number of teams from the same country is reduced from 3 to 2.
"
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 += "\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"| {potMap[pot]} | "
for drawpos in drawpositions:
# t1 = getTeamByName[o1]
sol += f"{drawpos} | "
# for o2 in order:
for t in teams:
for r in range(2):
color = 'white'
sol += f"{nOpponents_3country[(t.id,pot+r,drawpos)]} | "
# 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"{val} | "
sol += "
\n"
sol += "\n"
sol += "
\n"
sol += "\n"
sol += "
\n"
sol += "
\n"
sol += "
\n"
sol += "
\n"
sol += "
"
sol += "Table 2: At most 3 teams from same country
"
sol += "\n"
sol += "\n"
sol += ""
sol += "\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"| {potMap[pot]} | "
for drawpos in drawpositions:
# t1 = getTeamByName[o1]
sol += f"{drawpos} | "
# for o2 in order:
for t in teams:
for r in range(2):
color = 'white'
sol += f"{nOpponents_2country[(t.id,pot+r,drawpos)]} | "
# 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"{val} | "
sol += "
\n"
sol += "\n"
sol += "
\n"
sol += "\n"
sol += "
\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 += "\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"| {potMap[pot]} | "
for drawpos in drawpositions:
# t1 = getTeamByName[o1]
sol += f"{drawpos} | "
# 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"{tdiff} | "
# 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"{val} | "
sol += "
\n"
sol += "\n"
sol += "
\n"
sol += "\n"
sol += "
\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 += "\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"| {potMap[pot]} | "
# for drawpos in drawpositions:
# # t1 = getTeamByName[o1]
# sol += f"{drawpos} | "
# # 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"{nConflicts_3country[(t.id,pot+r,drawpos)]}% | "
# else:
# sol += f"{nConflicts_3country[(t.id,pot+r,drawpos)]} | "
# # 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"{val} | "
# sol += "
\n"
# sol += "\n"
# sol += "
\n"
# sol += "\n"
# sol += "
\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 += "\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"| {potMap[pot]} | "
# for drawpos in drawpositions:
# # t1 = getTeamByName[o1]
# sol += f"{drawpos} | "
# # 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"{nConflicts_2country[(t.id,pot+r,drawpos)]}% | "
# else:
# sol += f"{nConflicts_2country[(t.id,pot+r,drawpos)]} | "
# # 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"{val} | "
# sol += "
\n"
# sol += "\n"
# sol += "
\n"
# sol += "\n"
# sol += "
\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 += "\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"| {potMap[pot]} | "
# for drawpos in drawpositions:
# # t1 = getTeamByName[o1]
# sol += f"{drawpos} | "
# # 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"{tdiff}% | "
# # 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"{val} | "
# sol += "
\n"
# sol += "\n"
# sol += "
\n"
# sol += "\n"
# sol += "
\n"
sol += ""
with open(f'undirected_3_vs_2.html', 'w') as f:
f.write(sol)
# %%