UEFA Cycle 24
This commit is contained in:
parent
5c3cbfd4a0
commit
bb32c5ab70
8
.gitignore
vendored
8
.gitignore
vendored
@ -160,4 +160,10 @@ cython_debug/
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
|
||||
solver/data/save_point/*
|
||||
solver/data/save_point/*
|
||||
*.json
|
||||
*.csv
|
||||
*.html
|
||||
*.lp
|
||||
*.mps
|
||||
*.pptx
|
||||
|
||||
316
uefa/cycle24/simulations/debugging/conflict.py
Executable file
316
uefa/cycle24/simulations/debugging/conflict.py
Executable file
@ -0,0 +1,316 @@
|
||||
import pulp
|
||||
from pulp import lpSum, XPRESS, GUROBI, PULP_CBC_CMD, XPRESS_PY
|
||||
|
||||
"""
|
||||
##########################################################################################################################
|
||||
##########################################################################################################################
|
||||
"""
|
||||
|
||||
|
||||
teams = [{'id': 3696, 'country': 'FRA', 'pot': 4, 'shortname': 'Lens'},
|
||||
{'id': 3697, 'country': 'GER', 'pot': 4, 'shortname': 'Unio'},
|
||||
{'id': 3698, 'country': 'ENG', 'pot': 4, 'shortname': 'Newc'},
|
||||
{'id': 3699, 'country': 'ESP', 'pot': 4, 'shortname': 'Soci'},
|
||||
{'id': 3700, 'country': 'SUI', 'pot': 3, 'shortname': 'Youn'},
|
||||
{'id': 3701, 'country': 'NED', 'pot': 3, 'shortname': 'Feye'},
|
||||
{'id': 3702, 'country': 'ENG', 'pot': 1, 'shortname': 'ManU'},
|
||||
{'id': 3730, 'country': 'SRB', 'pot': 3, 'shortname': 'Crve'},
|
||||
{'id': 3732, 'country': 'ITA', 'pot': 1, 'shortname': 'Inte'},
|
||||
{'id': 3734, 'country': 'ITA', 'pot': 2, 'shortname': 'Napo'},
|
||||
{'id': 3756, 'country': 'ITA', 'pot': 3, 'shortname': 'Mila'},
|
||||
{'id': 3757, 'country': 'SCO', 'pot': 4, 'shortname': 'Celt'},
|
||||
{'id': 3758, 'country': 'DEN', 'pot': 3, 'shortname': 'Cope'},
|
||||
{'id': 3760, 'country': 'NED', 'pot': 3, 'shortname': 'PSV'},
|
||||
{'id': 3761, 'country': 'ENG', 'pot': 2, 'shortname': 'Arse'},
|
||||
{'id': 3762, 'country': 'ESP', 'pot': 1, 'shortname': 'Sevi'},
|
||||
{'id': 3764, 'country': 'ENG', 'pot': 1, 'shortname': 'Live'},
|
||||
{'id': 3765, 'country': 'UKR', 'pot': 2, 'shortname': 'Shak'},
|
||||
{'id': 3771, 'country': 'ITA', 'pot': 3, 'shortname': 'Atal'},
|
||||
{'id': 3853, 'country': 'FRA', 'pot': 4, 'shortname': 'Mars'},
|
||||
{'id': 3870, 'country': 'TUR', 'pot': 4, 'shortname': 'Gala'},
|
||||
{'id': 3894, 'country': 'ESP', 'pot': 1, 'shortname': 'Barc'},
|
||||
{'id': 3895, 'country': 'ITA', 'pot': 3, 'shortname': 'Lazi'},
|
||||
{'id': 3898, 'country': 'ESP', 'pot': 2, 'shortname': 'Atle'},
|
||||
{'id': 3904, 'country': 'AZE', 'pot': 4, 'shortname': 'Qara'},
|
||||
{'id': 3925, 'country': 'BEL', 'pot': 4, 'shortname': 'Antw'},
|
||||
{'id': 3926, 'country': 'GER', 'pot': 2, 'shortname': 'Leip'},
|
||||
{'id': 3928, 'country': 'POR', 'pot': 3, 'shortname': 'Brag'},
|
||||
{'id': 3930, 'country': 'POR', 'pot': 2, 'shortname': 'Benf'},
|
||||
{'id': 3932, 'country': 'GER', 'pot': 1, 'shortname': 'Baye'},
|
||||
{'id': 3933, 'country': 'ESP', 'pot': 1, 'shortname': 'Real'},
|
||||
{'id': 3935, 'country': 'FRA', 'pot': 1, 'shortname': 'PSG'},
|
||||
{'id': 3936, 'country': 'GER', 'pot': 2, 'shortname': 'Dort'},
|
||||
{'id': 3937, 'country': 'POR', 'pot': 2, 'shortname': 'Port'},
|
||||
{'id': 3938, 'country': 'AUT', 'pot': 2, 'shortname': 'Salz'},
|
||||
{'id': 3940, 'country': 'ENG', 'pot': 1, 'shortname': 'Manc'}]
|
||||
|
||||
getTeamById = {3702: '(ENG) Manchester United FC',
|
||||
3764: '(ENG) Liverpool FC',
|
||||
3940: '(ENG) Manchester City FC',
|
||||
3762: '(ESP) Sevilla FC',
|
||||
3894: '(ESP) FC Barcelona',
|
||||
3933: '(ESP) Real Madrid CF',
|
||||
3935: '(FRA) Paris Saint-Germain',
|
||||
3932: '(GER) FC Bayern München',
|
||||
3732: '(ITA) FC Internazionale Milano',
|
||||
3938: '(AUT) FC Salzburg',
|
||||
3761: '(ENG) Arsenal FC',
|
||||
3898: '(ESP) Club Atlético de Madrid',
|
||||
3926: '(GER) RB Leipzig',
|
||||
3936: '(GER) Borussia Dortmund',
|
||||
3734: '(ITA) SSC Napoli',
|
||||
3930: '(POR) SL Benfica',
|
||||
3937: '(POR) FC Porto',
|
||||
3765: '(UKR) FC Shakhtar Donetsk',
|
||||
3758: '(DEN) F.C. Copenhagen',
|
||||
3756: '(ITA) AC Milan',
|
||||
3771: '(ITA) Atalanta BC',
|
||||
3895: '(ITA) S.S. Lazio',
|
||||
3701: '(NED) Feyenoord',
|
||||
3760: '(NED) PSV Eindhoven',
|
||||
3928: '(POR) SC Braga',
|
||||
3730: '(SRB) FK Crvena zvezda',
|
||||
3700: '(SUI) BSC Young Boys',
|
||||
3904: '(AZE) Qarabağ FK',
|
||||
3925: '(BEL) R. Antwerp FC',
|
||||
3698: '(ENG) Newcastle United FC',
|
||||
3699: '(ESP) Real Sociedad de Fútbol',
|
||||
3696: '(FRA) RC Lens',
|
||||
3853: '(FRA) Olympique de Marseille',
|
||||
3697: '(GER) 1. FC Union Berlin',
|
||||
3757: '(SCO) Celtic FC',
|
||||
3870: '(TUR) Galatasaray A.Ş.'}
|
||||
|
||||
pot = {1: [{'id': 3702, 'country': 'ENG', 'pot': 1, 'shortname': 'ManU'},
|
||||
{'id': 3764, 'country': 'ENG', 'pot': 1, 'shortname': 'Liver'},
|
||||
{'id': 3940, 'country': 'ENG', 'pot': 1, 'shortname': 'Manch'},
|
||||
{'id': 3762, 'country': 'ESP', 'pot': 1, 'shortname': 'Sevil'},
|
||||
{'id': 3894, 'country': 'ESP', 'pot': 1, 'shortname': 'Barce'},
|
||||
{'id': 3933, 'country': 'ESP', 'pot': 1, 'shortname': 'Real '},
|
||||
{'id': 3935, 'country': 'FRA', 'pot': 1, 'shortname': 'PSG'},
|
||||
{'id': 3932, 'country': 'GER', 'pot': 1, 'shortname': 'Bayer'},
|
||||
{'id': 3732, 'country': 'ITA', 'pot': 1, 'shortname': 'Inter'}],
|
||||
2: [{'id': 3938, 'country': 'AUT', 'pot': 2, 'shortname': 'Salzb'},
|
||||
{'id': 3761, 'country': 'ENG', 'pot': 2, 'shortname': 'Arsen'},
|
||||
{'id': 3898, 'country': 'ESP', 'pot': 2, 'shortname': 'Atlét'},
|
||||
{'id': 3926, 'country': 'GER', 'pot': 2, 'shortname': 'Leipz'},
|
||||
{'id': 3936, 'country': 'GER', 'pot': 2, 'shortname': 'Dortm'},
|
||||
{'id': 3734, 'country': 'ITA', 'pot': 2, 'shortname': 'Napol'},
|
||||
{'id': 3930, 'country': 'POR', 'pot': 2, 'shortname': 'Benfi'},
|
||||
{'id': 3937, 'country': 'POR', 'pot': 2, 'shortname': 'Porto'},
|
||||
{'id': 3765, 'country': 'UKR', 'pot': 2, 'shortname': 'Shakh'}],
|
||||
3: [{'id': 3758, 'country': 'DEN', 'pot': 3, 'shortname': 'Copen'},
|
||||
{'id': 3756, 'country': 'ITA', 'pot': 3, 'shortname': 'Milan'},
|
||||
{'id': 3771, 'country': 'ITA', 'pot': 3, 'shortname': 'Atala'},
|
||||
{'id': 3895, 'country': 'ITA', 'pot': 3, 'shortname': 'Lazio'},
|
||||
{'id': 3701, 'country': 'NED', 'pot': 3, 'shortname': 'Feyen'},
|
||||
{'id': 3760, 'country': 'NED', 'pot': 3, 'shortname': 'PSV'},
|
||||
{'id': 3928, 'country': 'POR', 'pot': 3, 'shortname': 'Braga'},
|
||||
{'id': 3730, 'country': 'SRB', 'pot': 3, 'shortname': 'Crven'},
|
||||
{'id': 3700, 'country': 'SUI', 'pot': 3, 'shortname': 'Young'}],
|
||||
4: [{'id': 3904, 'country': 'AZE', 'pot': 4, 'shortname': 'Qarab'},
|
||||
{'id': 3925, 'country': 'BEL', 'pot': 4, 'shortname': 'Antwe'},
|
||||
{'id': 3698, 'country': 'ENG', 'pot': 4, 'shortname': 'Newca'},
|
||||
{'id': 3699, 'country': 'ESP', 'pot': 4, 'shortname': 'Socied'},
|
||||
{'id': 3696, 'country': 'FRA', 'pot': 4, 'shortname': 'Lens'},
|
||||
{'id': 3853, 'country': 'FRA', 'pot': 4, 'shortname': 'Marse'},
|
||||
{'id': 3697, 'country': 'GER', 'pot': 4, 'shortname': 'Union'},
|
||||
{'id': 3757, 'country': 'SCO', 'pot': 4, 'shortname': 'Celti'},
|
||||
{'id': 3870, 'country': 'TUR', 'pot': 4, 'shortname': 'Galat'}]}
|
||||
|
||||
|
||||
teams_from_country = {'NED': [{'id': 3701, 'country': 'NED', 'pot': 3, 'shortname': 'Feye'},
|
||||
{'id': 3760, 'country': 'NED', 'pot': 3, 'shortname': 'PSV'}],
|
||||
'UKR': [{'id': 3765, 'country': 'UKR', 'pot': 2, 'shortname': 'Shak'}],
|
||||
'ENG': [{'id': 3702, 'country': 'ENG', 'pot': 1, 'shortname': 'ManU'},
|
||||
{'id': 3764, 'country': 'ENG', 'pot': 1, 'shortname': 'Live'},
|
||||
{'id': 3940, 'country': 'ENG', 'pot': 1, 'shortname': 'Manc'},
|
||||
{'id': 3761, 'country': 'ENG', 'pot': 2, 'shortname': 'Arse'},
|
||||
{'id': 3698, 'country': 'ENG', 'pot': 4, 'shortname': 'Newc'}],
|
||||
'POR': [{'id': 3930, 'country': 'POR', 'pot': 2, 'shortname': 'Benf'},
|
||||
{'id': 3937, 'country': 'POR', 'pot': 2, 'shortname': 'Port'},
|
||||
{'id': 3928, 'country': 'POR', 'pot': 3, 'shortname': 'Brag'}],
|
||||
'GER': [{'id': 3932, 'country': 'GER', 'pot': 1, 'shortname': 'Baye'},
|
||||
{'id': 3926, 'country': 'GER', 'pot': 2, 'shortname': 'Leip'},
|
||||
{'id': 3936, 'country': 'GER', 'pot': 2, 'shortname': 'Dort'},
|
||||
{'id': 3697, 'country': 'GER', 'pot': 4, 'shortname': 'Unio'}],
|
||||
'DEN': [{'id': 3758, 'country': 'DEN', 'pot': 3, 'shortname': 'Cope'}],
|
||||
'FRA': [{'id': 3935, 'country': 'FRA', 'pot': 1, 'shortname': 'PSG'},
|
||||
{'id': 3696, 'country': 'FRA', 'pot': 4, 'shortname': 'Lens'},
|
||||
{'id': 3853, 'country': 'FRA', 'pot': 4, 'shortname': 'Mars'}],
|
||||
'AZE': [{'id': 3904, 'country': 'AZE', 'pot': 4, 'shortname': 'Qara'}],
|
||||
'TUR': [{'id': 3870, 'country': 'TUR', 'pot': 4, 'shortname': 'Gala'}],
|
||||
'ITA': [{'id': 3732, 'country': 'ITA', 'pot': 1, 'shortname': 'Inte'},
|
||||
{'id': 3734, 'country': 'ITA', 'pot': 2, 'shortname': 'Napo'},
|
||||
{'id': 3756, 'country': 'ITA', 'pot': 3, 'shortname': 'Mila'},
|
||||
{'id': 3771, 'country': 'ITA', 'pot': 3, 'shortname': 'Atal'},
|
||||
{'id': 3895, 'country': 'ITA', 'pot': 3, 'shortname': 'Lazi'}],
|
||||
'BEL': [{'id': 3925, 'country': 'BEL', 'pot': 4, 'shortname': 'Antw'}],
|
||||
'SRB': [{'id': 3730, 'country': 'SRB', 'pot': 3, 'shortname': 'Crve'}],
|
||||
'SUI': [{'id': 3700, 'country': 'SUI', 'pot': 3, 'shortname': 'Youn'}],
|
||||
'SCO': [{'id': 3757, 'country': 'SCO', 'pot': 4, 'shortname': 'Celt'}],
|
||||
'ESP': [{'id': 3762, 'country': 'ESP', 'pot': 1, 'shortname': 'Sevi'},
|
||||
{'id': 3894, 'country': 'ESP', 'pot': 1, 'shortname': 'Barc'},
|
||||
{'id': 3933, 'country': 'ESP', 'pot': 1, 'shortname': 'Real'},
|
||||
{'id': 3898, 'country': 'ESP', 'pot': 2, 'shortname': 'Atle'},
|
||||
{'id': 3699, 'country': 'ESP', 'pot': 4, 'shortname': 'Soci'}],
|
||||
'AUT': [{'id': 3938, 'country': 'AUT', 'pot': 2, 'shortname': 'Salz'}]}
|
||||
|
||||
countries = ['NED',
|
||||
'UKR',
|
||||
'ENG',
|
||||
'POR',
|
||||
'GER',
|
||||
'DEN',
|
||||
'FRA',
|
||||
'AZE',
|
||||
'TUR',
|
||||
'ITA',
|
||||
'BEL',
|
||||
'SRB',
|
||||
'SUI',
|
||||
'SCO',
|
||||
'ESP',
|
||||
'AUT']
|
||||
|
||||
|
||||
"""
|
||||
##########################################################################################################################
|
||||
##########################################################################################################################
|
||||
"""
|
||||
|
||||
|
||||
|
||||
def check_feasible(fixed_games):
|
||||
model = pulp.LpProblem(f"Draws", pulp.LpMinimize)
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
x[t1['id'], t2['id']] = pulp.LpVariable('x_'+str(t1['id'])+'_'+str(t2['id']),lowBound=0, upBound=1, cat=pulp.LpInteger)
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
model += lpSum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1
|
||||
model += lpSum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1
|
||||
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
model += lpSum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
model += x[t1,t2] + x[t2,t1] <= 1
|
||||
|
||||
# FIXATIONS
|
||||
for (t1,t2) in fixed_games:
|
||||
model += x[t1,t2] == 1
|
||||
|
||||
# OBJECTIVE
|
||||
model += lpSum(x[t1,t2] for (t1,t2) in x.keys())
|
||||
solver = XPRESS_PY(msg=1)
|
||||
model.solve(solver)
|
||||
print(XPRESS_PY.getAttribute(None,model,'bestbound'))
|
||||
|
||||
if model.status in [0,-1,-2]:
|
||||
print("INFEASIBLE")
|
||||
return False,x
|
||||
else:
|
||||
print("SUCCESS")
|
||||
return True,x
|
||||
|
||||
|
||||
|
||||
"""
|
||||
##########################################################################################################################
|
||||
##########################################################################################################################
|
||||
"""
|
||||
|
||||
|
||||
|
||||
|
||||
fixed_games = [(3940, 3894), (3933, 3940), (3940, 3937), (3765, 3940), (3940, 3895), (3700, 3940), (3940, 3696),
|
||||
(3925, 3940), (3702, 3935), (3894, 3702), (3702, 3926), (3937, 3702), (3702, 3700), (3758, 3702),
|
||||
(3702, 3699), (3757, 3702), (3932, 3762), (3732, 3932), (3932, 3938), (3761, 3932), (3932, 3730),
|
||||
(3701, 3932), (3932, 3870), (3853, 3932), (3764, 3933), (3935, 3764), (3764, 3936), (3898, 3764),
|
||||
(3764, 3756), (3928, 3764), (3764, 3925), (3904, 3764), (3762, 3732), (3762, 3761), (3930, 3762),
|
||||
(3762, 3701), (3760, 3762), (3762, 3697), (3698, 3762), (3732, 3765), (3926, 3732), (3732, 3928),
|
||||
(3730, 3732), (3732, 3698), (3870, 3732), (3894, 3930), (3938, 3894), (3894, 3758)]
|
||||
|
||||
|
||||
|
||||
|
||||
feasible, sol = check_feasible(fixed_games)
|
||||
|
||||
|
||||
# if feasible:
|
||||
# # GET GAMES
|
||||
# games = []
|
||||
# for key in sol.keys():
|
||||
# if sol[key].value() != 0:
|
||||
# games.append(key)
|
||||
|
||||
|
||||
# # CHECK AGAIN
|
||||
# check_feasible(games)
|
||||
|
||||
|
||||
# # WRITE SOL '.html'
|
||||
# teams = sorted(teams, key=lambda k: k['pot'])
|
||||
# sol = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
|
||||
# sol += " \
|
||||
# <style> \
|
||||
# table, th, td { \
|
||||
# border: 1px solid black; \
|
||||
# border-collapse: collapse; \
|
||||
# text-align: center; \
|
||||
# min-width:40px; \
|
||||
# padding:3px; \
|
||||
# margin: 3px; \
|
||||
# font-family : Arial;\
|
||||
# } \
|
||||
# h1 {\
|
||||
# font-family : Arial;\
|
||||
# }\
|
||||
# \
|
||||
# #etable td:nth-child(10),#etable th:nth-child(10) { border-right: 5px solid black; }\
|
||||
# #etable td:nth-child(19),#etable th:nth-child(19) { border-right: 5px solid black; }\
|
||||
# #etable td:nth-child(28),#etable th:nth-child(28) { border-right: 5px solid black; }\
|
||||
# tr:nth-child(9) { border-bottom: 5px solid black; }\
|
||||
# tr:nth-child(18) { border-bottom: 5px solid black; }\
|
||||
# tr:nth-child(27) { border-bottom: 5px solid black; }\
|
||||
# </style> \
|
||||
# "
|
||||
# sol += "<table id='etable' style='border:5px solid black'>\n"
|
||||
# sol += "<thead>\n"
|
||||
# sol += "<tr>"
|
||||
# sol += "<th></th>"
|
||||
# sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot A</th>"
|
||||
# sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot B</th>"
|
||||
# sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot C</th>"
|
||||
# sol += "<th colspan=9>Pot D</th>"
|
||||
# sol += "</tr>"
|
||||
# sol += "<tr>\n"
|
||||
# sol += f"<th></th>\n"
|
||||
# for t in teams:
|
||||
# sol += f"<th>{getTeamById[t['id']]}</th>\n"
|
||||
# sol += "</tr>\n"
|
||||
# sol += "</thead>\n"
|
||||
# sol += "<tbody>\n"
|
||||
# for t1 in teams:
|
||||
# sol += "<tr>\n"
|
||||
# sol += f"<td>{getTeamById[t1['id']]}</td>"
|
||||
# for t2 in teams:
|
||||
# if (t1['id'],t2['id']) in games:
|
||||
# sol += f"<td>{t2['country']}</td>"
|
||||
# elif (t2['id'],t1['id']) in games:
|
||||
# sol += f"<td>@{t2['country']}</td>"
|
||||
# else:
|
||||
# sol += f"<td></td>"
|
||||
# sol += "</tr>\n"
|
||||
# sol += "</tbody>\n"
|
||||
# sol += "</table>\n"
|
||||
|
||||
# with open(f'debug.html', 'w') as f:
|
||||
# f.write(sol)
|
||||
|
||||
744
uefa/cycle24/simulations/debugging/debug.py
Executable file
744
uefa/cycle24/simulations/debugging/debug.py
Executable file
@ -0,0 +1,744 @@
|
||||
# %%
|
||||
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"
|
||||
|
||||
from leagues import settings
|
||||
settings.DATABASES['default']['NAME'] = PROJECT_PATH+'/db.sqlite3'
|
||||
# settings.DATABASES['default']['ENGINE'] = 'django.db.backends.postgresql_psycopg2'
|
||||
# settings.DATABASES['default']['HOST'] = '0.0.0.0'
|
||||
# settings.DATABASES['default']['PORT'] = '5432'
|
||||
# settings.DATABASES['default']['USER'] = 'postgres'
|
||||
# settings.DATABASES['default']['PASSWORD'] = 'secret123'
|
||||
# settings.DATABASES['default']['NAME'] = 'mypgsqldb'
|
||||
# settings.DATABASES['default']['ATOMIC_REQUESTS'] = False
|
||||
# settings.DATABASES['default']['AUTOCOMMIT'] = True
|
||||
# settings.DATABASES['default']['CONN_MAX_AGE'] = 0
|
||||
# settings.DATABASES['default']['CONN_HEALTH_CHECKS'] = False
|
||||
# settings.DATABASES['default']['OPTIONS'] = {}
|
||||
|
||||
os.environ["XPRESSDIR"] = "/opt/xpressmp"
|
||||
os.environ["XPRESS"] = "/opt/xpressmp/bin"
|
||||
os.environ["LD_LIBRARY_PATH"] = os.environ["XPRESSDIR"] + "/lib"
|
||||
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["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprs.jar"
|
||||
os.environ["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprb.jar" + os.pathsep + os.environ["CLASSPATH"]
|
||||
os.environ["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprm.jar" + os.pathsep + os.environ["CLASSPATH"]
|
||||
os.environ["PATH"] = os.environ["XPRESSDIR"] + "/bin" + os.pathsep + os.environ["PATH"]
|
||||
|
||||
|
||||
import django
|
||||
django.setup()
|
||||
|
||||
from scheduler.models import *
|
||||
import csv
|
||||
from multiprocessing import Pool, cpu_count
|
||||
import random
|
||||
import time
|
||||
import pulp
|
||||
from pulp import lpSum, value, XPRESS, GUROBI, PULP_CBC_CMD
|
||||
|
||||
import xpress as xp
|
||||
# xp.controls.outputlog = 0
|
||||
|
||||
|
||||
|
||||
scenario = Scenario.objects.get(id=34)
|
||||
|
||||
# %%
|
||||
|
||||
# teamObjects = Team.objects.filter(season=scenario.season,active=True).order_by('pot','country')
|
||||
teamObjects = Team.objects.filter(season=scenario.season,active=True)
|
||||
teams = teamObjects.values('id','country','pot','name')
|
||||
|
||||
getTeamById = {}
|
||||
for t in teamObjects:
|
||||
getTeamById[t.id] = f"({t.pot}) {t.name}"
|
||||
|
||||
|
||||
countries = list(set(teamObjects.values_list('country', flat=True)))
|
||||
teams_from_country = {
|
||||
c:[t for t in teams if t['country']==c] for c in countries
|
||||
}
|
||||
|
||||
pot = {}
|
||||
for i in teamObjects.values_list('pot',flat=True).distinct():
|
||||
pot[i] = list(teams.filter(pot=i))
|
||||
|
||||
teams = list(teams)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
fixed_games = [(3940, 3894), (3933, 3940), (3940, 3937), (3765, 3940), (3940, 3895), (3700, 3940), (3940, 3696), (3925, 3940), (3702, 3935), (3894, 3702), (3702, 3926), (3937, 3702), (3702, 3700), (3758, 3702), (3702, 3699), (3757, 3702), (3932, 3762), (3732, 3932), (3932, 3938), (3761, 3932), (3932, 3730), (3701, 3932), (3932, 3870), (3853, 3932), (3764, 3933), (3935, 3764), (3764, 3936), (3898, 3764), (3764, 3756), (3928, 3764), (3764, 3925), (3904, 3764), (3762, 3732), (3762, 3761), (3930, 3762), (3762, 3701), (3760, 3762), (3762, 3697), (3698, 3762), (3732, 3765), (3926, 3732), (3732, 3928), (3730, 3732), (3732, 3698), (3870, 3732), (3894, 3930), (3938, 3894), (3894, 3758)]
|
||||
|
||||
|
||||
# fixed_games = [(3702, 3935), (3702, 3926), (3702, 3700), (3702, 3699), (3764, 3933), (3764, 3936), (3764, 3756), (3764, 3925), (3940, 3894), (3940, 3937), (3940, 3895), (3940, 3696), (3762, 3732), (3762, 3761), (3762, 3701), (3762, 3697), (3894, 3702), (3894, 3930), (3894, 3758), (3894, 3904), (3933, 3940), (3933, 3734), (3933, 3771), (3933, 3853), (3935, 3764), (3935, 3898), (3935, 3760), (3935, 3757), (3932, 3762), (3932, 3938), (3932, 3730), (3932, 3870), (3732, 3932), (3732, 3765), (3732, 3928), (3732, 3698), (3938, 3894), (3938, 3930), (3938, 3730), (3938, 3697), (3761, 3932), (3761, 3938), (3761, 3895), (3761, 3904), (3898, 3764), (3898, 3761), (3898, 3700), (3898, 3696), (3926, 3732), (3926, 3734), (3926, 3701), (3926, 3699), (3936, 3933), (3936, 3765), (3936, 3758), (3936, 3698), (3734, 3935), (3734, 3936), (3734, 3928), (3734, 3925), (3930, 3762), (3930, 3926), (3930, 3756), (3930, 3853), (3937, 3702), (3937, 3898), (3937, 3771), (3937, 3757), (3765, 3940), (3765, 3937), (3765, 3760), (3765, 3870), (3758, 3702), (3758, 3926), (3758, 3756), (3758, 3925), (3756, 3894), (3756, 3936), (3756, 3701), (3756, 3698), (3771, 3935), (3771, 3898), (3771, 3700), (3771, 3697), (3895, 3933), (3895, 3930), (3895, 3758), (3895, 3699), (3701, 3932), (3701, 3761), (3701, 3771), (3701, 3870), (3760, 3762), (3760, 3734), (3760, 3895), (3760, 3757), (3928, 3764), (3928, 3938), (3928, 3760), (3928, 3904), (3730, 3732), (3730, 3937), (3730, 3928), (3730, 3696), (3700, 3940), (3700, 3765), (3700, 3730), (3700, 3853), (3904, 3764), (3904, 3898), (3904, 3771), (3904, 3696), (3925, 3940), (3925, 3930), (3925, 3701), (3925, 3697), (3698, 3762), (3698, 3938), (3698, 3758), (3698, 3699), (3699, 3935), (3699, 3937), (3699, 3760), (3699, 3853), (3696, 3894), (3696, 3765), (3696, 3895), (3696, 3925), (3853, 3932), (3853, 3936), (3853, 3928), (3853, 3757), (3697, 3933), (3697, 3761), (3697, 3756), (3697, 3904), (3757, 3702), (3757, 3734), (3757, 3730), (3757, 3870), (3870, 3732), (3870, 3926), (3870, 3700), (3870, 3698)]
|
||||
|
||||
|
||||
# sol = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
|
||||
# sol += " \
|
||||
# <style> \
|
||||
# table, th, td { \
|
||||
# border: 1px solid black; \
|
||||
# border-collapse: collapse; \
|
||||
# text-align: center; \
|
||||
# min-width:40px; \
|
||||
# padding:3px; \
|
||||
# margin: 3px; \
|
||||
# font-family : Arial;\
|
||||
# } \
|
||||
# h1 {\
|
||||
# font-family : Arial;\
|
||||
# }\
|
||||
# \
|
||||
# #etable td:nth-child(10),#etable th:nth-child(10) { border-right: 5px solid black; }\
|
||||
# #etable td:nth-child(19),#etable th:nth-child(19) { border-right: 5px solid black; }\
|
||||
# #etable td:nth-child(28),#etable th:nth-child(28) { border-right: 5px solid black; }\
|
||||
# tr:nth-child(9) { border-bottom: 5px solid black; }\
|
||||
# tr:nth-child(18) { border-bottom: 5px solid black; }\
|
||||
# tr:nth-child(27) { border-bottom: 5px solid black; }\
|
||||
# </style> \
|
||||
# "
|
||||
# sol += "</head><body>"
|
||||
|
||||
# sol += "<table id='etable' style='border:5px solid black'>\n"
|
||||
# sol += "<thead>\n"
|
||||
# sol += "<tr>"
|
||||
# sol += "<th></th>"
|
||||
# sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot A</th>"
|
||||
# sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot B</th>"
|
||||
# sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot C</th>"
|
||||
# sol += "<th colspan=9>Pot D</th>"
|
||||
# sol += "</tr>"
|
||||
# sol += "<tr>\n"
|
||||
# sol += f"<th></th>\n"
|
||||
# # for o in order:
|
||||
# for t in teams:
|
||||
# # t = getTeamByName[o]
|
||||
# sol += f"<th>{t['name']}({t['country']})</th>\n"
|
||||
# sol += "</tr>\n"
|
||||
# sol += "</thead>\n"
|
||||
# sol += "<tbody>\n"
|
||||
# # for o1 in order:
|
||||
# for t1 in teams:
|
||||
# # t1 = getTeamByName[o1]
|
||||
# sol += "<tr>\n"
|
||||
# sol += f"<td>{t1['name']}({t1['country']})</td>"
|
||||
# # for o2 in order:
|
||||
# for t2 in teams:
|
||||
# # t2 = getTeamByName[o2]
|
||||
# # val = stats[t1,t2]
|
||||
# if (t1['id'],t2['id']) in fixed_games:
|
||||
# sol += f"<td>{t2['country']}</td>"
|
||||
# elif (t2['id'],t1['id']) in fixed_games:
|
||||
# sol += f"<td>@{t2['country']}</td>"
|
||||
# else:
|
||||
# sol += f"<td></td>"
|
||||
# sol += "</tr>\n"
|
||||
|
||||
# sol += "</tbody>\n"
|
||||
# sol += "</table>\n"
|
||||
|
||||
|
||||
|
||||
# with open(f'debug.html', 'w') as f:
|
||||
# f.write(sol)
|
||||
|
||||
|
||||
|
||||
|
||||
# %%
|
||||
|
||||
|
||||
|
||||
def check_feasible(fixed_games):
|
||||
|
||||
model = pulp.LpProblem(f"Draws", pulp.LpMinimize)
|
||||
xp_model = xp.problem(name='Draws', sense=xp.minimize)
|
||||
xp_model.setControl('outputlog', 1)
|
||||
xp_model.setControl('presolve',0)
|
||||
x = {}
|
||||
xp_x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
x[t1['id'], t2['id']] = pulp.LpVariable('x_'+str(t1['id'])+'_'+str(t2['id']),lowBound=0, upBound=1, cat=pulp.LpInteger)
|
||||
xp_x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer)
|
||||
|
||||
xp_model.addVariable(xp_x)
|
||||
|
||||
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
xp_model.addConstraint(xp.Sum(xp_x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in xp_x.keys()) == 1)
|
||||
xp_model.addConstraint(xp.Sum(xp_x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in xp_x.keys()) == 1)
|
||||
model += lpSum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1
|
||||
model += lpSum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1
|
||||
|
||||
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
xp_model.addConstraint(xp.Sum(xp_x[t['id'],t2['id']]+xp_x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2)
|
||||
model += lpSum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2
|
||||
|
||||
|
||||
# FIXATIONS
|
||||
for (t1,t2) in fixed_games:
|
||||
xp_model.addConstraint(xp_x[t1,t2] == 1)
|
||||
model += x[t1,t2] == 1
|
||||
|
||||
|
||||
|
||||
for (t1,t2) in xp_x.keys():
|
||||
xp_model.addConstraint(xp_x[t1,t2] + xp_x[t2,t1] <= 1)
|
||||
for (t1,t2) in x.keys():
|
||||
model += x[t1,t2] + x[t2,t1] <= 1
|
||||
|
||||
# model += lpSum(random.uniform(0,1)*x[key] for key in x.keys())
|
||||
model.writeMPS('pulp.mps',rename=True)
|
||||
model.solve(XPRESS(msg=1))
|
||||
|
||||
# xp_model.solve()
|
||||
# print(model.status)
|
||||
# if model.status in [-1,-2]:
|
||||
# print("ERROR")
|
||||
# else:
|
||||
# print("SUCCESS")
|
||||
|
||||
|
||||
# games = []
|
||||
# for key in x.keys():
|
||||
# if x[key].value() != 0:
|
||||
# # print(key,xp_model.getSolution(xp_x[key]))
|
||||
# games.append(key)
|
||||
|
||||
|
||||
# sol = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
|
||||
# sol += " \
|
||||
# <style> \
|
||||
# table, th, td { \
|
||||
# border: 1px solid black; \
|
||||
# border-collapse: collapse; \
|
||||
# text-align: center; \
|
||||
# min-width:40px; \
|
||||
# padding:3px; \
|
||||
# margin: 3px; \
|
||||
# font-family : Arial;\
|
||||
# } \
|
||||
# h1 {\
|
||||
# font-family : Arial;\
|
||||
# }\
|
||||
# \
|
||||
# #etable td:nth-child(10),#etable th:nth-child(10) { border-right: 5px solid black; }\
|
||||
# #etable td:nth-child(19),#etable th:nth-child(19) { border-right: 5px solid black; }\
|
||||
# #etable td:nth-child(28),#etable th:nth-child(28) { border-right: 5px solid black; }\
|
||||
# tr:nth-child(9) { border-bottom: 5px solid black; }\
|
||||
# tr:nth-child(18) { border-bottom: 5px solid black; }\
|
||||
# tr:nth-child(27) { border-bottom: 5px solid black; }\
|
||||
# </style> \
|
||||
# "
|
||||
|
||||
# sol += "<table id='etable' style='border:5px solid black'>\n"
|
||||
# sol += "<thead>\n"
|
||||
# sol += "<tr>"
|
||||
# sol += "<th></th>"
|
||||
# sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot A</th>"
|
||||
# sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot B</th>"
|
||||
# sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot C</th>"
|
||||
# sol += "<th colspan=9>Pot D</th>"
|
||||
# sol += "</tr>"
|
||||
# sol += "<tr>\n"
|
||||
# sol += f"<th></th>\n"
|
||||
# # for o in order:
|
||||
# for t in teams:
|
||||
# # t = getTeamByName[o]
|
||||
# sol += f"<th>{getTeamById[t['id']]}</th>\n"
|
||||
# sol += "</tr>\n"
|
||||
# sol += "</thead>\n"
|
||||
# sol += "<tbody>\n"
|
||||
# # for o1 in order:
|
||||
# for t1 in teams:
|
||||
# # t1 = getTeamByName[o1]
|
||||
# sol += "<tr>\n"
|
||||
# sol += f"<td>{getTeamById[t1['id']]}</td>"
|
||||
# # for o2 in order:
|
||||
# for t2 in teams:
|
||||
# # t2 = getTeamByName[o2]
|
||||
# # val = stats[t1,t2]
|
||||
# if (t1['id'],t2['id']) in games:
|
||||
# sol += f"<td>{t2['country']}</td>"
|
||||
# elif (t2['id'],t1['id']) in games:
|
||||
# sol += f"<td>@{t2['country']}</td>"
|
||||
# else:
|
||||
# sol += f"<td></td>"
|
||||
# sol += "</tr>\n"
|
||||
|
||||
# sol += "</tbody>\n"
|
||||
# sol += "</table>\n"
|
||||
|
||||
|
||||
|
||||
# with open(f'debug_pulp.html', 'w') as f:
|
||||
# f.write(sol)
|
||||
|
||||
# print("\n\n\n\n")
|
||||
# # model.writeMPS('pulp.mps',rename=True)
|
||||
# # xp_model.write('xpress.lp','lps')
|
||||
# xp_model.solve()
|
||||
|
||||
|
||||
|
||||
# if xp_model.getProbStatus() != 6:
|
||||
# print("ERROR")
|
||||
# # print("INFEASIBLE FOUND")
|
||||
# else:
|
||||
# print("SUCCESS")
|
||||
|
||||
# games = []
|
||||
# for key in xp_x.keys():
|
||||
# if xp_model.getSolution(xp_x[key]) != 0:
|
||||
# # print(key,xp_model.getSolution(xp_x[key]))
|
||||
# games.append(key)
|
||||
|
||||
# print(len(games))
|
||||
|
||||
# sol = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
|
||||
# sol += " \
|
||||
# <style> \
|
||||
# table, th, td { \
|
||||
# border: 1px solid black; \
|
||||
# border-collapse: collapse; \
|
||||
# text-align: center; \
|
||||
# min-width:40px; \
|
||||
# padding:3px; \
|
||||
# margin: 3px; \
|
||||
# font-family : Arial;\
|
||||
# } \
|
||||
# h1 {\
|
||||
# font-family : Arial;\
|
||||
# }\
|
||||
# \
|
||||
# #etable td:nth-child(10),#etable th:nth-child(10) { border-right: 5px solid black; }\
|
||||
# #etable td:nth-child(19),#etable th:nth-child(19) { border-right: 5px solid black; }\
|
||||
# #etable td:nth-child(28),#etable th:nth-child(28) { border-right: 5px solid black; }\
|
||||
# tr:nth-child(9) { border-bottom: 5px solid black; }\
|
||||
# tr:nth-child(18) { border-bottom: 5px solid black; }\
|
||||
# tr:nth-child(27) { border-bottom: 5px solid black; }\
|
||||
# </style> \
|
||||
# "
|
||||
|
||||
# sol += "<table id='etable' style='border:5px solid black'>\n"
|
||||
# sol += "<thead>\n"
|
||||
# sol += "<tr>"
|
||||
# sol += "<th></th>"
|
||||
# sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot A</th>"
|
||||
# sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot B</th>"
|
||||
# sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot C</th>"
|
||||
# sol += "<th colspan=9>Pot D</th>"
|
||||
# sol += "</tr>"
|
||||
# sol += "<tr>\n"
|
||||
# sol += f"<th></th>\n"
|
||||
# # for o in order:
|
||||
# for t in teams:
|
||||
# # t = getTeamByName[o]
|
||||
# sol += f"<th>{getTeamById[t['id']]}</th>\n"
|
||||
# sol += "</tr>\n"
|
||||
# sol += "</thead>\n"
|
||||
# sol += "<tbody>\n"
|
||||
# # for o1 in order:
|
||||
# for t1 in teams:
|
||||
# # t1 = getTeamByName[o1]
|
||||
# sol += "<tr>\n"
|
||||
# sol += f"<td>{getTeamById[t1['id']]}</td>"
|
||||
# # for o2 in order:
|
||||
# for t2 in teams:
|
||||
# # t2 = getTeamByName[o2]
|
||||
# # val = stats[t1,t2]
|
||||
# if (t1['id'],t2['id']) in games:
|
||||
# sol += f"<td>{t2['country']}</td>"
|
||||
# elif (t2['id'],t1['id']) in games:
|
||||
# sol += f"<td>@{t2['country']}</td>"
|
||||
# else:
|
||||
# sol += f"<td></td>"
|
||||
# sol += "</tr>\n"
|
||||
|
||||
# sol += "</tbody>\n"
|
||||
# sol += "</table>\n"
|
||||
|
||||
|
||||
|
||||
# with open(f'debug_xpress.html', 'w') as f:
|
||||
# f.write(sol)
|
||||
|
||||
|
||||
|
||||
|
||||
# def check_feasible_2(fixed_games):
|
||||
# model = xp.problem(name='Draws', sense=xp.minimize)
|
||||
# model.setControl ('outputlog', 1)
|
||||
|
||||
# x = {}
|
||||
# for t1 in teams:
|
||||
# for t2 in teams:
|
||||
# if t1['country'] != t2['country']:
|
||||
# x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer)
|
||||
|
||||
# model.addVariable(x)
|
||||
|
||||
# # REQUIREMENTS
|
||||
# for t in teams:
|
||||
# for r in range(1,5):
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
# model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
# for c in countries:
|
||||
# if c != t['country']:
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2)
|
||||
|
||||
|
||||
# # FIXATIONS
|
||||
# for (t1,t2) in fixed_games:
|
||||
# # print("FIXING",t1,t2)
|
||||
# model.addConstraint(x[t1,t2] == 1)
|
||||
|
||||
# for (t1,t2) in x.keys():
|
||||
# model.addConstraint(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
|
||||
# tt =time.time()
|
||||
# model.solve()
|
||||
# comp_time = time.time()-tt
|
||||
|
||||
|
||||
# if model.getProbStatus() != 6:
|
||||
# # print("INFEASIBLE FOUND")
|
||||
# return False, comp_time
|
||||
# else:
|
||||
# return True, comp_time
|
||||
|
||||
|
||||
check_feasible(fixed_games)
|
||||
|
||||
exit()
|
||||
|
||||
|
||||
# %%
|
||||
|
||||
|
||||
model = xp.problem(name='Draws', sense=xp.minimize)
|
||||
model.setControl ('outputlog', 1)
|
||||
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer)
|
||||
|
||||
model.addVariable(x)
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2)
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
model.addConstraint(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
def check_feasible_fix(fixed_games):
|
||||
# FIXATIONS
|
||||
# for key in x.keys():
|
||||
# if key in fixed_games:
|
||||
# # x[key].lb = 1
|
||||
# model.chgbounds([x[key]],['L'],[1])
|
||||
# else:
|
||||
# # x[key].lb = 0
|
||||
# model.chgbounds([x[key]],['L'],[0])
|
||||
|
||||
reset_bounds = [key for key in x.keys() if key not in fixed_games]
|
||||
|
||||
model.chgbounds([x[key] for key in fixed_games],['L' for _ in range(len(fixed_games))],[1 for _ in range(len(fixed_games))])
|
||||
model.chgbounds([x[key] for key in reset_bounds],['L' for _ in range(len(reset_bounds))],[0 for _ in range(len(reset_bounds))])
|
||||
|
||||
# tt =time.time()
|
||||
model.solve()
|
||||
# comp_time = time.time()-tt
|
||||
|
||||
if model.getProbStatus() != 6:
|
||||
# print("INFEASIBLE FOUND")
|
||||
# return False, comp_time
|
||||
return False
|
||||
else:
|
||||
# return True, comp_time
|
||||
return True
|
||||
|
||||
|
||||
|
||||
check_feasible_fix(fixed_games)
|
||||
exit()
|
||||
|
||||
# def ucl24_random_games(team_to_check, pots_to_check, oldgames):
|
||||
# teamObjects = Team.objects.filter(season=scenario.season,active=True)
|
||||
# teams = [t.id for t in teamObjects]
|
||||
# t_country = {t.id : t.country for t in teamObjects}
|
||||
# t_name = {t.id : t.name for t in teamObjects}
|
||||
# t_pot = {t.id : t.pot for t in teamObjects}
|
||||
# countries = sorted(list(set(t_country.values())))
|
||||
# pots = sorted(list(set(t_pot.values())))
|
||||
|
||||
# max_opponents_from_same_country=2
|
||||
|
||||
# givenHome = { (t,p) : False for t in teams for p in pots }
|
||||
# givenAway = { (t,p) : False for t in teams for p in pots }
|
||||
# gamesAgainstCountry = { (t,c) : 0 for t in teams for c in countries }
|
||||
|
||||
# for (t1,t2) in oldgames:
|
||||
# givenHome[t1,t_pot[t2]]=t2
|
||||
# givenAway[t2,t_pot[t1]]=t1
|
||||
# gamesAgainstCountry[(t1,t_country[t2])]+=1
|
||||
# gamesAgainstCountry[(t2,t_country[t1])]+=1
|
||||
|
||||
# no_solution_found = True
|
||||
|
||||
# possHomeOpponents={}
|
||||
# possAwayOpponents={}
|
||||
# for p in pots_to_check:
|
||||
# print( "POT " , p)
|
||||
# possOpponents1 = [ t for t in teams if t_country[t]!=t_country[team_to_check] and t_pot[t]==p and t!=givenAway[team_to_check,p] ]
|
||||
# possOpponents = [ t for t in possOpponents1 if gamesAgainstCountry[(team_to_check,t_country[t])]<2 and gamesAgainstCountry[(t,t_country[team_to_check])]<2]
|
||||
# if givenHome[team_to_check,p]:
|
||||
# possHomeOpponents[p]= [givenHome[team_to_check,p]]
|
||||
# else:
|
||||
# possHomeOpponents[p] = [ t for t in possOpponents if not givenAway[t,t_pot[team_to_check]] ]
|
||||
# if givenAway[team_to_check,p]:
|
||||
# possAwayOpponents[p]= [givenAway[team_to_check,p]]
|
||||
# else:
|
||||
# possAwayOpponents[p] = [ t for t in possOpponents if not givenHome[t,t_pot[team_to_check]]]
|
||||
|
||||
# while no_solution_found:
|
||||
# newgames = []
|
||||
# for p in pots_to_check:
|
||||
# random_home= random.choice(possHomeOpponents[p])
|
||||
# random_away= random.choice(possAwayOpponents[p])
|
||||
# print (p,"-> " , random_home==random_away, t_name[random_home], "\t ", t_name[random_away] )
|
||||
# newgames+=[(team_to_check,random_home), (random_away,team_to_check) ]
|
||||
# if random_home!=random_away and check_feasible(oldgames+newgames):
|
||||
# no_solution_found = False
|
||||
|
||||
# newgames = [gm for gm in newgames if gm not in oldgames]
|
||||
# return newgames
|
||||
|
||||
|
||||
# %%
|
||||
|
||||
|
||||
|
||||
def simulate_draws(filename,n):
|
||||
|
||||
print("RUNNING ASYNC",filename)
|
||||
|
||||
for i in range(1, n):
|
||||
if i % 100 == 0:
|
||||
print("RUNNING ASYNC",filename,i)
|
||||
# start_time = time.time()
|
||||
# n_computations = 0
|
||||
# check_time = 0
|
||||
# total_comp_time = 0
|
||||
|
||||
|
||||
possible_opps = {}
|
||||
for pos in range(8):
|
||||
p = pos//2+1
|
||||
teams_from_pot = list(teamObjects.filter(pot=p).values('id','country'))
|
||||
possible_opps[pos] = {
|
||||
t['id']: [t2['id'] for t2 in teams_from_pot if t2['country'] != t['country']] for t in teams
|
||||
}
|
||||
|
||||
sol_opps = {
|
||||
(t['id'],p):None
|
||||
for t in teams for p in range(8)
|
||||
}
|
||||
fixed_games = []
|
||||
feasible = True
|
||||
|
||||
for p in range(1,5):
|
||||
currentPot = list(teamObjects.filter(pot=p).values_list('id', flat=True))
|
||||
|
||||
while(feasible and currentPot):
|
||||
new_team = currentPot.pop(random.randint(0,len(currentPot)-1))
|
||||
for current_pos in range(8):
|
||||
while (feasible and sol_opps[new_team,current_pos] == None):
|
||||
try:
|
||||
new_opponent = random.choice(possible_opps[current_pos][new_team])
|
||||
except:
|
||||
feasible = False
|
||||
print("INFEASIBLE")
|
||||
print(sol_opps)
|
||||
print(fixed_games)
|
||||
print(possible_opps)
|
||||
print(new_team,current_pos)
|
||||
print(possible_opps[current_pos][new_team])
|
||||
|
||||
|
||||
exit()
|
||||
|
||||
if sol_opps[new_opponent,(2*p-1)-(current_pos % 2)] == None:
|
||||
new_game = (new_team,new_opponent) if current_pos % 2 == 0 else (new_opponent,new_team)
|
||||
# n_computations += 1
|
||||
# tt = time.time()
|
||||
# check, comp_time = check_feasible_fix(fixed_games+[new_game])
|
||||
# check_time += time.time()-tt
|
||||
# total_comp_time += comp_time
|
||||
if check_feasible_fix(fixed_games+[new_game]):
|
||||
sol_opps[new_team,current_pos] = new_opponent
|
||||
sol_opps[new_opponent,(2*p-1)-(current_pos % 2)] = new_team
|
||||
fixed_games.append(new_game)
|
||||
if new_opponent in possible_opps[(2*p-1)-(current_pos % 2)][new_team]:
|
||||
possible_opps[(2*p-1)-(current_pos % 2)][new_team].remove(new_opponent)
|
||||
possible_opps[current_pos][new_team].remove(new_opponent)
|
||||
else:
|
||||
possible_opps[current_pos][new_team].remove(new_opponent)
|
||||
|
||||
|
||||
# for p in [1,2,3,4]:
|
||||
# # for p in [4,3,2,1]:
|
||||
# currentPot = list(teamObjects.filter(pot=p).values_list('id', flat=True))
|
||||
|
||||
# while(feasible and currentPot):
|
||||
# # Draw Team
|
||||
# new_team = currentPot.pop(random.randint(0,len(currentPot)-1))
|
||||
# draw_index_dict[new_team] = draw_index
|
||||
# draw_index += 1
|
||||
|
||||
# # print("New team",new_team,getTeamById[new_team])
|
||||
# for pos in range(8):
|
||||
# # Skip if already drawn
|
||||
# if sol_opps[new_team,pos]:
|
||||
# continue
|
||||
# # Update possible opponents
|
||||
# opponent_pool = []
|
||||
# for new_opponent in possible_opps[pos][new_team]:
|
||||
# if sol_opps[new_opponent,(2*p-1)-(pos % 2)] != None:
|
||||
# continue
|
||||
# # print(f"---> ALREADY DRAWN {pos}: {getTeamById[new_opponent]}")
|
||||
# else:
|
||||
# new_game = (new_team,new_opponent) if pos % 2 == 0 else (new_opponent,new_team)
|
||||
# n_computations += 1
|
||||
# tt = time.time()
|
||||
# feasible = check_feasible(fixed_games+[new_game])
|
||||
# comp_time += time.time()-tt
|
||||
# if feasible:
|
||||
# opponent_pool.append(new_opponent)
|
||||
# else:
|
||||
# # print(f"---> CANNOT DRAW {pos}: {[getTeamById[ttt] for ttt in new_game]}")
|
||||
# num_combinatorial_clashes[new_team,pos] += 1
|
||||
# num_possible_opps[new_team,pos] = len(opponent_pool)
|
||||
# # Draw random opponent
|
||||
# new_opponent = random.choice(opponent_pool)
|
||||
# new_game = (new_team,new_opponent) if pos % 2 == 0 else (new_opponent,new_team)
|
||||
# # if not check_feasible(fixed_games+[new_game]):
|
||||
# # print("INFEASIBLE")
|
||||
# # print("POSSOPS AFTER",[getTeamById[tt] for tt in possible_opps[pos][new_team]])
|
||||
# # print(f"{p} - {pos} - {getTeamById[sol_opps[new_opponent,(2*p-1)-(pos % 2)]]}")
|
||||
# # feasible = False
|
||||
# # break
|
||||
|
||||
# sol_opps[new_team,pos] = new_opponent
|
||||
# sol_opps[new_opponent,(2*p-1)-(pos % 2)] = new_team
|
||||
# if pos % 2 == 0:
|
||||
# possible_opps[pos+1][new_team].remove(new_opponent)
|
||||
# fixed_games.append(new_game)
|
||||
|
||||
|
||||
# print("COMPUTATIONS",n_computations)
|
||||
# print("TIME\t",time.time()-start_time)
|
||||
# print("CHECK\t",check_time)
|
||||
# print("COMP\t",total_comp_time)
|
||||
with open(filename+'.csv', "a") as f:
|
||||
for t in teams:
|
||||
f.write(f"{i},{t['id']},{';'.join([str(sol_opps[t['id'],p]) for p in range(8)])}\n")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# for game in fixed_games:
|
||||
# if game[0] == new_team or game[1] == new_team:
|
||||
# print("\t"," vs ".join([getTeamById[tt] for tt in game]))
|
||||
# print(f"--- > {draw_index_dict[new_team]}")
|
||||
# for pos in range(8):
|
||||
# print(f"--- > {pos} - {num_possible_opps[new_team,pos]}")
|
||||
|
||||
# iterate over h/a-encounters
|
||||
# for current_pos in range(8):
|
||||
# while (sol_opps[new_team,current_pos] == None):
|
||||
# # print(possible_opps[current_pos][new_team])
|
||||
# # draw opponent
|
||||
# new_opponent = random.choice(possible_opps[current_pos][new_team])
|
||||
# print("\tNEW OPP",new_opponent,getTeamById[new_opponent])
|
||||
# new_game = (new_team,new_opponent) if current_pos % 2 == 0 else (new_opponent,new_team)
|
||||
# if check_feasible(fixed_games+[new_game]):
|
||||
# # print("FEASIBLE",new_game,[getTeamById[tt] for tt in new_game])
|
||||
# sol_opps[new_team,current_pos] = new_opponent
|
||||
# sol_opps[new_opponent,(2*p-1)-(current_pos % 2)] = new_team
|
||||
# fixed_games.append(new_game)
|
||||
# possible_opps[current_pos][new_team].remove(new_opponent)
|
||||
# else:
|
||||
# possible_opps[current_pos][new_team].remove(new_opponent)
|
||||
# %%
|
||||
|
||||
|
||||
# # SOLUTION
|
||||
# for g in fixed_games:
|
||||
# print(getTeamById[g[0]],getTeamById[g[1]])
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# n = sys.maxsize
|
||||
|
||||
# pool = Pool()
|
||||
# result = {}
|
||||
# answer = {}
|
||||
# n_threads = cpu_count()
|
||||
# # n_threads = 1
|
||||
|
||||
# for cpu in range(n_threads):
|
||||
# result[cpu] = pool.apply_async(simulate_draws, args=(f'thread_{cpu}_pot_by_pot', n,))
|
||||
|
||||
# for cpu in range(n_threads):
|
||||
# answer[cpu] = result[cpu].get()
|
||||
|
||||
|
||||
# %%
|
||||
n = sys.maxsize
|
||||
simulate_draws('test', n)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# %%
|
||||
|
||||
|
||||
495
uefa/cycle24/simulations/debugging/debug_2.py
Executable file
495
uefa/cycle24/simulations/debugging/debug_2.py
Executable file
@ -0,0 +1,495 @@
|
||||
# %%
|
||||
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"
|
||||
|
||||
from leagues import settings
|
||||
settings.DATABASES['default']['NAME'] = PROJECT_PATH+'/db.sqlite3'
|
||||
# settings.DATABASES['default']['ENGINE'] = 'django.db.backends.postgresql_psycopg2'
|
||||
# settings.DATABASES['default']['HOST'] = '0.0.0.0'
|
||||
# settings.DATABASES['default']['PORT'] = '5432'
|
||||
# settings.DATABASES['default']['USER'] = 'postgres'
|
||||
# settings.DATABASES['default']['PASSWORD'] = 'secret123'
|
||||
# settings.DATABASES['default']['NAME'] = 'mypgsqldb'
|
||||
# settings.DATABASES['default']['ATOMIC_REQUESTS'] = False
|
||||
# settings.DATABASES['default']['AUTOCOMMIT'] = True
|
||||
# settings.DATABASES['default']['CONN_MAX_AGE'] = 0
|
||||
# settings.DATABASES['default']['CONN_HEALTH_CHECKS'] = False
|
||||
# settings.DATABASES['default']['OPTIONS'] = {}
|
||||
|
||||
# os.environ["XPRESSDIR"] = "/opt/xpressmp_8.4"
|
||||
# os.environ["XPRESS"] = "/opt/xpressmp_8.4/bin"
|
||||
os.environ["XPRESSDIR"] = "/opt/xpressmp"
|
||||
os.environ["XPRESS"] = "/opt/xpressmp/bin"
|
||||
os.environ["LD_LIBRARY_PATH"] = os.environ["XPRESSDIR"] + "/lib"
|
||||
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["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprs.jar"
|
||||
os.environ["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprb.jar" + os.pathsep + os.environ["CLASSPATH"]
|
||||
os.environ["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprm.jar" + os.pathsep + os.environ["CLASSPATH"]
|
||||
os.environ["PATH"] = os.environ["XPRESSDIR"] + "/bin" + os.pathsep + os.environ["PATH"]
|
||||
|
||||
|
||||
import django
|
||||
django.setup()
|
||||
|
||||
from scheduler.models import *
|
||||
import csv
|
||||
from multiprocessing import Pool, cpu_count
|
||||
import random
|
||||
import time
|
||||
import pulp
|
||||
from pulp import lpSum, value, XPRESS, GUROBI, PULP_CBC_CMD
|
||||
import codecs
|
||||
# import xpress as xp
|
||||
# xp.controls.outputlog = 0
|
||||
|
||||
|
||||
|
||||
scenario = Scenario.objects.get(id=34)
|
||||
|
||||
|
||||
teamObjects = Team.objects.filter(season=scenario.season,active=True).order_by('pot','country')
|
||||
# teamObjects = Team.objects.filter(season=scenario.season,active=True)
|
||||
teams = teamObjects.values('id','country','pot','shortname')
|
||||
|
||||
for t in teams:
|
||||
t['shortname'] = t['shortname'][:4]
|
||||
if t['shortname'][:-1] == 'Atl':
|
||||
t['shortname'] = 'Atle'
|
||||
|
||||
getTeamById = {}
|
||||
for t in teamObjects:
|
||||
getTeamById[t.id] = f"({t.country}) {t.name}"
|
||||
|
||||
|
||||
countries = list(set(teamObjects.values_list('country', flat=True)))
|
||||
teams_from_country = {
|
||||
c:[t for t in teams if t['country']==c] for c in countries
|
||||
}
|
||||
|
||||
pot = {}
|
||||
for i in teamObjects.values_list('pot',flat=True).distinct():
|
||||
pot[i] = list(teams.filter(pot=i))
|
||||
|
||||
teams = list(teams)
|
||||
|
||||
|
||||
|
||||
fixed_games = [(3940, 3894), (3933, 3940), (3940, 3937), (3765, 3940), (3940, 3895), (3700, 3940), (3940, 3696), (3925, 3940), (3702, 3935), (3894, 3702), (3702, 3926), (3937, 3702), (3702, 3700), (3758, 3702), (3702, 3699), (3757, 3702), (3932, 3762), (3732, 3932), (3932, 3938), (3761, 3932), (3932, 3730), (3701, 3932), (3932, 3870), (3853, 3932), (3764, 3933), (3935, 3764), (3764, 3936), (3898, 3764), (3764, 3756), (3928, 3764), (3764, 3925), (3904, 3764), (3762, 3732), (3762, 3761), (3930, 3762), (3762, 3701), (3760, 3762), (3762, 3697), (3698, 3762), (3732, 3765), (3926, 3732), (3732, 3928), (3730, 3732), (3732, 3698), (3870, 3732), (3894, 3930), (3938, 3894), (3894, 3758)]
|
||||
|
||||
|
||||
|
||||
# %%
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
model = pulp.LpProblem(f"Draws", pulp.LpMinimize)
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
x[t1['id'], t2['id']] = pulp.LpVariable('x_'+str(t1['id'])+'_'+str(t2['id']),lowBound=0, upBound=1, cat=pulp.LpInteger)
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
model += lpSum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1
|
||||
model += lpSum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1
|
||||
|
||||
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
model += lpSum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2
|
||||
|
||||
|
||||
# FIXATIONS
|
||||
for (t1,t2) in fixed_games:
|
||||
model += x[t1,t2] == 1
|
||||
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
model += x[t1,t2] + x[t2,t1] <= 1
|
||||
|
||||
# model += lpSum(random.uniform(0,1)*x[key] for key in x.keys())
|
||||
with open ("model.txt", "w") as f:
|
||||
f.write(model.__repr__())
|
||||
model.writeLP('pulp.lp')
|
||||
model.writeMPS('pulp.mps')
|
||||
model.solve(XPRESS(msg=1))
|
||||
|
||||
if model.status in [-1,-2]:
|
||||
print("ERROR")
|
||||
else:
|
||||
print("SUCCESS")
|
||||
|
||||
|
||||
exit()
|
||||
|
||||
print("\n\n\n\n")
|
||||
|
||||
model = pulp.LpProblem(f"Draws", pulp.LpMinimize)
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
x[t1['id'], t2['id']] = pulp.LpVariable('x_'+str(t1['shortname'])+'_'+str(t2['shortname']),lowBound=0, upBound=1, cat=pulp.LpInteger)
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
model += lpSum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1, f"pot_{getTeamById[t['id']]}_{r}_H"
|
||||
model += lpSum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1, f"pot_{getTeamById[t['id']]}_{r}_A"
|
||||
|
||||
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
model += lpSum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2, f"country_{getTeamById[t['id']]}_{c}"
|
||||
|
||||
|
||||
# FIXATIONS
|
||||
for (t1,t2) in fixed_games:
|
||||
model += x[t1,t2] == 1, f"fix_{t1}_{t2}"
|
||||
|
||||
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
model += x[t1,t2] + x[t2,t1] <= 1, f"symmetry_{t1}_{t2}"
|
||||
|
||||
model.solve(XPRESS(msg=1))
|
||||
|
||||
|
||||
|
||||
# games = []
|
||||
# for key in x.keys():
|
||||
# x[key].lowBound = x[key].value()
|
||||
# if x[key].value() != 0:
|
||||
# games.append(key)
|
||||
|
||||
# with open ("model2.txt", "w") as f:
|
||||
# f.write(model.__repr__())
|
||||
# model.solve(XPRESS(msg=1))
|
||||
|
||||
|
||||
|
||||
exit()
|
||||
|
||||
|
||||
# %%
|
||||
|
||||
|
||||
model = xp.problem(name='Draws', sense=xp.minimize)
|
||||
model.setControl ('outputlog', 1)
|
||||
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer)
|
||||
|
||||
model.addVariable(x)
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2)
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
model.addConstraint(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
def check_feasible_fix(fixed_games):
|
||||
# FIXATIONS
|
||||
# for key in x.keys():
|
||||
# if key in fixed_games:
|
||||
# # x[key].lb = 1
|
||||
# model.chgbounds([x[key]],['L'],[1])
|
||||
# else:
|
||||
# # x[key].lb = 0
|
||||
# model.chgbounds([x[key]],['L'],[0])
|
||||
|
||||
reset_bounds = [key for key in x.keys() if key not in fixed_games]
|
||||
|
||||
model.chgbounds([x[key] for key in fixed_games],['L' for _ in range(len(fixed_games))],[1 for _ in range(len(fixed_games))])
|
||||
model.chgbounds([x[key] for key in reset_bounds],['L' for _ in range(len(reset_bounds))],[0 for _ in range(len(reset_bounds))])
|
||||
|
||||
# tt =time.time()
|
||||
model.solve()
|
||||
# comp_time = time.time()-tt
|
||||
|
||||
if model.getProbStatus() != 6:
|
||||
# print("INFEASIBLE FOUND")
|
||||
# return False, comp_time
|
||||
return False
|
||||
else:
|
||||
# return True, comp_time
|
||||
return True
|
||||
|
||||
|
||||
|
||||
check_feasible_fix(fixed_games)
|
||||
exit()
|
||||
|
||||
# def ucl24_random_games(team_to_check, pots_to_check, oldgames):
|
||||
# teamObjects = Team.objects.filter(season=scenario.season,active=True)
|
||||
# teams = [t.id for t in teamObjects]
|
||||
# t_country = {t.id : t.country for t in teamObjects}
|
||||
# t_name = {t.id : t.name for t in teamObjects}
|
||||
# t_pot = {t.id : t.pot for t in teamObjects}
|
||||
# countries = sorted(list(set(t_country.values())))
|
||||
# pots = sorted(list(set(t_pot.values())))
|
||||
|
||||
# max_opponents_from_same_country=2
|
||||
|
||||
# givenHome = { (t,p) : False for t in teams for p in pots }
|
||||
# givenAway = { (t,p) : False for t in teams for p in pots }
|
||||
# gamesAgainstCountry = { (t,c) : 0 for t in teams for c in countries }
|
||||
|
||||
# for (t1,t2) in oldgames:
|
||||
# givenHome[t1,t_pot[t2]]=t2
|
||||
# givenAway[t2,t_pot[t1]]=t1
|
||||
# gamesAgainstCountry[(t1,t_country[t2])]+=1
|
||||
# gamesAgainstCountry[(t2,t_country[t1])]+=1
|
||||
|
||||
# no_solution_found = True
|
||||
|
||||
# possHomeOpponents={}
|
||||
# possAwayOpponents={}
|
||||
# for p in pots_to_check:
|
||||
# print( "POT " , p)
|
||||
# possOpponents1 = [ t for t in teams if t_country[t]!=t_country[team_to_check] and t_pot[t]==p and t!=givenAway[team_to_check,p] ]
|
||||
# possOpponents = [ t for t in possOpponents1 if gamesAgainstCountry[(team_to_check,t_country[t])]<2 and gamesAgainstCountry[(t,t_country[team_to_check])]<2]
|
||||
# if givenHome[team_to_check,p]:
|
||||
# possHomeOpponents[p]= [givenHome[team_to_check,p]]
|
||||
# else:
|
||||
# possHomeOpponents[p] = [ t for t in possOpponents if not givenAway[t,t_pot[team_to_check]] ]
|
||||
# if givenAway[team_to_check,p]:
|
||||
# possAwayOpponents[p]= [givenAway[team_to_check,p]]
|
||||
# else:
|
||||
# possAwayOpponents[p] = [ t for t in possOpponents if not givenHome[t,t_pot[team_to_check]]]
|
||||
|
||||
# while no_solution_found:
|
||||
# newgames = []
|
||||
# for p in pots_to_check:
|
||||
# random_home= random.choice(possHomeOpponents[p])
|
||||
# random_away= random.choice(possAwayOpponents[p])
|
||||
# print (p,"-> " , random_home==random_away, t_name[random_home], "\t ", t_name[random_away] )
|
||||
# newgames+=[(team_to_check,random_home), (random_away,team_to_check) ]
|
||||
# if random_home!=random_away and check_feasible(oldgames+newgames):
|
||||
# no_solution_found = False
|
||||
|
||||
# newgames = [gm for gm in newgames if gm not in oldgames]
|
||||
# return newgames
|
||||
|
||||
|
||||
# %%
|
||||
|
||||
|
||||
|
||||
def simulate_draws(filename,n):
|
||||
|
||||
print("RUNNING ASYNC",filename)
|
||||
|
||||
for i in range(1, n):
|
||||
if i % 100 == 0:
|
||||
print("RUNNING ASYNC",filename,i)
|
||||
# start_time = time.time()
|
||||
# n_computations = 0
|
||||
# check_time = 0
|
||||
# total_comp_time = 0
|
||||
|
||||
|
||||
possible_opps = {}
|
||||
for pos in range(8):
|
||||
p = pos//2+1
|
||||
teams_from_pot = list(teamObjects.filter(pot=p).values('id','country'))
|
||||
possible_opps[pos] = {
|
||||
t['id']: [t2['id'] for t2 in teams_from_pot if t2['country'] != t['country']] for t in teams
|
||||
}
|
||||
|
||||
sol_opps = {
|
||||
(t['id'],p):None
|
||||
for t in teams for p in range(8)
|
||||
}
|
||||
fixed_games = []
|
||||
feasible = True
|
||||
|
||||
for p in range(1,5):
|
||||
currentPot = list(teamObjects.filter(pot=p).values_list('id', flat=True))
|
||||
|
||||
while(feasible and currentPot):
|
||||
new_team = currentPot.pop(random.randint(0,len(currentPot)-1))
|
||||
for current_pos in range(8):
|
||||
while (feasible and sol_opps[new_team,current_pos] == None):
|
||||
try:
|
||||
new_opponent = random.choice(possible_opps[current_pos][new_team])
|
||||
except:
|
||||
feasible = False
|
||||
print("INFEASIBLE")
|
||||
print(sol_opps)
|
||||
print(fixed_games)
|
||||
print(possible_opps)
|
||||
print(new_team,current_pos)
|
||||
print(possible_opps[current_pos][new_team])
|
||||
|
||||
|
||||
exit()
|
||||
|
||||
if sol_opps[new_opponent,(2*p-1)-(current_pos % 2)] == None:
|
||||
new_game = (new_team,new_opponent) if current_pos % 2 == 0 else (new_opponent,new_team)
|
||||
# n_computations += 1
|
||||
# tt = time.time()
|
||||
# check, comp_time = check_feasible_fix(fixed_games+[new_game])
|
||||
# check_time += time.time()-tt
|
||||
# total_comp_time += comp_time
|
||||
if check_feasible_fix(fixed_games+[new_game]):
|
||||
sol_opps[new_team,current_pos] = new_opponent
|
||||
sol_opps[new_opponent,(2*p-1)-(current_pos % 2)] = new_team
|
||||
fixed_games.append(new_game)
|
||||
if new_opponent in possible_opps[(2*p-1)-(current_pos % 2)][new_team]:
|
||||
possible_opps[(2*p-1)-(current_pos % 2)][new_team].remove(new_opponent)
|
||||
possible_opps[current_pos][new_team].remove(new_opponent)
|
||||
else:
|
||||
possible_opps[current_pos][new_team].remove(new_opponent)
|
||||
|
||||
|
||||
# for p in [1,2,3,4]:
|
||||
# # for p in [4,3,2,1]:
|
||||
# currentPot = list(teamObjects.filter(pot=p).values_list('id', flat=True))
|
||||
|
||||
# while(feasible and currentPot):
|
||||
# # Draw Team
|
||||
# new_team = currentPot.pop(random.randint(0,len(currentPot)-1))
|
||||
# draw_index_dict[new_team] = draw_index
|
||||
# draw_index += 1
|
||||
|
||||
# # print("New team",new_team,getTeamById[new_team])
|
||||
# for pos in range(8):
|
||||
# # Skip if already drawn
|
||||
# if sol_opps[new_team,pos]:
|
||||
# continue
|
||||
# # Update possible opponents
|
||||
# opponent_pool = []
|
||||
# for new_opponent in possible_opps[pos][new_team]:
|
||||
# if sol_opps[new_opponent,(2*p-1)-(pos % 2)] != None:
|
||||
# continue
|
||||
# # print(f"---> ALREADY DRAWN {pos}: {getTeamById[new_opponent]}")
|
||||
# else:
|
||||
# new_game = (new_team,new_opponent) if pos % 2 == 0 else (new_opponent,new_team)
|
||||
# n_computations += 1
|
||||
# tt = time.time()
|
||||
# feasible = check_feasible(fixed_games+[new_game])
|
||||
# comp_time += time.time()-tt
|
||||
# if feasible:
|
||||
# opponent_pool.append(new_opponent)
|
||||
# else:
|
||||
# # print(f"---> CANNOT DRAW {pos}: {[getTeamById[ttt] for ttt in new_game]}")
|
||||
# num_combinatorial_clashes[new_team,pos] += 1
|
||||
# num_possible_opps[new_team,pos] = len(opponent_pool)
|
||||
# # Draw random opponent
|
||||
# new_opponent = random.choice(opponent_pool)
|
||||
# new_game = (new_team,new_opponent) if pos % 2 == 0 else (new_opponent,new_team)
|
||||
# # if not check_feasible(fixed_games+[new_game]):
|
||||
# # print("INFEASIBLE")
|
||||
# # print("POSSOPS AFTER",[getTeamById[tt] for tt in possible_opps[pos][new_team]])
|
||||
# # print(f"{p} - {pos} - {getTeamById[sol_opps[new_opponent,(2*p-1)-(pos % 2)]]}")
|
||||
# # feasible = False
|
||||
# # break
|
||||
|
||||
# sol_opps[new_team,pos] = new_opponent
|
||||
# sol_opps[new_opponent,(2*p-1)-(pos % 2)] = new_team
|
||||
# if pos % 2 == 0:
|
||||
# possible_opps[pos+1][new_team].remove(new_opponent)
|
||||
# fixed_games.append(new_game)
|
||||
|
||||
|
||||
# print("COMPUTATIONS",n_computations)
|
||||
# print("TIME\t",time.time()-start_time)
|
||||
# print("CHECK\t",check_time)
|
||||
# print("COMP\t",total_comp_time)
|
||||
with open(filename+'.csv', "a") as f:
|
||||
for t in teams:
|
||||
f.write(f"{i},{t['id']},{';'.join([str(sol_opps[t['id'],p]) for p in range(8)])}\n")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# for game in fixed_games:
|
||||
# if game[0] == new_team or game[1] == new_team:
|
||||
# print("\t"," vs ".join([getTeamById[tt] for tt in game]))
|
||||
# print(f"--- > {draw_index_dict[new_team]}")
|
||||
# for pos in range(8):
|
||||
# print(f"--- > {pos} - {num_possible_opps[new_team,pos]}")
|
||||
|
||||
# iterate over h/a-encounters
|
||||
# for current_pos in range(8):
|
||||
# while (sol_opps[new_team,current_pos] == None):
|
||||
# # print(possible_opps[current_pos][new_team])
|
||||
# # draw opponent
|
||||
# new_opponent = random.choice(possible_opps[current_pos][new_team])
|
||||
# print("\tNEW OPP",new_opponent,getTeamById[new_opponent])
|
||||
# new_game = (new_team,new_opponent) if current_pos % 2 == 0 else (new_opponent,new_team)
|
||||
# if check_feasible(fixed_games+[new_game]):
|
||||
# # print("FEASIBLE",new_game,[getTeamById[tt] for tt in new_game])
|
||||
# sol_opps[new_team,current_pos] = new_opponent
|
||||
# sol_opps[new_opponent,(2*p-1)-(current_pos % 2)] = new_team
|
||||
# fixed_games.append(new_game)
|
||||
# possible_opps[current_pos][new_team].remove(new_opponent)
|
||||
# else:
|
||||
# possible_opps[current_pos][new_team].remove(new_opponent)
|
||||
# %%
|
||||
|
||||
|
||||
# # SOLUTION
|
||||
# for g in fixed_games:
|
||||
# print(getTeamById[g[0]],getTeamById[g[1]])
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# n = sys.maxsize
|
||||
|
||||
# pool = Pool()
|
||||
# result = {}
|
||||
# answer = {}
|
||||
# n_threads = cpu_count()
|
||||
# # n_threads = 1
|
||||
|
||||
# for cpu in range(n_threads):
|
||||
# result[cpu] = pool.apply_async(simulate_draws, args=(f'thread_{cpu}_pot_by_pot', n,))
|
||||
|
||||
# for cpu in range(n_threads):
|
||||
# answer[cpu] = result[cpu].get()
|
||||
|
||||
|
||||
# %%
|
||||
n = sys.maxsize
|
||||
simulate_draws('test', n)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# %%
|
||||
|
||||
|
||||
307
uefa/cycle24/simulations/debugging/debug_draws.py
Executable file
307
uefa/cycle24/simulations/debugging/debug_draws.py
Executable file
@ -0,0 +1,307 @@
|
||||
import pulp
|
||||
from pulp import lpSum, XPRESS, GUROBI, PULP_CBC_CMD
|
||||
|
||||
"""
|
||||
##########################################################################################################################
|
||||
##########################################################################################################################
|
||||
"""
|
||||
|
||||
|
||||
teams = [{'id': 3696, 'country': 'FRA', 'pot': 4, 'shortname': 'Lens'},
|
||||
{'id': 3697, 'country': 'GER', 'pot': 4, 'shortname': 'Unio'},
|
||||
{'id': 3698, 'country': 'ENG', 'pot': 4, 'shortname': 'Newc'},
|
||||
{'id': 3699, 'country': 'ESP', 'pot': 4, 'shortname': 'Soci'},
|
||||
{'id': 3700, 'country': 'SUI', 'pot': 3, 'shortname': 'Youn'},
|
||||
{'id': 3701, 'country': 'NED', 'pot': 3, 'shortname': 'Feye'},
|
||||
{'id': 3702, 'country': 'ENG', 'pot': 1, 'shortname': 'ManU'},
|
||||
{'id': 3730, 'country': 'SRB', 'pot': 3, 'shortname': 'Crve'},
|
||||
{'id': 3732, 'country': 'ITA', 'pot': 1, 'shortname': 'Inte'},
|
||||
{'id': 3734, 'country': 'ITA', 'pot': 2, 'shortname': 'Napo'},
|
||||
{'id': 3756, 'country': 'ITA', 'pot': 3, 'shortname': 'Mila'},
|
||||
{'id': 3757, 'country': 'SCO', 'pot': 4, 'shortname': 'Celt'},
|
||||
{'id': 3758, 'country': 'DEN', 'pot': 3, 'shortname': 'Cope'},
|
||||
{'id': 3760, 'country': 'NED', 'pot': 3, 'shortname': 'PSV'},
|
||||
{'id': 3761, 'country': 'ENG', 'pot': 2, 'shortname': 'Arse'},
|
||||
{'id': 3762, 'country': 'ESP', 'pot': 1, 'shortname': 'Sevi'},
|
||||
{'id': 3764, 'country': 'ENG', 'pot': 1, 'shortname': 'Live'},
|
||||
{'id': 3765, 'country': 'UKR', 'pot': 2, 'shortname': 'Shak'},
|
||||
{'id': 3771, 'country': 'ITA', 'pot': 3, 'shortname': 'Atal'},
|
||||
{'id': 3853, 'country': 'FRA', 'pot': 4, 'shortname': 'Mars'},
|
||||
{'id': 3870, 'country': 'TUR', 'pot': 4, 'shortname': 'Gala'},
|
||||
{'id': 3894, 'country': 'ESP', 'pot': 1, 'shortname': 'Barc'},
|
||||
{'id': 3895, 'country': 'ITA', 'pot': 3, 'shortname': 'Lazi'},
|
||||
{'id': 3898, 'country': 'ESP', 'pot': 2, 'shortname': 'Atle'},
|
||||
{'id': 3904, 'country': 'AZE', 'pot': 4, 'shortname': 'Qara'},
|
||||
{'id': 3925, 'country': 'BEL', 'pot': 4, 'shortname': 'Antw'},
|
||||
{'id': 3926, 'country': 'GER', 'pot': 2, 'shortname': 'Leip'},
|
||||
{'id': 3928, 'country': 'POR', 'pot': 3, 'shortname': 'Brag'},
|
||||
{'id': 3930, 'country': 'POR', 'pot': 2, 'shortname': 'Benf'},
|
||||
{'id': 3932, 'country': 'GER', 'pot': 1, 'shortname': 'Baye'},
|
||||
{'id': 3933, 'country': 'ESP', 'pot': 1, 'shortname': 'Real'},
|
||||
{'id': 3935, 'country': 'FRA', 'pot': 1, 'shortname': 'PSG'},
|
||||
{'id': 3936, 'country': 'GER', 'pot': 2, 'shortname': 'Dort'},
|
||||
{'id': 3937, 'country': 'POR', 'pot': 2, 'shortname': 'Port'},
|
||||
{'id': 3938, 'country': 'AUT', 'pot': 2, 'shortname': 'Salz'},
|
||||
{'id': 3940, 'country': 'ENG', 'pot': 1, 'shortname': 'Manc'}]
|
||||
|
||||
getTeamById = {3702: '(ENG) Manchester United FC',
|
||||
3764: '(ENG) Liverpool FC',
|
||||
3940: '(ENG) Manchester City FC',
|
||||
3762: '(ESP) Sevilla FC',
|
||||
3894: '(ESP) FC Barcelona',
|
||||
3933: '(ESP) Real Madrid CF',
|
||||
3935: '(FRA) Paris Saint-Germain',
|
||||
3932: '(GER) FC Bayern München',
|
||||
3732: '(ITA) FC Internazionale Milano',
|
||||
3938: '(AUT) FC Salzburg',
|
||||
3761: '(ENG) Arsenal FC',
|
||||
3898: '(ESP) Club Atlético de Madrid',
|
||||
3926: '(GER) RB Leipzig',
|
||||
3936: '(GER) Borussia Dortmund',
|
||||
3734: '(ITA) SSC Napoli',
|
||||
3930: '(POR) SL Benfica',
|
||||
3937: '(POR) FC Porto',
|
||||
3765: '(UKR) FC Shakhtar Donetsk',
|
||||
3758: '(DEN) F.C. Copenhagen',
|
||||
3756: '(ITA) AC Milan',
|
||||
3771: '(ITA) Atalanta BC',
|
||||
3895: '(ITA) S.S. Lazio',
|
||||
3701: '(NED) Feyenoord',
|
||||
3760: '(NED) PSV Eindhoven',
|
||||
3928: '(POR) SC Braga',
|
||||
3730: '(SRB) FK Crvena zvezda',
|
||||
3700: '(SUI) BSC Young Boys',
|
||||
3904: '(AZE) Qarabağ FK',
|
||||
3925: '(BEL) R. Antwerp FC',
|
||||
3698: '(ENG) Newcastle United FC',
|
||||
3699: '(ESP) Real Sociedad de Fútbol',
|
||||
3696: '(FRA) RC Lens',
|
||||
3853: '(FRA) Olympique de Marseille',
|
||||
3697: '(GER) 1. FC Union Berlin',
|
||||
3757: '(SCO) Celtic FC',
|
||||
3870: '(TUR) Galatasaray A.Ş.'}
|
||||
|
||||
pot = {1: [{'id': 3702, 'country': 'ENG', 'pot': 1, 'shortname': 'ManU'},
|
||||
{'id': 3764, 'country': 'ENG', 'pot': 1, 'shortname': 'Liver'},
|
||||
{'id': 3940, 'country': 'ENG', 'pot': 1, 'shortname': 'Manch'},
|
||||
{'id': 3762, 'country': 'ESP', 'pot': 1, 'shortname': 'Sevil'},
|
||||
{'id': 3894, 'country': 'ESP', 'pot': 1, 'shortname': 'Barce'},
|
||||
{'id': 3933, 'country': 'ESP', 'pot': 1, 'shortname': 'Real '},
|
||||
{'id': 3935, 'country': 'FRA', 'pot': 1, 'shortname': 'PSG'},
|
||||
{'id': 3932, 'country': 'GER', 'pot': 1, 'shortname': 'Bayer'},
|
||||
{'id': 3732, 'country': 'ITA', 'pot': 1, 'shortname': 'Inter'}],
|
||||
2: [{'id': 3938, 'country': 'AUT', 'pot': 2, 'shortname': 'Salzb'},
|
||||
{'id': 3761, 'country': 'ENG', 'pot': 2, 'shortname': 'Arsen'},
|
||||
{'id': 3898, 'country': 'ESP', 'pot': 2, 'shortname': 'Atlét'},
|
||||
{'id': 3926, 'country': 'GER', 'pot': 2, 'shortname': 'Leipz'},
|
||||
{'id': 3936, 'country': 'GER', 'pot': 2, 'shortname': 'Dortm'},
|
||||
{'id': 3734, 'country': 'ITA', 'pot': 2, 'shortname': 'Napol'},
|
||||
{'id': 3930, 'country': 'POR', 'pot': 2, 'shortname': 'Benfi'},
|
||||
{'id': 3937, 'country': 'POR', 'pot': 2, 'shortname': 'Porto'},
|
||||
{'id': 3765, 'country': 'UKR', 'pot': 2, 'shortname': 'Shakh'}],
|
||||
3: [{'id': 3758, 'country': 'DEN', 'pot': 3, 'shortname': 'Copen'},
|
||||
{'id': 3756, 'country': 'ITA', 'pot': 3, 'shortname': 'Milan'},
|
||||
{'id': 3771, 'country': 'ITA', 'pot': 3, 'shortname': 'Atala'},
|
||||
{'id': 3895, 'country': 'ITA', 'pot': 3, 'shortname': 'Lazio'},
|
||||
{'id': 3701, 'country': 'NED', 'pot': 3, 'shortname': 'Feyen'},
|
||||
{'id': 3760, 'country': 'NED', 'pot': 3, 'shortname': 'PSV'},
|
||||
{'id': 3928, 'country': 'POR', 'pot': 3, 'shortname': 'Braga'},
|
||||
{'id': 3730, 'country': 'SRB', 'pot': 3, 'shortname': 'Crven'},
|
||||
{'id': 3700, 'country': 'SUI', 'pot': 3, 'shortname': 'Young'}],
|
||||
4: [{'id': 3904, 'country': 'AZE', 'pot': 4, 'shortname': 'Qarab'},
|
||||
{'id': 3925, 'country': 'BEL', 'pot': 4, 'shortname': 'Antwe'},
|
||||
{'id': 3698, 'country': 'ENG', 'pot': 4, 'shortname': 'Newca'},
|
||||
{'id': 3699, 'country': 'ESP', 'pot': 4, 'shortname': 'Socied'},
|
||||
{'id': 3696, 'country': 'FRA', 'pot': 4, 'shortname': 'Lens'},
|
||||
{'id': 3853, 'country': 'FRA', 'pot': 4, 'shortname': 'Marse'},
|
||||
{'id': 3697, 'country': 'GER', 'pot': 4, 'shortname': 'Union'},
|
||||
{'id': 3757, 'country': 'SCO', 'pot': 4, 'shortname': 'Celti'},
|
||||
{'id': 3870, 'country': 'TUR', 'pot': 4, 'shortname': 'Galat'}]}
|
||||
|
||||
|
||||
teams_from_country = {'NED': [{'id': 3701, 'country': 'NED', 'pot': 3, 'shortname': 'Feye'},
|
||||
{'id': 3760, 'country': 'NED', 'pot': 3, 'shortname': 'PSV'}],
|
||||
'UKR': [{'id': 3765, 'country': 'UKR', 'pot': 2, 'shortname': 'Shak'}],
|
||||
'ENG': [{'id': 3702, 'country': 'ENG', 'pot': 1, 'shortname': 'ManU'},
|
||||
{'id': 3764, 'country': 'ENG', 'pot': 1, 'shortname': 'Live'},
|
||||
{'id': 3940, 'country': 'ENG', 'pot': 1, 'shortname': 'Manc'},
|
||||
{'id': 3761, 'country': 'ENG', 'pot': 2, 'shortname': 'Arse'},
|
||||
{'id': 3698, 'country': 'ENG', 'pot': 4, 'shortname': 'Newc'}],
|
||||
'POR': [{'id': 3930, 'country': 'POR', 'pot': 2, 'shortname': 'Benf'},
|
||||
{'id': 3937, 'country': 'POR', 'pot': 2, 'shortname': 'Port'},
|
||||
{'id': 3928, 'country': 'POR', 'pot': 3, 'shortname': 'Brag'}],
|
||||
'GER': [{'id': 3932, 'country': 'GER', 'pot': 1, 'shortname': 'Baye'},
|
||||
{'id': 3926, 'country': 'GER', 'pot': 2, 'shortname': 'Leip'},
|
||||
{'id': 3936, 'country': 'GER', 'pot': 2, 'shortname': 'Dort'},
|
||||
{'id': 3697, 'country': 'GER', 'pot': 4, 'shortname': 'Unio'}],
|
||||
'DEN': [{'id': 3758, 'country': 'DEN', 'pot': 3, 'shortname': 'Cope'}],
|
||||
'FRA': [{'id': 3935, 'country': 'FRA', 'pot': 1, 'shortname': 'PSG'},
|
||||
{'id': 3696, 'country': 'FRA', 'pot': 4, 'shortname': 'Lens'},
|
||||
{'id': 3853, 'country': 'FRA', 'pot': 4, 'shortname': 'Mars'}],
|
||||
'AZE': [{'id': 3904, 'country': 'AZE', 'pot': 4, 'shortname': 'Qara'}],
|
||||
'TUR': [{'id': 3870, 'country': 'TUR', 'pot': 4, 'shortname': 'Gala'}],
|
||||
'ITA': [{'id': 3732, 'country': 'ITA', 'pot': 1, 'shortname': 'Inte'},
|
||||
{'id': 3734, 'country': 'ITA', 'pot': 2, 'shortname': 'Napo'},
|
||||
{'id': 3756, 'country': 'ITA', 'pot': 3, 'shortname': 'Mila'},
|
||||
{'id': 3771, 'country': 'ITA', 'pot': 3, 'shortname': 'Atal'},
|
||||
{'id': 3895, 'country': 'ITA', 'pot': 3, 'shortname': 'Lazi'}],
|
||||
'BEL': [{'id': 3925, 'country': 'BEL', 'pot': 4, 'shortname': 'Antw'}],
|
||||
'SRB': [{'id': 3730, 'country': 'SRB', 'pot': 3, 'shortname': 'Crve'}],
|
||||
'SUI': [{'id': 3700, 'country': 'SUI', 'pot': 3, 'shortname': 'Youn'}],
|
||||
'SCO': [{'id': 3757, 'country': 'SCO', 'pot': 4, 'shortname': 'Celt'}],
|
||||
'ESP': [{'id': 3762, 'country': 'ESP', 'pot': 1, 'shortname': 'Sevi'},
|
||||
{'id': 3894, 'country': 'ESP', 'pot': 1, 'shortname': 'Barc'},
|
||||
{'id': 3933, 'country': 'ESP', 'pot': 1, 'shortname': 'Real'},
|
||||
{'id': 3898, 'country': 'ESP', 'pot': 2, 'shortname': 'Atle'},
|
||||
{'id': 3699, 'country': 'ESP', 'pot': 4, 'shortname': 'Soci'}],
|
||||
'AUT': [{'id': 3938, 'country': 'AUT', 'pot': 2, 'shortname': 'Salz'}]}
|
||||
|
||||
countries = ['NED',
|
||||
'UKR',
|
||||
'ENG',
|
||||
'POR',
|
||||
'GER',
|
||||
'DEN',
|
||||
'FRA',
|
||||
'AZE',
|
||||
'TUR',
|
||||
'ITA',
|
||||
'BEL',
|
||||
'SRB',
|
||||
'SUI',
|
||||
'SCO',
|
||||
'ESP',
|
||||
'AUT']
|
||||
|
||||
|
||||
|
||||
|
||||
fixed_games = [(3940, 3894), (3933, 3940), (3940, 3937), (3765, 3940), (3940, 3895), (3700, 3940), (3940, 3696),
|
||||
(3925, 3940), (3702, 3935), (3894, 3702), (3702, 3926), (3937, 3702), (3702, 3700), (3758, 3702),
|
||||
(3702, 3699), (3757, 3702), (3932, 3762), (3732, 3932), (3932, 3938), (3761, 3932), (3932, 3730),
|
||||
(3701, 3932), (3932, 3870), (3853, 3932), (3764, 3933), (3935, 3764), (3764, 3936), (3898, 3764),
|
||||
(3764, 3756), (3928, 3764), (3764, 3925), (3904, 3764), (3762, 3732), (3762, 3761), (3930, 3762),
|
||||
(3762, 3701), (3760, 3762), (3762, 3697), (3698, 3762), (3732, 3765), (3926, 3732), (3732, 3928),
|
||||
(3730, 3732), (3732, 3698), (3870, 3732), (3894, 3930), (3938, 3894), (3894, 3758)]
|
||||
|
||||
|
||||
|
||||
"""
|
||||
##########################################################################################################################
|
||||
##########################################################################################################################
|
||||
"""
|
||||
|
||||
model = pulp.LpProblem(f"Draws", pulp.LpMinimize)
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
x[t1['id'], t2['id']] = pulp.LpVariable('x_'+str(t1['id'])+'_'+str(t2['id']),lowBound=0, upBound=1, cat=pulp.LpInteger)
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
model += lpSum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1
|
||||
model += lpSum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1
|
||||
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
model += lpSum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
model += x[t1,t2] + x[t2,t1] <= 1
|
||||
|
||||
# FIXATIONS
|
||||
for (t1,t2) in fixed_games:
|
||||
model += x[t1,t2] == 1
|
||||
|
||||
model.solve(XPRESS(msg=1))
|
||||
|
||||
if model.status in [-1,-2]:
|
||||
print("INFEASIBLE")
|
||||
else:
|
||||
print("SUCCESS")
|
||||
|
||||
|
||||
|
||||
|
||||
"""
|
||||
##########################################################################################################################
|
||||
##########################################################################################################################
|
||||
"""
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# if feasible:
|
||||
# # GET GAMES
|
||||
# games = []
|
||||
# for key in sol.keys():
|
||||
# if sol[key].value() != 0:
|
||||
# games.append(key)
|
||||
|
||||
|
||||
# # CHECK AGAIN
|
||||
# check_feasible(games)
|
||||
|
||||
|
||||
# # WRITE SOL '.html'
|
||||
# teams = sorted(teams, key=lambda k: k['pot'])
|
||||
# sol = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
|
||||
# sol += " \
|
||||
# <style> \
|
||||
# table, th, td { \
|
||||
# border: 1px solid black; \
|
||||
# border-collapse: collapse; \
|
||||
# text-align: center; \
|
||||
# min-width:40px; \
|
||||
# padding:3px; \
|
||||
# margin: 3px; \
|
||||
# font-family : Arial;\
|
||||
# } \
|
||||
# h1 {\
|
||||
# font-family : Arial;\
|
||||
# }\
|
||||
# \
|
||||
# #etable td:nth-child(10),#etable th:nth-child(10) { border-right: 5px solid black; }\
|
||||
# #etable td:nth-child(19),#etable th:nth-child(19) { border-right: 5px solid black; }\
|
||||
# #etable td:nth-child(28),#etable th:nth-child(28) { border-right: 5px solid black; }\
|
||||
# tr:nth-child(9) { border-bottom: 5px solid black; }\
|
||||
# tr:nth-child(18) { border-bottom: 5px solid black; }\
|
||||
# tr:nth-child(27) { border-bottom: 5px solid black; }\
|
||||
# </style> \
|
||||
# "
|
||||
# sol += "<table id='etable' style='border:5px solid black'>\n"
|
||||
# sol += "<thead>\n"
|
||||
# sol += "<tr>"
|
||||
# sol += "<th></th>"
|
||||
# sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot A</th>"
|
||||
# sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot B</th>"
|
||||
# sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot C</th>"
|
||||
# sol += "<th colspan=9>Pot D</th>"
|
||||
# sol += "</tr>"
|
||||
# sol += "<tr>\n"
|
||||
# sol += f"<th></th>\n"
|
||||
# for t in teams:
|
||||
# sol += f"<th>{getTeamById[t['id']]}</th>\n"
|
||||
# sol += "</tr>\n"
|
||||
# sol += "</thead>\n"
|
||||
# sol += "<tbody>\n"
|
||||
# for t1 in teams:
|
||||
# sol += "<tr>\n"
|
||||
# sol += f"<td>{getTeamById[t1['id']]}</td>"
|
||||
# for t2 in teams:
|
||||
# if (t1['id'],t2['id']) in games:
|
||||
# sol += f"<td>{t2['country']}</td>"
|
||||
# elif (t2['id'],t1['id']) in games:
|
||||
# sol += f"<td>@{t2['country']}</td>"
|
||||
# else:
|
||||
# sol += f"<td></td>"
|
||||
# sol += "</tr>\n"
|
||||
# sol += "</tbody>\n"
|
||||
# sol += "</table>\n"
|
||||
|
||||
# with open(f'debug_draws.html', 'w') as f:
|
||||
# f.write(sol)
|
||||
|
||||
18
uefa/cycle24/simulations/debugging/debug_xpress.py
Executable file
18
uefa/cycle24/simulations/debugging/debug_xpress.py
Executable file
@ -0,0 +1,18 @@
|
||||
import xpress as xp
|
||||
|
||||
m = xp.problem()
|
||||
m.read("debug.mps")
|
||||
|
||||
print("Set presolve to 1")
|
||||
m.setControl('presolve',1)
|
||||
m.optimize()
|
||||
print("solution status code: ", m.getProbStatus(), " -->",
|
||||
m.getProbStatusString())
|
||||
|
||||
|
||||
print("\n\n")
|
||||
print("Set presolve to 0")
|
||||
m.setControl('presolve',0)
|
||||
m.optimize()
|
||||
print("solution status code: ", m.getProbStatus(), " -->",
|
||||
m.getProbStatusString())
|
||||
492
uefa/cycle24/simulations/double_draws/drawsimulation_october_gurobi_double.py
Executable file
492
uefa/cycle24/simulations/double_draws/drawsimulation_october_gurobi_double.py
Executable file
@ -0,0 +1,492 @@
|
||||
# %%
|
||||
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"
|
||||
|
||||
from leagues import settings
|
||||
settings.DATABASES['default']['NAME'] = PROJECT_PATH+'/db.sqlite3'
|
||||
# settings.DATABASES['default']['ENGINE'] = 'django.db.backends.postgresql_psycopg2'
|
||||
# settings.DATABASES['default']['HOST'] = '0.0.0.0'
|
||||
# settings.DATABASES['default']['PORT'] = '5432'
|
||||
# settings.DATABASES['default']['USER'] = 'postgres'
|
||||
# settings.DATABASES['default']['PASSWORD'] = 'secret123'
|
||||
# settings.DATABASES['default']['NAME'] = 'mypgsqldb'
|
||||
# settings.DATABASES['default']['ATOMIC_REQUESTS'] = False
|
||||
# settings.DATABASES['default']['AUTOCOMMIT'] = True
|
||||
# settings.DATABASES['default']['CONN_MAX_AGE'] = 0
|
||||
# settings.DATABASES['default']['CONN_HEALTH_CHECKS'] = False
|
||||
# settings.DATABASES['default']['OPTIONS'] = {}
|
||||
|
||||
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["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["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprs.jar"
|
||||
os.environ["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprb.jar" + os.pathsep + os.environ["CLASSPATH"]
|
||||
os.environ["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprm.jar" + os.pathsep + os.environ["CLASSPATH"]
|
||||
os.environ["PATH"] = os.environ["XPRESSDIR"] + "/bin" + os.pathsep + os.environ["PATH"]
|
||||
|
||||
|
||||
import django
|
||||
django.setup()
|
||||
|
||||
from scheduler.models import *
|
||||
import csv
|
||||
from multiprocessing import Pool, cpu_count
|
||||
import random
|
||||
import time
|
||||
import pulp
|
||||
from pulp import lpSum, value, XPRESS, GUROBI, PULP_CBC_CMD
|
||||
import gurobipy as gp
|
||||
from gurobipy import GRB
|
||||
import xpress as xp
|
||||
# xp.controls.outputlog = 0
|
||||
|
||||
|
||||
|
||||
scenario = Scenario.objects.get(id=34)
|
||||
|
||||
# %%
|
||||
|
||||
teamObjects = Team.objects.filter(season=scenario.season,active=True).order_by('pot')
|
||||
teams = teamObjects.values('id','country','pot','name')
|
||||
|
||||
getTeamById = {}
|
||||
for t in teamObjects:
|
||||
getTeamById[t.id] = f"({t.pot}) {t.name}"
|
||||
|
||||
getCountryById = {}
|
||||
for t in teamObjects:
|
||||
getCountryById[t.id] = t.country
|
||||
|
||||
|
||||
countries = list(set(teamObjects.values_list('country', flat=True)))
|
||||
teams_from_country = {
|
||||
c:[t for t in teams if t['country']==c] for c in countries
|
||||
}
|
||||
|
||||
pot = {}
|
||||
for i in teamObjects.values_list('pot',flat=True).distinct():
|
||||
pot[i] = list(teams.filter(pot=i))
|
||||
|
||||
teams = list(teams)
|
||||
|
||||
|
||||
|
||||
|
||||
# fixed_games = [(3940, 3894), (3933, 3940), (3940, 3937), (3765, 3940), (3940, 3895), (3700, 3940), (3940, 3696), (3925, 3940), (3702, 3935), (3894, 3702), (3702, 3926), (3937, 3702), (3702, 3700), (3758, 3702), (3702, 3699), (3757, 3702), (3932, 3762), (3732, 3932), (3932, 3938), (3761, 3932), (3932, 3730), (3701, 3932), (3932, 3870), (3853, 3932), (3764, 3933), (3935, 3764), (3764, 3936), (3898, 3764), (3764, 3756), (3928, 3764), (3764, 3925), (3904, 3764), (3762, 3732), (3762, 3761), (3930, 3762), (3762, 3701), (3760, 3762), (3762, 3697), (3698, 3762), (3732, 3765), (3926, 3732), (3732, 3928), (3730, 3732), (3732, 3698), (3870, 3732), (3894, 3930), (3938, 3894), (3894, 3758)]
|
||||
|
||||
|
||||
|
||||
def check_feasible_pulp(fixed_games):
|
||||
|
||||
model = pulp.LpProblem(f"Draws", pulp.LpMinimize)
|
||||
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
x[t1['id'], t2['id']] = pulp.LpVariable('x_'+str(t1['id'])+'_'+str(t2['id']),lowBound=0, upBound=1, cat=pulp.LpInteger)
|
||||
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
# model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
model += lpSum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1
|
||||
model += lpSum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1
|
||||
|
||||
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 3)
|
||||
model += lpSum(x[t['id'],t2['id']] for t2 in teams_from_country[c]) <= 2
|
||||
|
||||
# FIXATIONS
|
||||
for (t1,t2) in fixed_games:
|
||||
# print("FIXING",t1,t2)
|
||||
# model.addConstraint(x[t1,t2] == 1)
|
||||
model += x[t1,t2] == 1
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
model += x[t1,t2] + x[t2,t1] <= 1, f'directed_{t1}_{t2}'
|
||||
# model.addConstraint(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
model += lpSum(random.uniform(0,1)*x[key] for key in x.keys())
|
||||
tt =time.time()
|
||||
model.solve(XPRESS(msg=0,timeLimit=120,keepFiles=0))
|
||||
comp_time = time.time()-tt
|
||||
|
||||
if model.status in [-1,-2]:
|
||||
return False, comp_time
|
||||
else:
|
||||
return True, comp_time
|
||||
|
||||
|
||||
|
||||
|
||||
model = gp.Model('Draws')
|
||||
model.Params.OutputFlag = 0
|
||||
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
# x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer)
|
||||
x[t1['id'], t2['id']] = model.addVar(vtype=GRB.BINARY)
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
model.addConstr(gp.quicksum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
model.addConstr(gp.quicksum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
model.addConstr(gp.quicksum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2)
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
model.addConstr(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
|
||||
|
||||
|
||||
def check_feasible_gurobi(fixed_games):
|
||||
|
||||
# FIXATIONS
|
||||
for key in x.keys():
|
||||
if key in fixed_games:
|
||||
x[key].lb = 1
|
||||
else:
|
||||
x[key].lb = 0
|
||||
|
||||
model.update()
|
||||
|
||||
# tt =time.time()
|
||||
# model.solve()
|
||||
model.optimize()
|
||||
# comp_time = time.time()-tt
|
||||
|
||||
|
||||
if model.Status == GRB.OPTIMAL:
|
||||
return True, 0
|
||||
else:
|
||||
# print("INFEASIBLE FOUND")
|
||||
return False, 0
|
||||
|
||||
|
||||
def check_feasible(fixed_games):
|
||||
model = xp.problem(name='Draws', sense=xp.minimize)
|
||||
model.setControl ('outputlog', 1)
|
||||
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer)
|
||||
|
||||
model.addVariable(x)
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2)
|
||||
|
||||
# FIXATIONS
|
||||
for (t1,t2) in fixed_games:
|
||||
# print("FIXING",t1,t2)
|
||||
model.addConstraint(x[t1,t2] == 1)
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
model.addConstraint(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
|
||||
tt =time.time()
|
||||
model.solve()
|
||||
comp_time = time.time()-tt
|
||||
|
||||
|
||||
if model.getProbStatus() != 6:
|
||||
# print("INFEASIBLE FOUND")
|
||||
return False, comp_time
|
||||
else:
|
||||
return True, comp_time
|
||||
|
||||
|
||||
|
||||
|
||||
# model = xp.problem(name='Draws', sense=xp.minimize)
|
||||
# model.setControl ('outputlog', 0)
|
||||
|
||||
# x = {}
|
||||
# for t1 in teams:
|
||||
# for t2 in teams:
|
||||
# if t1['country'] != t2['country']:
|
||||
# x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer)
|
||||
|
||||
# model.addVariable(x)
|
||||
|
||||
# # REQUIREMENTS
|
||||
# for t in teams:
|
||||
# for r in range(1,5):
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
# model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
# for c in countries:
|
||||
# if c != t['country']:
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2)
|
||||
|
||||
# for (t1,t2) in x.keys():
|
||||
# model.addConstraint(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
def check_feasible_fix(fixed_games):
|
||||
# FIXATIONS
|
||||
# for key in x.keys():
|
||||
# if key in fixed_games:
|
||||
# # x[key].lb = 1
|
||||
# model.chgbounds([x[key]],['L'],[1])
|
||||
# else:
|
||||
# # x[key].lb = 0
|
||||
# model.chgbounds([x[key]],['L'],[0])
|
||||
|
||||
reset_bounds = [key for key in x.keys() if key not in fixed_games]
|
||||
|
||||
model.chgbounds([x[key] for key in fixed_games],['L' for _ in range(len(fixed_games))],[1 for _ in range(len(fixed_games))])
|
||||
model.chgbounds([x[key] for key in reset_bounds],['L' for _ in range(len(reset_bounds))],[0 for _ in range(len(reset_bounds))])
|
||||
|
||||
tt =time.time()
|
||||
model.solve()
|
||||
comp_time = time.time()-tt
|
||||
|
||||
if model.getProbStatus() != 6:
|
||||
# print("INFEASIBLE FOUND")
|
||||
return False, comp_time
|
||||
return False
|
||||
else:
|
||||
return True, comp_time
|
||||
return True
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
import itertools
|
||||
from itertools import permutations , product
|
||||
|
||||
def simulate_draws(filename,n):
|
||||
|
||||
print("RUNNING ASYNC",filename)
|
||||
fixed_games=None
|
||||
for i in range(1, n):
|
||||
if i % 100 == 0:
|
||||
print("RUNNING ASYNC",filename,i)
|
||||
# start_time = time.time()
|
||||
# n_computations = 0
|
||||
# check_time = 0
|
||||
# total_comp_time = 0
|
||||
|
||||
|
||||
possible_opps = {}
|
||||
for pos in range(8):
|
||||
p = pos//2+1
|
||||
teams_from_pot = list(teamObjects.filter(pot=p).values('id','country'))
|
||||
possible_opps[pos] = {
|
||||
t['id']: [t2['id'] for t2 in teams_from_pot if t2['country'] != t['country']] for t in teams
|
||||
}
|
||||
|
||||
sol_opps = {
|
||||
(t['id'],p):None
|
||||
for t in teams for p in range(8)
|
||||
}
|
||||
|
||||
sol_countries = {
|
||||
(t['id'],c):0
|
||||
for t in teams for c in countries if c != t['country']
|
||||
}
|
||||
|
||||
fixed_games = []
|
||||
feasible = True
|
||||
|
||||
for p in range(1,5):
|
||||
currentPot = list(teamObjects.filter(pot=p).values_list('id', flat=True))
|
||||
|
||||
while(feasible and currentPot):
|
||||
new_team = currentPot.pop(random.randint(0,len(currentPot)-1))
|
||||
for current_pos in range(2*(p-1),8,2):
|
||||
if sol_opps[new_team,current_pos] != None and sol_opps[new_team,current_pos+1] != None:
|
||||
continue
|
||||
|
||||
possible_opps[current_pos][new_team] = [t for t in possible_opps[current_pos][new_team] if sol_countries[new_team,getCountryById[t]] < 2 and
|
||||
sol_countries[t,getCountryById[new_team]] < 2 and sol_opps[t,(2*p-1)] == None]
|
||||
possible_opps[current_pos+1][new_team] = [t for t in possible_opps[current_pos+1][new_team] if sol_countries[new_team,getCountryById[t]] < 2 and
|
||||
sol_countries[t,getCountryById[new_team]] < 2 and sol_opps[t,(2*p-1)-1] == None]
|
||||
|
||||
list_1 = [None]
|
||||
list_2 = [None]
|
||||
if sol_opps[new_team,current_pos] == None:
|
||||
list_1 = possible_opps[current_pos][new_team]
|
||||
if sol_opps[new_team,current_pos+1] == None:
|
||||
list_2 = possible_opps[current_pos+1][new_team]
|
||||
|
||||
# unique_combinations = []
|
||||
# for i in range(len(list_1)):
|
||||
# for j in range(len(list_2)):
|
||||
# unique_combinations.append((list_1[i], list_2[j]))
|
||||
unique_combinations = list(itertools.product(list_1, list_2))
|
||||
random.shuffle(unique_combinations)
|
||||
|
||||
|
||||
no_solution_found = True
|
||||
while (no_solution_found):
|
||||
new_games = []
|
||||
# if sol_opps[new_team,current_pos] == None:
|
||||
# new_opponent1 = random.choice(possible_opps[current_pos][new_team])
|
||||
# new_games.append((new_team,new_opponent1))
|
||||
|
||||
# if sol_opps[new_team,current_pos+1] == None:
|
||||
# new_opponent2 = random.choice(possible_opps[current_pos+1][new_team])
|
||||
# new_games.append((new_opponent2,new_team))
|
||||
|
||||
new_opponent1,new_opponent2 = unique_combinations.pop()
|
||||
|
||||
if new_opponent1:
|
||||
new_games.append((new_team,new_opponent1))
|
||||
|
||||
if new_opponent2:
|
||||
new_games.append((new_opponent2,new_team))
|
||||
|
||||
# n_computations += 1
|
||||
# tt = time.time()
|
||||
check, comp_time = check_feasible_gurobi(fixed_games+new_games)
|
||||
# check_time += time.time()-tt
|
||||
# total_comp_time += comp_time
|
||||
if check:
|
||||
no_solution_found = False
|
||||
if sol_opps[new_team,current_pos] == None:
|
||||
sol_opps[new_team,current_pos] = new_opponent1
|
||||
sol_countries[new_team,getCountryById[new_opponent1]] += 1
|
||||
sol_opps[new_opponent1,(2*p-1)] = new_team
|
||||
sol_countries[new_opponent1,getCountryById[new_team]] += 1
|
||||
if new_team in possible_opps[(2*p-1)-1][new_opponent1]:
|
||||
possible_opps[(2*p-1)-1][new_opponent1].remove(new_team)
|
||||
if sol_opps[new_team,current_pos+1] == None:
|
||||
sol_opps[new_team,current_pos+1] = new_opponent2
|
||||
sol_countries[new_team,getCountryById[new_opponent2]] += 1
|
||||
sol_opps[new_opponent2,(2*p-1)-(1)] = new_team
|
||||
sol_countries[new_opponent2,getCountryById[new_team]] += 1
|
||||
if new_team in possible_opps[(2*p-1)][new_opponent2]:
|
||||
possible_opps[(2*p-1)][new_opponent2].remove(new_team)
|
||||
fixed_games += new_games
|
||||
|
||||
|
||||
|
||||
# print("COMPUTATIONS",n_computations)
|
||||
# print("TIME\t",time.time()-start_time)
|
||||
# print("CHECK\t",check_time)
|
||||
# print("COMP\t",total_comp_time)
|
||||
|
||||
|
||||
|
||||
with open(filename+'.csv', "a") as f:
|
||||
for t in teams:
|
||||
f.write(f"{i},{t['id']},{';'.join([str(sol_opps[t['id'],p]) for p in range(8)])}\n")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# WRITE SOL '.html'
|
||||
sol = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
|
||||
sol += " \
|
||||
<style> \
|
||||
table, th, td { \
|
||||
border: 1px solid black; \
|
||||
border-collapse: collapse; \
|
||||
text-align: center; \
|
||||
min-width:40px; \
|
||||
padding:3px; \
|
||||
margin: 3px; \
|
||||
font-family : Arial;\
|
||||
} \
|
||||
h1 {\
|
||||
font-family : Arial;\
|
||||
}\
|
||||
\
|
||||
#etable td:nth-child(10),#etable th:nth-child(10) { border-right: 5px solid black; }\
|
||||
#etable td:nth-child(19),#etable th:nth-child(19) { border-right: 5px solid black; }\
|
||||
#etable td:nth-child(28),#etable th:nth-child(28) { border-right: 5px solid black; }\
|
||||
tr:nth-child(9) { border-bottom: 5px solid black; }\
|
||||
tr:nth-child(18) { border-bottom: 5px solid black; }\
|
||||
tr:nth-child(27) { border-bottom: 5px solid black; }\
|
||||
</style> \
|
||||
"
|
||||
sol += "<table id='etable' style='border:5px solid black'>\n"
|
||||
sol += "<thead>\n"
|
||||
sol += "<tr>"
|
||||
sol += "<th></th>"
|
||||
sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot A</th>"
|
||||
sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot B</th>"
|
||||
sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot C</th>"
|
||||
sol += "<th colspan=9>Pot D</th>"
|
||||
sol += "</tr>"
|
||||
sol += "<tr>\n"
|
||||
sol += f"<th></th>\n"
|
||||
for t in teams:
|
||||
sol += f"<th>{getTeamById[t['id']]}</th>\n"
|
||||
sol += "</tr>\n"
|
||||
sol += "</thead>\n"
|
||||
sol += "<tbody>\n"
|
||||
for t1 in teams:
|
||||
sol += "<tr>\n"
|
||||
sol += f"<td>{getTeamById[t1['id']]}</td>"
|
||||
for t2 in teams:
|
||||
if (t1['id'],t2['id']) in fixed_games:
|
||||
sol += f"<td>{t2['country']}</td>"
|
||||
elif (t2['id'],t1['id']) in fixed_games:
|
||||
sol += f"<td>@{t2['country']}</td>"
|
||||
else:
|
||||
sol += f"<td></td>"
|
||||
sol += "</tr>\n"
|
||||
sol += "</tbody>\n"
|
||||
sol += "</table>\n"
|
||||
|
||||
with open(f'debug.html', 'w') as f:
|
||||
f.write(sol)
|
||||
|
||||
|
||||
n = sys.maxsize
|
||||
|
||||
pool = Pool()
|
||||
result = {}
|
||||
answer = {}
|
||||
n_threads = cpu_count()
|
||||
# n_threads = 1
|
||||
|
||||
for cpu in range(n_threads):
|
||||
result[cpu] = pool.apply_async(simulate_draws, args=(f'thread_{cpu}_pot_by_pot', n,))
|
||||
|
||||
for cpu in range(n_threads):
|
||||
answer[cpu] = result[cpu].get()
|
||||
|
||||
|
||||
# %%
|
||||
# n = 2
|
||||
# simulate_draws('test', n)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
315
uefa/cycle24/simulations/double_draws/probabilities_october.py
Executable file
315
uefa/cycle24/simulations/double_draws/probabilities_october.py
Executable file
@ -0,0 +1,315 @@
|
||||
# %%
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
||||
scenario = Scenario.objects.get(id=34)
|
||||
|
||||
# %%
|
||||
|
||||
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
|
||||
}
|
||||
random_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_undirected = 0
|
||||
simulations_directed = 0
|
||||
maxVal = 1
|
||||
minVal = 99999999
|
||||
maxCVal = 1
|
||||
minCVal = 9999999
|
||||
maxRVal = 1
|
||||
minRVal = 9999999
|
||||
maxCRVal = 1
|
||||
minCRVal = 9999999
|
||||
|
||||
old_c = "START"
|
||||
for i in range(16):
|
||||
with open(f'thread_{i}_pot_by_pot.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_undirected +=1
|
||||
|
||||
team = getTeamByID[int(row[1])]
|
||||
Aopps = [getTeamByID[int(t)] for t in row[2].split(";")][:2]
|
||||
for o in Aopps:
|
||||
stats[team,o] += 1
|
||||
pots[team][getPotByID[o.id]] += 1
|
||||
played_countries[team,o.country] += 1
|
||||
Bopps = [getTeamByID[int(t)] for t in row[2].split(";")][2:4]
|
||||
for o in Bopps:
|
||||
stats[team,o] += 1
|
||||
pots[team][getPotByID[o.id]] += 1
|
||||
played_countries[team,o.country] += 1
|
||||
Copps = [getTeamByID[int(t)] for t in row[2].split(";")][4:6]
|
||||
for o in Copps:
|
||||
stats[team,o] += 1
|
||||
pots[team][getPotByID[o.id]] += 1
|
||||
played_countries[team,o.country] += 1
|
||||
Dopps = [getTeamByID[int(t)] for t in row[2].split(";")][6:]
|
||||
for o in Dopps:
|
||||
stats[team,o] += 1
|
||||
pots[team][getPotByID[o.id]] += 1
|
||||
played_countries[team,o.country] += 1
|
||||
|
||||
if stats[team,o] > maxVal:
|
||||
maxVal = stats[team,o]
|
||||
|
||||
if played_countries[team,o.country] > maxCVal:
|
||||
maxCVal = played_countries[team,o.country]
|
||||
|
||||
diff = {}
|
||||
mindval = 999999
|
||||
maxdval = 0
|
||||
# simulations_undirected = 1
|
||||
simulations_directed = 1
|
||||
|
||||
for key in random_stats.keys():
|
||||
diff[key] = stats[key]/simulations_undirected - 2*random_stats[key]/simulations_directed
|
||||
if diff[key] > maxdval:
|
||||
maxdval = diff[key]
|
||||
if diff[key] > 0 and diff[key] < mindval:
|
||||
mindval = diff[key]
|
||||
|
||||
|
||||
|
||||
for key, val in stats.items():
|
||||
if val > 0 and val < minVal:
|
||||
minVal = val
|
||||
|
||||
|
||||
for key, val in random_stats.items():
|
||||
if val > 0 and val < minRVal:
|
||||
minRVal = val
|
||||
|
||||
|
||||
for key, val in played_countries.items():
|
||||
if val > 0 and val < minCVal:
|
||||
minCVal = val
|
||||
|
||||
|
||||
for key, val in random_played_countries.items():
|
||||
if val > 0 and val < minCRVal:
|
||||
minCRVal = 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 = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
|
||||
sol += " \
|
||||
<style> \
|
||||
table, th, td { \
|
||||
border: 1px solid black; \
|
||||
border-collapse: collapse; \
|
||||
text-align: center; \
|
||||
min-width:40px; \
|
||||
padding:3px; \
|
||||
margin: 3px; \
|
||||
font-family : Arial;\
|
||||
} \
|
||||
h1 {\
|
||||
font-family : Arial;\
|
||||
}\
|
||||
\
|
||||
#etable td:nth-child(10),#etable th:nth-child(10) { border-right: 5px solid black; }\
|
||||
#etable td:nth-child(19),#etable th:nth-child(19) { border-right: 5px solid black; }\
|
||||
#etable td:nth-child(28),#etable th:nth-child(28) { border-right: 5px solid black; }\
|
||||
tr:nth-child(9) { border-bottom: 5px solid black; }\
|
||||
tr:nth-child(18) { border-bottom: 5px solid black; }\
|
||||
tr:nth-child(27) { border-bottom: 5px solid black; }\
|
||||
</style> \
|
||||
"
|
||||
sol += "</head><body>"
|
||||
sol += "<h2>Probabilities of games - drawn pot by pot</h2>"
|
||||
sol += "<table id='etable' style='border:5px solid black'>\n"
|
||||
sol += "<thead>\n"
|
||||
sol += "<tr>"
|
||||
sol += f"<th>{simulations_undirected}</th>"
|
||||
sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot A</th>"
|
||||
sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot B</th>"
|
||||
sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot C</th>"
|
||||
sol += "<th colspan=9>Pot D</th>"
|
||||
sol += "</tr>"
|
||||
sol += "<tr>\n"
|
||||
sol += f"<th></th>\n"
|
||||
# for o in order:
|
||||
for t in teams:
|
||||
# t = getTeamByName[o]
|
||||
sol += f"<th>({t.country}) {t.shortname}</th>\n"
|
||||
sol += "</tr>\n"
|
||||
sol += "</thead>\n"
|
||||
sol += "<tbody>\n"
|
||||
# for o1 in order:
|
||||
for t1 in teams:
|
||||
# t1 = getTeamByName[o1]
|
||||
sol += "<tr>\n"
|
||||
sol += f"<td>({t1.country}) {t1.shortname}</td>"
|
||||
# for o2 in order:
|
||||
for t2 in teams:
|
||||
# t2 = getTeamByName[o2]
|
||||
color = heatmap_color_for((stats[t1,t2]-minVal)/((maxVal-minVal) or 1))
|
||||
if stats[t1,t2] == 0:
|
||||
color = 'grey'
|
||||
val = f"{round((stats[t1,t2]/simulations_undirected)*100)}%"
|
||||
# val = stats[t1,t2]
|
||||
sol += f"<td style='background-color:{color}'>{val}</td>"
|
||||
sol += "</tr>\n"
|
||||
|
||||
sol += "</tbody>\n"
|
||||
sol += "</table>\n"
|
||||
|
||||
|
||||
with open(f'probabilities_pot_by_pot.html', 'w') as f:
|
||||
f.write(sol)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# %%
|
||||
497
uefa/cycle24/simulations/drawsimulation_october.py
Executable file
497
uefa/cycle24/simulations/drawsimulation_october.py
Executable file
@ -0,0 +1,497 @@
|
||||
# %%
|
||||
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"
|
||||
|
||||
from leagues import settings
|
||||
settings.DATABASES['default']['NAME'] = PROJECT_PATH+'/db.sqlite3'
|
||||
# settings.DATABASES['default']['ENGINE'] = 'django.db.backends.postgresql_psycopg2'
|
||||
# settings.DATABASES['default']['HOST'] = '0.0.0.0'
|
||||
# settings.DATABASES['default']['PORT'] = '5432'
|
||||
# settings.DATABASES['default']['USER'] = 'postgres'
|
||||
# settings.DATABASES['default']['PASSWORD'] = 'secret123'
|
||||
# settings.DATABASES['default']['NAME'] = 'mypgsqldb'
|
||||
# settings.DATABASES['default']['ATOMIC_REQUESTS'] = False
|
||||
# settings.DATABASES['default']['AUTOCOMMIT'] = True
|
||||
# settings.DATABASES['default']['CONN_MAX_AGE'] = 0
|
||||
# settings.DATABASES['default']['CONN_HEALTH_CHECKS'] = False
|
||||
# settings.DATABASES['default']['OPTIONS'] = {}
|
||||
|
||||
os.environ["XPRESSDIR"] = "/opt/xpressmp_9.0.2"
|
||||
os.environ["XPRESS"] = "/opt/xpressmp_9.0.2/bin"
|
||||
os.environ["LD_LIBRARY_PATH"] = os.environ["XPRESSDIR"] + "/lib"
|
||||
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["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprs.jar"
|
||||
os.environ["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprb.jar" + os.pathsep + os.environ["CLASSPATH"]
|
||||
os.environ["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprm.jar" + os.pathsep + os.environ["CLASSPATH"]
|
||||
os.environ["PATH"] = os.environ["XPRESSDIR"] + "/bin" + os.pathsep + os.environ["PATH"]
|
||||
|
||||
|
||||
import django
|
||||
django.setup()
|
||||
|
||||
from scheduler.models import *
|
||||
from draws.models import *
|
||||
import csv
|
||||
from multiprocessing import Pool, cpu_count
|
||||
import random
|
||||
import time
|
||||
import pulp
|
||||
from pulp import lpSum, value, XPRESS, GUROBI, PULP_CBC_CMD
|
||||
|
||||
import xpress as xp
|
||||
# xp.controls.outputlog = 0
|
||||
|
||||
|
||||
|
||||
scenario = Scenario.objects.get(id=4)
|
||||
|
||||
# %%
|
||||
|
||||
teamObjects = Team.objects.filter(season=scenario.season,active=True)
|
||||
teams = teamObjects.values('id','country','pot','name')
|
||||
|
||||
getTeamById = {}
|
||||
for t in teamObjects:
|
||||
getTeamById[t.id] = f"({t.pot}) {t.name}"
|
||||
|
||||
|
||||
countries = list(set(teamObjects.values_list('country', flat=True)))
|
||||
teams_from_country = {
|
||||
c:[t for t in teams if t['country']==c] for c in countries
|
||||
}
|
||||
|
||||
pot = {}
|
||||
for i in teamObjects.values_list('pot',flat=True).distinct():
|
||||
pot[i] = list(teams.filter(pot=i))
|
||||
|
||||
teams = list(teams)
|
||||
|
||||
clashes = Clash.objects.filter(draw__season=scenario.season)
|
||||
|
||||
|
||||
# fixed_games = [(3940, 3894), (3933, 3940), (3940, 3937), (3765, 3940), (3940, 3895), (3700, 3940), (3940, 3696), (3925, 3940), (3702, 3935), (3894, 3702), (3702, 3926), (3937, 3702), (3702, 3700), (3758, 3702), (3702, 3699), (3757, 3702), (3932, 3762), (3732, 3932), (3932, 3938), (3761, 3932), (3932, 3730), (3701, 3932), (3932, 3870), (3853, 3932), (3764, 3933), (3935, 3764), (3764, 3936), (3898, 3764), (3764, 3756), (3928, 3764), (3764, 3925), (3904, 3764), (3762, 3732), (3762, 3761), (3930, 3762), (3762, 3701), (3760, 3762), (3762, 3697), (3698, 3762), (3732, 3765), (3926, 3732), (3732, 3928), (3730, 3732), (3732, 3698), (3870, 3732), (3894, 3930), (3938, 3894), (3894, 3758)]
|
||||
|
||||
# %%
|
||||
|
||||
def check_feasible_pulp(fixed_games):
|
||||
|
||||
model = pulp.LpProblem(f"Draws", pulp.LpMinimize)
|
||||
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
x[t1['id'], t2['id']] = pulp.LpVariable('x_'+str(t1['id'])+'_'+str(t2['id']),lowBound=0, upBound=1, cat=pulp.LpInteger)
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
# model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
model += lpSum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1
|
||||
model += lpSum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1
|
||||
|
||||
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 3)
|
||||
model += lpSum(x[t['id'],t2['id']] for t2 in teams_from_country[c]) <= 2
|
||||
|
||||
# FIXATIONS
|
||||
for (t1,t2) in fixed_games:
|
||||
# print("FIXING",t1,t2)
|
||||
# model.addConstraint(x[t1,t2] == 1)
|
||||
model += x[t1,t2] == 1
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
model += x[t1,t2] + x[t2,t1] <= 1, f'directed_{t1}_{t2}'
|
||||
# model.addConstraint(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
model += lpSum(random.uniform(0,1)*x[key] for key in x.keys())
|
||||
tt =time.time()
|
||||
model.solve(XPRESS(msg=0,timeLimit=120,keepFiles=0))
|
||||
comp_time = time.time()-tt
|
||||
|
||||
if model.status in [-1,-2]:
|
||||
return False, comp_time
|
||||
else:
|
||||
return True, comp_time
|
||||
|
||||
|
||||
|
||||
def check_feasible(fixed_games):
|
||||
model = xp.problem(name='Draws', sense=xp.minimize)
|
||||
model.setControl ('outputlog', 1)
|
||||
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer)
|
||||
|
||||
model.addVariable(x)
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 3)
|
||||
|
||||
|
||||
for clash in clashes:
|
||||
for c1 in clash.countries.all():
|
||||
for c2 in clash.countries.all():
|
||||
if c1 != c2 and teams_from_country.get(c1.shortname) and teams_from_country.get(c2.shortname):
|
||||
model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t in teams_from_country[c1.shortname] for t2 in teams_from_country[c2.shortname]) <= 0)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# FIXATIONS
|
||||
for (t1,t2) in fixed_games:
|
||||
# print("FIXING",t1,t2)
|
||||
model.addConstraint(x[t1,t2] == 1)
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
model.addConstraint(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
|
||||
tt =time.time()
|
||||
model.solve()
|
||||
comp_time = time.time()-tt
|
||||
|
||||
|
||||
if model.getProbStatus() != 6:
|
||||
# print("INFEASIBLE FOUND")
|
||||
return False, comp_time
|
||||
else:
|
||||
return True, comp_time
|
||||
|
||||
|
||||
|
||||
|
||||
model = xp.problem(name='Draws', sense=xp.minimize)
|
||||
model.setControl ('outputlog', 0)
|
||||
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer)
|
||||
|
||||
model.addVariable(x)
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2)
|
||||
|
||||
|
||||
for clash in clashes:
|
||||
for c1 in clash.countries.all():
|
||||
for c2 in clash.countries.all():
|
||||
if c1 != c2 and teams_from_country.get(c1.shortname) and teams_from_country.get(c2.shortname):
|
||||
model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t in teams_from_country[c1.shortname] for t2 in teams_from_country[c2.shortname]) <= 0)
|
||||
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
model.addConstraint(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
def check_feasible_fix(fixed_games):
|
||||
# FIXATIONS
|
||||
# for key in x.keys():
|
||||
# if key in fixed_games:
|
||||
# # x[key].lb = 1
|
||||
# model.chgbounds([x[key]],['L'],[1])
|
||||
# else:
|
||||
# # x[key].lb = 0
|
||||
# model.chgbounds([x[key]],['L'],[0])
|
||||
|
||||
reset_bounds = [key for key in x.keys() if key not in fixed_games]
|
||||
|
||||
model.chgbounds([x[key] for key in fixed_games],['L' for _ in range(len(fixed_games))],[1 for _ in range(len(fixed_games))])
|
||||
model.chgbounds([x[key] for key in reset_bounds],['L' for _ in range(len(reset_bounds))],[0 for _ in range(len(reset_bounds))])
|
||||
|
||||
tt =time.time()
|
||||
model.solve()
|
||||
comp_time = time.time()-tt
|
||||
|
||||
if model.getProbStatus() != 6:
|
||||
# print("INFEASIBLE FOUND")
|
||||
return False, comp_time
|
||||
return False
|
||||
else:
|
||||
return True, comp_time
|
||||
return True
|
||||
|
||||
|
||||
# def ucl24_random_games(team_to_check, pots_to_check, oldgames):
|
||||
# teamObjects = Team.objects.filter(season=scenario.season,active=True)
|
||||
# teams = [t.id for t in teamObjects]
|
||||
# t_country = {t.id : t.country for t in teamObjects}
|
||||
# t_name = {t.id : t.name for t in teamObjects}
|
||||
# t_pot = {t.id : t.pot for t in teamObjects}
|
||||
# countries = sorted(list(set(t_country.values())))
|
||||
# pots = sorted(list(set(t_pot.values())))
|
||||
|
||||
# max_opponents_from_same_country=2
|
||||
|
||||
# givenHome = { (t,p) : False for t in teams for p in pots }
|
||||
# givenAway = { (t,p) : False for t in teams for p in pots }
|
||||
# gamesAgainstCountry = { (t,c) : 0 for t in teams for c in countries }
|
||||
|
||||
# for (t1,t2) in oldgames:
|
||||
# givenHome[t1,t_pot[t2]]=t2
|
||||
# givenAway[t2,t_pot[t1]]=t1
|
||||
# gamesAgainstCountry[(t1,t_country[t2])]+=1
|
||||
# gamesAgainstCountry[(t2,t_country[t1])]+=1
|
||||
|
||||
# no_solution_found = True
|
||||
|
||||
# possHomeOpponents={}
|
||||
# possAwayOpponents={}
|
||||
# for p in pots_to_check:
|
||||
# print( "POT " , p)
|
||||
# possOpponents1 = [ t for t in teams if t_country[t]!=t_country[team_to_check] and t_pot[t]==p and t!=givenAway[team_to_check,p] ]
|
||||
# possOpponents = [ t for t in possOpponents1 if gamesAgainstCountry[(team_to_check,t_country[t])]<2 and gamesAgainstCountry[(t,t_country[team_to_check])]<2]
|
||||
# if givenHome[team_to_check,p]:
|
||||
# possHomeOpponents[p]= [givenHome[team_to_check,p]]
|
||||
# else:
|
||||
# possHomeOpponents[p] = [ t for t in possOpponents if not givenAway[t,t_pot[team_to_check]] ]
|
||||
# if givenAway[team_to_check,p]:
|
||||
# possAwayOpponents[p]= [givenAway[team_to_check,p]]
|
||||
# else:
|
||||
# possAwayOpponents[p] = [ t for t in possOpponents if not givenHome[t,t_pot[team_to_check]]]
|
||||
|
||||
# while no_solution_found:
|
||||
# newgames = []
|
||||
# for p in pots_to_check:
|
||||
# random_home= random.choice(possHomeOpponents[p])
|
||||
# random_away= random.choice(possAwayOpponents[p])
|
||||
# print (p,"-> " , random_home==random_away, t_name[random_home], "\t ", t_name[random_away] )
|
||||
# newgames+=[(team_to_check,random_home), (random_away,team_to_check) ]
|
||||
# if random_home!=random_away and check_feasible(oldgames+newgames):
|
||||
# no_solution_found = False
|
||||
|
||||
# newgames = [gm for gm in newgames if gm not in oldgames]
|
||||
# return newgames
|
||||
|
||||
|
||||
# %%
|
||||
|
||||
|
||||
|
||||
def simulate_draws(filename,n):
|
||||
|
||||
print("RUNNING ASYNC",filename)
|
||||
|
||||
for i in range(1, n):
|
||||
if i % 100 == 0:
|
||||
print("RUNNING ASYNC",filename,i)
|
||||
start_time = time.time()
|
||||
n_computations = 0
|
||||
check_time = 0
|
||||
total_comp_time = 0
|
||||
|
||||
|
||||
possible_opps = {}
|
||||
for pos in range(8):
|
||||
p = pos//2+1
|
||||
teams_from_pot = list(teamObjects.filter(pot=p).values('id','country'))
|
||||
possible_opps[pos] = {
|
||||
t['id']: [t2['id'] for t2 in teams_from_pot if t2['country'] != t['country']] for t in teams
|
||||
}
|
||||
|
||||
sol_opps = {
|
||||
(t['id'],p):None
|
||||
for t in teams for p in range(8)
|
||||
}
|
||||
fixed_games = []
|
||||
feasible = True
|
||||
|
||||
for p in range(1,5):
|
||||
currentPot = list(teamObjects.filter(pot=p).values_list('id', flat=True))
|
||||
|
||||
while(feasible and currentPot):
|
||||
new_team = currentPot.pop(random.randint(0,len(currentPot)-1))
|
||||
for current_pos in range(8):
|
||||
while (feasible and sol_opps[new_team,current_pos] == None):
|
||||
try:
|
||||
new_opponent = random.choice(possible_opps[current_pos][new_team])
|
||||
except:
|
||||
feasible = False
|
||||
print("INFEASIBLE")
|
||||
# print(sol_opps)
|
||||
# print(fixed_games)
|
||||
# print(possible_opps)
|
||||
# print(new_team,current_pos)
|
||||
# print(possible_opps[current_pos][new_team])
|
||||
exit()
|
||||
|
||||
if sol_opps[new_opponent,(2*p-1)-(current_pos % 2)] == None:
|
||||
new_game = (new_team,new_opponent) if current_pos % 2 == 0 else (new_opponent,new_team)
|
||||
n_computations += 1
|
||||
tt = time.time()
|
||||
# check, comp_time = check_feasible_pulp(fixed_games+[new_game])
|
||||
# check, comp_time = check_feasible_fix(fixed_games+[new_game])
|
||||
check, comp_time = check_feasible(fixed_games+[new_game])
|
||||
check_time += time.time()-tt
|
||||
total_comp_time += comp_time
|
||||
if check:
|
||||
# if check_feasible_fix(fixed_games+[new_game]):
|
||||
sol_opps[new_team,current_pos] = new_opponent
|
||||
sol_opps[new_opponent,(2*p-1)-(current_pos % 2)] = new_team
|
||||
fixed_games.append(new_game)
|
||||
if new_opponent in possible_opps[(2*p-1)-(current_pos % 2)][new_team]:
|
||||
possible_opps[(2*p-1)-(current_pos % 2)][new_team].remove(new_opponent)
|
||||
possible_opps[current_pos][new_team].remove(new_opponent)
|
||||
else:
|
||||
possible_opps[current_pos][new_team].remove(new_opponent)
|
||||
|
||||
|
||||
# for p in [1,2,3,4]:
|
||||
# # for p in [4,3,2,1]:
|
||||
# currentPot = list(teamObjects.filter(pot=p).values_list('id', flat=True))
|
||||
|
||||
# while(feasible and currentPot):
|
||||
# # Draw Team
|
||||
# new_team = currentPot.pop(random.randint(0,len(currentPot)-1))
|
||||
# draw_index_dict[new_team] = draw_index
|
||||
# draw_index += 1
|
||||
|
||||
# # print("New team",new_team,getTeamById[new_team])
|
||||
# for pos in range(8):
|
||||
# # Skip if already drawn
|
||||
# if sol_opps[new_team,pos]:
|
||||
# continue
|
||||
# # Update possible opponents
|
||||
# opponent_pool = []
|
||||
# for new_opponent in possible_opps[pos][new_team]:
|
||||
# if sol_opps[new_opponent,(2*p-1)-(pos % 2)] != None:
|
||||
# continue
|
||||
# # print(f"---> ALREADY DRAWN {pos}: {getTeamById[new_opponent]}")
|
||||
# else:
|
||||
# new_game = (new_team,new_opponent) if pos % 2 == 0 else (new_opponent,new_team)
|
||||
# n_computations += 1
|
||||
# tt = time.time()
|
||||
# feasible = check_feasible(fixed_games+[new_game])
|
||||
# comp_time += time.time()-tt
|
||||
# if feasible:
|
||||
# opponent_pool.append(new_opponent)
|
||||
# else:
|
||||
# # print(f"---> CANNOT DRAW {pos}: {[getTeamById[ttt] for ttt in new_game]}")
|
||||
# num_combinatorial_clashes[new_team,pos] += 1
|
||||
# num_possible_opps[new_team,pos] = len(opponent_pool)
|
||||
# # Draw random opponent
|
||||
# new_opponent = random.choice(opponent_pool)
|
||||
# new_game = (new_team,new_opponent) if pos % 2 == 0 else (new_opponent,new_team)
|
||||
# # if not check_feasible(fixed_games+[new_game]):
|
||||
# # print("INFEASIBLE")
|
||||
# # print("POSSOPS AFTER",[getTeamById[tt] for tt in possible_opps[pos][new_team]])
|
||||
# # print(f"{p} - {pos} - {getTeamById[sol_opps[new_opponent,(2*p-1)-(pos % 2)]]}")
|
||||
# # feasible = False
|
||||
# # break
|
||||
|
||||
# sol_opps[new_team,pos] = new_opponent
|
||||
# sol_opps[new_opponent,(2*p-1)-(pos % 2)] = new_team
|
||||
# if pos % 2 == 0:
|
||||
# possible_opps[pos+1][new_team].remove(new_opponent)
|
||||
# fixed_games.append(new_game)
|
||||
|
||||
|
||||
print("COMPUTATIONS",n_computations)
|
||||
print("TIME\t",time.time()-start_time)
|
||||
print("CHECK\t",check_time)
|
||||
print("COMP\t",total_comp_time)
|
||||
with open(filename+'.csv', "a") as f:
|
||||
for t in teams:
|
||||
f.write(f"{i},{t['id']},{';'.join([str(sol_opps[t['id'],p]) for p in range(8)])}\n")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# for game in fixed_games:
|
||||
# if game[0] == new_team or game[1] == new_team:
|
||||
# print("\t"," vs ".join([getTeamById[tt] for tt in game]))
|
||||
# print(f"--- > {draw_index_dict[new_team]}")
|
||||
# for pos in range(8):
|
||||
# print(f"--- > {pos} - {num_possible_opps[new_team,pos]}")
|
||||
|
||||
# iterate over h/a-encounters
|
||||
# for current_pos in range(8):
|
||||
# while (sol_opps[new_team,current_pos] == None):
|
||||
# # print(possible_opps[current_pos][new_team])
|
||||
# # draw opponent
|
||||
# new_opponent = random.choice(possible_opps[current_pos][new_team])
|
||||
# print("\tNEW OPP",new_opponent,getTeamById[new_opponent])
|
||||
# new_game = (new_team,new_opponent) if current_pos % 2 == 0 else (new_opponent,new_team)
|
||||
# if check_feasible(fixed_games+[new_game]):
|
||||
# # print("FEASIBLE",new_game,[getTeamById[tt] for tt in new_game])
|
||||
# sol_opps[new_team,current_pos] = new_opponent
|
||||
# sol_opps[new_opponent,(2*p-1)-(current_pos % 2)] = new_team
|
||||
# fixed_games.append(new_game)
|
||||
# possible_opps[current_pos][new_team].remove(new_opponent)
|
||||
# else:
|
||||
# possible_opps[current_pos][new_team].remove(new_opponent)
|
||||
# %%
|
||||
|
||||
|
||||
# # SOLUTION
|
||||
# for g in fixed_games:
|
||||
# print(getTeamById[g[0]],getTeamById[g[1]])
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# n = sys.maxsize
|
||||
|
||||
# pool = Pool()
|
||||
# result = {}
|
||||
# answer = {}
|
||||
# n_threads = cpu_count()
|
||||
# # n_threads = 1
|
||||
|
||||
# for cpu in range(n_threads):
|
||||
# result[cpu] = pool.apply_async(simulate_draws, args=(f'thread_{cpu}_pot_by_pot', n,))
|
||||
|
||||
# for cpu in range(n_threads):
|
||||
# answer[cpu] = result[cpu].get()
|
||||
|
||||
|
||||
# %%
|
||||
# n = sys.maxsize
|
||||
n = 2
|
||||
simulate_draws('test', n)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# %%
|
||||
|
||||
|
||||
477
uefa/cycle24/simulations/drawsimulation_october_gurobi.py
Executable file
477
uefa/cycle24/simulations/drawsimulation_october_gurobi.py
Executable file
@ -0,0 +1,477 @@
|
||||
# %%
|
||||
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"
|
||||
|
||||
from leagues import settings
|
||||
settings.DATABASES['default']['NAME'] = PROJECT_PATH+'/db.sqlite3'
|
||||
# settings.DATABASES['default']['ENGINE'] = 'django.db.backends.postgresql_psycopg2'
|
||||
# settings.DATABASES['default']['HOST'] = '0.0.0.0'
|
||||
# settings.DATABASES['default']['PORT'] = '5432'
|
||||
# settings.DATABASES['default']['USER'] = 'postgres'
|
||||
# settings.DATABASES['default']['PASSWORD'] = 'secret123'
|
||||
# settings.DATABASES['default']['NAME'] = 'mypgsqldb'
|
||||
# settings.DATABASES['default']['ATOMIC_REQUESTS'] = False
|
||||
# settings.DATABASES['default']['AUTOCOMMIT'] = True
|
||||
# settings.DATABASES['default']['CONN_MAX_AGE'] = 0
|
||||
# settings.DATABASES['default']['CONN_HEALTH_CHECKS'] = False
|
||||
# settings.DATABASES['default']['OPTIONS'] = {}
|
||||
|
||||
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["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["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprs.jar"
|
||||
os.environ["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprb.jar" + os.pathsep + os.environ["CLASSPATH"]
|
||||
os.environ["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprm.jar" + os.pathsep + os.environ["CLASSPATH"]
|
||||
os.environ["PATH"] = os.environ["XPRESSDIR"] + "/bin" + os.pathsep + os.environ["PATH"]
|
||||
|
||||
|
||||
import django
|
||||
django.setup()
|
||||
|
||||
from scheduler.models import *
|
||||
import csv
|
||||
from multiprocessing import Pool, cpu_count
|
||||
import random
|
||||
import time
|
||||
import pulp
|
||||
from pulp import lpSum, value, XPRESS, GUROBI, PULP_CBC_CMD
|
||||
import gurobipy as gp
|
||||
from gurobipy import GRB
|
||||
import xpress as xp
|
||||
# xp.controls.outputlog = 0
|
||||
|
||||
|
||||
|
||||
scenario = Scenario.objects.get(id=34)
|
||||
|
||||
# %%
|
||||
|
||||
teamObjects = Team.objects.filter(season=scenario.season,active=True)
|
||||
teams = teamObjects.values('id','country','pot','name')
|
||||
|
||||
getTeamById = {}
|
||||
for t in teamObjects:
|
||||
getTeamById[t.id] = f"({t.pot}) {t.name}"
|
||||
|
||||
|
||||
countries = list(set(teamObjects.values_list('country', flat=True)))
|
||||
teams_from_country = {
|
||||
c:[t for t in teams if t['country']==c] for c in countries
|
||||
}
|
||||
|
||||
pot = {}
|
||||
for i in teamObjects.values_list('pot',flat=True).distinct():
|
||||
pot[i] = list(teams.filter(pot=i))
|
||||
|
||||
teams = list(teams)
|
||||
|
||||
|
||||
|
||||
|
||||
# fixed_games = [(3940, 3894), (3933, 3940), (3940, 3937), (3765, 3940), (3940, 3895), (3700, 3940), (3940, 3696), (3925, 3940), (3702, 3935), (3894, 3702), (3702, 3926), (3937, 3702), (3702, 3700), (3758, 3702), (3702, 3699), (3757, 3702), (3932, 3762), (3732, 3932), (3932, 3938), (3761, 3932), (3932, 3730), (3701, 3932), (3932, 3870), (3853, 3932), (3764, 3933), (3935, 3764), (3764, 3936), (3898, 3764), (3764, 3756), (3928, 3764), (3764, 3925), (3904, 3764), (3762, 3732), (3762, 3761), (3930, 3762), (3762, 3701), (3760, 3762), (3762, 3697), (3698, 3762), (3732, 3765), (3926, 3732), (3732, 3928), (3730, 3732), (3732, 3698), (3870, 3732), (3894, 3930), (3938, 3894), (3894, 3758)]
|
||||
|
||||
|
||||
|
||||
def check_feasible_pulp(fixed_games):
|
||||
|
||||
model = pulp.LpProblem(f"Draws", pulp.LpMinimize)
|
||||
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
x[t1['id'], t2['id']] = pulp.LpVariable('x_'+str(t1['id'])+'_'+str(t2['id']),lowBound=0, upBound=1, cat=pulp.LpInteger)
|
||||
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
# model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
model += lpSum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1
|
||||
model += lpSum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1
|
||||
|
||||
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 3)
|
||||
model += lpSum(x[t['id'],t2['id']] for t2 in teams_from_country[c]) <= 2
|
||||
|
||||
# FIXATIONS
|
||||
for (t1,t2) in fixed_games:
|
||||
# print("FIXING",t1,t2)
|
||||
# model.addConstraint(x[t1,t2] == 1)
|
||||
model += x[t1,t2] == 1
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
model += x[t1,t2] + x[t2,t1] <= 1, f'directed_{t1}_{t2}'
|
||||
# model.addConstraint(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
model += lpSum(random.uniform(0,1)*x[key] for key in x.keys())
|
||||
tt =time.time()
|
||||
model.solve(XPRESS(msg=0,timeLimit=120,keepFiles=0))
|
||||
comp_time = time.time()-tt
|
||||
|
||||
if model.status in [-1,-2]:
|
||||
return False, comp_time
|
||||
else:
|
||||
return True, comp_time
|
||||
|
||||
|
||||
|
||||
|
||||
model = gp.Model('Draws')
|
||||
model.Params.OutputFlag = 0
|
||||
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
# x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer)
|
||||
x[t1['id'], t2['id']] = model.addVar(vtype=GRB.BINARY)
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
model.addConstr(gp.quicksum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
model.addConstr(gp.quicksum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
model.addConstr(gp.quicksum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2)
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
# model.addConstraint(x[t1,t2] + x[t2,t1] <= 1)
|
||||
model.addConstr(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
|
||||
|
||||
|
||||
def check_feasible_gurobi(fixed_games):
|
||||
|
||||
# FIXATIONS
|
||||
for key in x.keys():
|
||||
if key in fixed_games:
|
||||
x[key].lb = 1
|
||||
else:
|
||||
x[key].lb = 0
|
||||
|
||||
model.update()
|
||||
|
||||
tt =time.time()
|
||||
# model.solve()
|
||||
model.optimize()
|
||||
comp_time = time.time()-tt
|
||||
|
||||
|
||||
if model.Status == GRB.OPTIMAL:
|
||||
return True, comp_time
|
||||
else:
|
||||
# print("INFEASIBLE FOUND")
|
||||
return False, comp_time
|
||||
|
||||
|
||||
def check_feasible(fixed_games):
|
||||
model = xp.problem(name='Draws', sense=xp.minimize)
|
||||
model.setControl ('outputlog', 0)
|
||||
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer)
|
||||
|
||||
model.addVariable(x)
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2)
|
||||
|
||||
# FIXATIONS
|
||||
for (t1,t2) in fixed_games:
|
||||
# print("FIXING",t1,t2)
|
||||
model.addConstraint(x[t1,t2] == 1)
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
model.addConstraint(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
|
||||
tt =time.time()
|
||||
model.solve()
|
||||
comp_time = time.time()-tt
|
||||
|
||||
|
||||
if model.getProbStatus() != 6:
|
||||
# print("INFEASIBLE FOUND")
|
||||
return False, comp_time
|
||||
else:
|
||||
return True, comp_time
|
||||
|
||||
|
||||
|
||||
|
||||
# model = xp.problem(name='Draws', sense=xp.minimize)
|
||||
# model.setControl ('outputlog', 0)
|
||||
|
||||
# x = {}
|
||||
# for t1 in teams:
|
||||
# for t2 in teams:
|
||||
# if t1['country'] != t2['country']:
|
||||
# x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer)
|
||||
|
||||
# model.addVariable(x)
|
||||
|
||||
# # REQUIREMENTS
|
||||
# for t in teams:
|
||||
# for r in range(1,5):
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
# model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
# for c in countries:
|
||||
# if c != t['country']:
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2)
|
||||
|
||||
# for (t1,t2) in x.keys():
|
||||
# model.addConstraint(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
def check_feasible_fix(fixed_games):
|
||||
# FIXATIONS
|
||||
# for key in x.keys():
|
||||
# if key in fixed_games:
|
||||
# # x[key].lb = 1
|
||||
# model.chgbounds([x[key]],['L'],[1])
|
||||
# else:
|
||||
# # x[key].lb = 0
|
||||
# model.chgbounds([x[key]],['L'],[0])
|
||||
|
||||
reset_bounds = [key for key in x.keys() if key not in fixed_games]
|
||||
|
||||
model.chgbounds([x[key] for key in fixed_games],['L' for _ in range(len(fixed_games))],[1 for _ in range(len(fixed_games))])
|
||||
model.chgbounds([x[key] for key in reset_bounds],['L' for _ in range(len(reset_bounds))],[0 for _ in range(len(reset_bounds))])
|
||||
|
||||
tt =time.time()
|
||||
model.solve()
|
||||
comp_time = time.time()-tt
|
||||
|
||||
if model.getProbStatus() != 6:
|
||||
# print("INFEASIBLE FOUND")
|
||||
return False, comp_time
|
||||
return False
|
||||
else:
|
||||
return True, comp_time
|
||||
return True
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def simulate_draws(filename,n):
|
||||
|
||||
print("RUNNING ASYNC",filename)
|
||||
|
||||
for i in range(1, n):
|
||||
if i % 100 == 0:
|
||||
print("RUNNING ASYNC",filename,i)
|
||||
# start_time = time.time()
|
||||
# n_computations = 0
|
||||
# check_time = 0
|
||||
# total_comp_time = 0
|
||||
|
||||
|
||||
possible_opps = {}
|
||||
for pos in range(8):
|
||||
p = pos//2+1
|
||||
teams_from_pot = list(teamObjects.filter(pot=p).values('id','country'))
|
||||
possible_opps[pos] = {
|
||||
t['id']: [t2['id'] for t2 in teams_from_pot if t2['country'] != t['country']] for t in teams
|
||||
}
|
||||
|
||||
sol_opps = {
|
||||
(t['id'],p):None
|
||||
for t in teams for p in range(8)
|
||||
}
|
||||
fixed_games = []
|
||||
feasible = True
|
||||
|
||||
for p in range(1,5):
|
||||
currentPot = list(teamObjects.filter(pot=p).values_list('id', flat=True))
|
||||
|
||||
while(feasible and currentPot):
|
||||
new_team = currentPot.pop(random.randint(0,len(currentPot)-1))
|
||||
for current_pos in range(8):
|
||||
while (feasible and sol_opps[new_team,current_pos] == None):
|
||||
try:
|
||||
new_opponent = random.choice(possible_opps[current_pos][new_team])
|
||||
except:
|
||||
feasible = False
|
||||
print("INFEASIBLE")
|
||||
# print(sol_opps)
|
||||
# print(fixed_games)
|
||||
# print(possible_opps)
|
||||
# print(new_team,current_pos)
|
||||
# print(possible_opps[current_pos][new_team])
|
||||
exit()
|
||||
|
||||
if sol_opps[new_opponent,(2*p-1)-(current_pos % 2)] == None:
|
||||
new_game = (new_team,new_opponent) if current_pos % 2 == 0 else (new_opponent,new_team)
|
||||
# n_computations += 1
|
||||
# tt = time.time()
|
||||
# check, comp_time = check_feasible_pulp(fixed_games+[new_game])
|
||||
check, comp_time = check_feasible_gurobi(fixed_games+[new_game])
|
||||
# check_time += time.time()-tt
|
||||
# total_comp_time += comp_time
|
||||
if check:
|
||||
# if check_feasible_fix(fixed_games+[new_game]):
|
||||
sol_opps[new_team,current_pos] = new_opponent
|
||||
sol_opps[new_opponent,(2*p-1)-(current_pos % 2)] = new_team
|
||||
fixed_games.append(new_game)
|
||||
if new_opponent in possible_opps[(2*p-1)-(current_pos % 2)][new_team]:
|
||||
possible_opps[(2*p-1)-(current_pos % 2)][new_team].remove(new_opponent)
|
||||
possible_opps[current_pos][new_team].remove(new_opponent)
|
||||
else:
|
||||
possible_opps[current_pos][new_team].remove(new_opponent)
|
||||
|
||||
|
||||
# for p in [1,2,3,4]:
|
||||
# # for p in [4,3,2,1]:
|
||||
# currentPot = list(teamObjects.filter(pot=p).values_list('id', flat=True))
|
||||
|
||||
# while(feasible and currentPot):
|
||||
# # Draw Team
|
||||
# new_team = currentPot.pop(random.randint(0,len(currentPot)-1))
|
||||
# draw_index_dict[new_team] = draw_index
|
||||
# draw_index += 1
|
||||
|
||||
# # print("New team",new_team,getTeamById[new_team])
|
||||
# for pos in range(8):
|
||||
# # Skip if already drawn
|
||||
# if sol_opps[new_team,pos]:
|
||||
# continue
|
||||
# # Update possible opponents
|
||||
# opponent_pool = []
|
||||
# for new_opponent in possible_opps[pos][new_team]:
|
||||
# if sol_opps[new_opponent,(2*p-1)-(pos % 2)] != None:
|
||||
# continue
|
||||
# # print(f"---> ALREADY DRAWN {pos}: {getTeamById[new_opponent]}")
|
||||
# else:
|
||||
# new_game = (new_team,new_opponent) if pos % 2 == 0 else (new_opponent,new_team)
|
||||
# n_computations += 1
|
||||
# tt = time.time()
|
||||
# feasible = check_feasible(fixed_games+[new_game])
|
||||
# comp_time += time.time()-tt
|
||||
# if feasible:
|
||||
# opponent_pool.append(new_opponent)
|
||||
# else:
|
||||
# # print(f"---> CANNOT DRAW {pos}: {[getTeamById[ttt] for ttt in new_game]}")
|
||||
# num_combinatorial_clashes[new_team,pos] += 1
|
||||
# num_possible_opps[new_team,pos] = len(opponent_pool)
|
||||
# # Draw random opponent
|
||||
# new_opponent = random.choice(opponent_pool)
|
||||
# new_game = (new_team,new_opponent) if pos % 2 == 0 else (new_opponent,new_team)
|
||||
# # if not check_feasible(fixed_games+[new_game]):
|
||||
# # print("INFEASIBLE")
|
||||
# # print("POSSOPS AFTER",[getTeamById[tt] for tt in possible_opps[pos][new_team]])
|
||||
# # print(f"{p} - {pos} - {getTeamById[sol_opps[new_opponent,(2*p-1)-(pos % 2)]]}")
|
||||
# # feasible = False
|
||||
# # break
|
||||
|
||||
# sol_opps[new_team,pos] = new_opponent
|
||||
# sol_opps[new_opponent,(2*p-1)-(pos % 2)] = new_team
|
||||
# if pos % 2 == 0:
|
||||
# possible_opps[pos+1][new_team].remove(new_opponent)
|
||||
# fixed_games.append(new_game)
|
||||
|
||||
|
||||
# print("COMPUTATIONS",n_computations)
|
||||
# print("TIME\t",time.time()-start_time)
|
||||
# print("CHECK\t",check_time)
|
||||
# print("COMP\t",total_comp_time)
|
||||
with open(filename+'.csv', "a") as f:
|
||||
for t in teams:
|
||||
f.write(f"{i},{t['id']},{';'.join([str(sol_opps[t['id'],p]) for p in range(8)])}\n")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# for game in fixed_games:
|
||||
# if game[0] == new_team or game[1] == new_team:
|
||||
# print("\t"," vs ".join([getTeamById[tt] for tt in game]))
|
||||
# print(f"--- > {draw_index_dict[new_team]}")
|
||||
# for pos in range(8):
|
||||
# print(f"--- > {pos} - {num_possible_opps[new_team,pos]}")
|
||||
|
||||
# iterate over h/a-encounters
|
||||
# for current_pos in range(8):
|
||||
# while (sol_opps[new_team,current_pos] == None):
|
||||
# # print(possible_opps[current_pos][new_team])
|
||||
# # draw opponent
|
||||
# new_opponent = random.choice(possible_opps[current_pos][new_team])
|
||||
# print("\tNEW OPP",new_opponent,getTeamById[new_opponent])
|
||||
# new_game = (new_team,new_opponent) if current_pos % 2 == 0 else (new_opponent,new_team)
|
||||
# if check_feasible(fixed_games+[new_game]):
|
||||
# # print("FEASIBLE",new_game,[getTeamById[tt] for tt in new_game])
|
||||
# sol_opps[new_team,current_pos] = new_opponent
|
||||
# sol_opps[new_opponent,(2*p-1)-(current_pos % 2)] = new_team
|
||||
# fixed_games.append(new_game)
|
||||
# possible_opps[current_pos][new_team].remove(new_opponent)
|
||||
# else:
|
||||
# possible_opps[current_pos][new_team].remove(new_opponent)
|
||||
# %%
|
||||
|
||||
|
||||
# # SOLUTION
|
||||
# for g in fixed_games:
|
||||
# print(getTeamById[g[0]],getTeamById[g[1]])
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
n = sys.maxsize
|
||||
|
||||
pool = Pool()
|
||||
result = {}
|
||||
answer = {}
|
||||
n_threads = cpu_count()
|
||||
# n_threads = 1
|
||||
|
||||
for cpu in range(n_threads):
|
||||
result[cpu] = pool.apply_async(simulate_draws, args=(f'thread_{cpu}_pot_by_pot', n,))
|
||||
|
||||
for cpu in range(n_threads):
|
||||
answer[cpu] = result[cpu].get()
|
||||
|
||||
|
||||
# %%
|
||||
# n = 2
|
||||
# simulate_draws('test', n)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# %%
|
||||
|
||||
|
||||
596
uefa/cycle24/simulations/drawsimulation_october_gurobi_all.py
Executable file
596
uefa/cycle24/simulations/drawsimulation_october_gurobi_all.py
Executable file
@ -0,0 +1,596 @@
|
||||
# %%
|
||||
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"
|
||||
|
||||
from leagues import settings
|
||||
settings.DATABASES['default']['NAME'] = PROJECT_PATH+'/db.sqlite3'
|
||||
# settings.DATABASES['default']['ENGINE'] = 'django.db.backends.postgresql_psycopg2'
|
||||
# settings.DATABASES['default']['HOST'] = '0.0.0.0'
|
||||
# settings.DATABASES['default']['PORT'] = '5432'
|
||||
# settings.DATABASES['default']['USER'] = 'postgres'
|
||||
# settings.DATABASES['default']['PASSWORD'] = 'secret123'
|
||||
# settings.DATABASES['default']['NAME'] = 'mypgsqldb'
|
||||
# settings.DATABASES['default']['ATOMIC_REQUESTS'] = False
|
||||
# settings.DATABASES['default']['AUTOCOMMIT'] = True
|
||||
# settings.DATABASES['default']['CONN_MAX_AGE'] = 0
|
||||
# settings.DATABASES['default']['CONN_HEALTH_CHECKS'] = False
|
||||
# settings.DATABASES['default']['OPTIONS'] = {}
|
||||
|
||||
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["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["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprs.jar"
|
||||
os.environ["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprb.jar" + os.pathsep + os.environ["CLASSPATH"]
|
||||
os.environ["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprm.jar" + os.pathsep + os.environ["CLASSPATH"]
|
||||
os.environ["PATH"] = os.environ["XPRESSDIR"] + "/bin" + os.pathsep + os.environ["PATH"]
|
||||
|
||||
|
||||
import django
|
||||
django.setup()
|
||||
|
||||
from scheduler.models import *
|
||||
from draws.models import *
|
||||
import csv
|
||||
from multiprocessing import Pool, cpu_count
|
||||
import random
|
||||
import time
|
||||
import pulp
|
||||
from pulp import lpSum, value, XPRESS, GUROBI, PULP_CBC_CMD
|
||||
import gurobipy as gp
|
||||
from gurobipy import GRB
|
||||
import xpress as xp
|
||||
# xp.controls.outputlog = 0
|
||||
|
||||
|
||||
|
||||
scenario = Scenario.objects.get(id=4)
|
||||
|
||||
# %%
|
||||
|
||||
teamObjects = Team.objects.filter(season=scenario.season,active=True).order_by('pot')
|
||||
teams = teamObjects.values('id','country','pot','name')
|
||||
|
||||
getTeamById = {}
|
||||
for t in teamObjects:
|
||||
getTeamById[t.id] = f"({t.pot}) {t.name}"
|
||||
|
||||
getCountryById = {}
|
||||
for t in teamObjects:
|
||||
getCountryById[t.id] = t.country
|
||||
|
||||
countries = list(set(teamObjects.values_list('country', flat=True)))
|
||||
teams_from_country = {
|
||||
c:[t for t in teams if t['country']==c] for c in countries
|
||||
}
|
||||
|
||||
pot = {}
|
||||
for i in teamObjects.values_list('pot',flat=True).distinct():
|
||||
pot[i] = list(teams.filter(pot=i))
|
||||
|
||||
teams = list(teams)
|
||||
|
||||
|
||||
|
||||
|
||||
# fixed_games = [(3940, 3894), (3933, 3940), (3940, 3937), (3765, 3940), (3940, 3895), (3700, 3940), (3940, 3696), (3925, 3940), (3702, 3935), (3894, 3702), (3702, 3926), (3937, 3702), (3702, 3700), (3758, 3702), (3702, 3699), (3757, 3702), (3932, 3762), (3732, 3932), (3932, 3938), (3761, 3932), (3932, 3730), (3701, 3932), (3932, 3870), (3853, 3932), (3764, 3933), (3935, 3764), (3764, 3936), (3898, 3764), (3764, 3756), (3928, 3764), (3764, 3925), (3904, 3764), (3762, 3732), (3762, 3761), (3930, 3762), (3762, 3701), (3760, 3762), (3762, 3697), (3698, 3762), (3732, 3765), (3926, 3732), (3732, 3928), (3730, 3732), (3732, 3698), (3870, 3732), (3894, 3930), (3938, 3894), (3894, 3758)]
|
||||
|
||||
|
||||
|
||||
def check_feasible_pulp(fixed_games):
|
||||
|
||||
model = pulp.LpProblem(f"Draws", pulp.LpMinimize)
|
||||
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
x[t1['id'], t2['id']] = pulp.LpVariable('x_'+str(t1['id'])+'_'+str(t2['id']),lowBound=0, upBound=1, cat=pulp.LpInteger)
|
||||
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
# model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
model += lpSum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1
|
||||
model += lpSum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1
|
||||
|
||||
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 3)
|
||||
model += lpSum(x[t['id'],t2['id']] for t2 in teams_from_country[c]) <= 2
|
||||
|
||||
# FIXATIONS
|
||||
for (t1,t2) in fixed_games:
|
||||
# print("FIXING",t1,t2)
|
||||
# model.addConstraint(x[t1,t2] == 1)
|
||||
model += x[t1,t2] == 1
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
model += x[t1,t2] + x[t2,t1] <= 1, f'directed_{t1}_{t2}'
|
||||
# model.addConstraint(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
model += lpSum(random.uniform(0,1)*x[key] for key in x.keys())
|
||||
tt =time.time()
|
||||
model.solve(XPRESS(msg=0,timeLimit=120,keepFiles=0))
|
||||
comp_time = time.time()-tt
|
||||
|
||||
if model.status in [-1,-2]:
|
||||
return False, comp_time
|
||||
else:
|
||||
return True, comp_time
|
||||
|
||||
|
||||
|
||||
|
||||
model = gp.Model('Draws')
|
||||
model.Params.OutputFlag = 0
|
||||
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
# x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer)
|
||||
x[t1['id'], t2['id']] = model.addVar(vtype=GRB.BINARY)
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
model.addConstr(gp.quicksum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
model.addConstr(gp.quicksum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
model.addConstr(gp.quicksum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2)
|
||||
|
||||
|
||||
for clash in Clash.objects.filter(draw__season=scenario.season):
|
||||
for c1 in clash.countries.all():
|
||||
for c2 in clash.countries.all():
|
||||
if c1 != c2 and teams_from_country.get(c1.shortname) and teams_from_country.get(c2.shortname):
|
||||
model.addConstr(gp.quicksum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t in teams_from_country[c1.shortname] for t2 in teams_from_country[c2.shortname]) <= 0)
|
||||
print("CLASH",c1,c2)
|
||||
|
||||
|
||||
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
model.addConstr(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
|
||||
|
||||
|
||||
def check_feasible_gurobi(fixed_games):
|
||||
|
||||
# FIXATIONS
|
||||
for key in x.keys():
|
||||
if key in fixed_games:
|
||||
x[key].lb = 1
|
||||
else:
|
||||
x[key].lb = 0
|
||||
|
||||
model.update()
|
||||
|
||||
# tt =time.time()
|
||||
# model.solve()
|
||||
model.optimize()
|
||||
# comp_time = time.time()-tt
|
||||
|
||||
|
||||
if model.Status == GRB.OPTIMAL:
|
||||
return True, 0
|
||||
else:
|
||||
# print("INFEASIBLE FOUND")
|
||||
return False, 0
|
||||
|
||||
|
||||
def check_feasible(fixed_games):
|
||||
model = xp.problem(name='Draws', sense=xp.minimize)
|
||||
model.setControl ('outputlog', 1)
|
||||
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer)
|
||||
|
||||
model.addVariable(x)
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2)
|
||||
|
||||
# FIXATIONS
|
||||
for (t1,t2) in fixed_games:
|
||||
# print("FIXING",t1,t2)
|
||||
model.addConstraint(x[t1,t2] == 1)
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
model.addConstraint(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
|
||||
tt =time.time()
|
||||
model.solve()
|
||||
comp_time = time.time()-tt
|
||||
|
||||
|
||||
if model.getProbStatus() != 6:
|
||||
# print("INFEASIBLE FOUND")
|
||||
return False, comp_time
|
||||
else:
|
||||
return True, comp_time
|
||||
|
||||
|
||||
|
||||
|
||||
# model = xp.problem(name='Draws', sense=xp.minimize)
|
||||
# model.setControl ('outputlog', 0)
|
||||
|
||||
# x = {}
|
||||
# for t1 in teams:
|
||||
# for t2 in teams:
|
||||
# if t1['country'] != t2['country']:
|
||||
# x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer)
|
||||
|
||||
# model.addVariable(x)
|
||||
|
||||
# # REQUIREMENTS
|
||||
# for t in teams:
|
||||
# for r in range(1,5):
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
# model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
# for c in countries:
|
||||
# if c != t['country']:
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2)
|
||||
|
||||
# for (t1,t2) in x.keys():
|
||||
# model.addConstraint(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
def check_feasible_fix(fixed_games):
|
||||
# FIXATIONS
|
||||
# for key in x.keys():
|
||||
# if key in fixed_games:
|
||||
# # x[key].lb = 1
|
||||
# model.chgbounds([x[key]],['L'],[1])
|
||||
# else:
|
||||
# # x[key].lb = 0
|
||||
# model.chgbounds([x[key]],['L'],[0])
|
||||
|
||||
reset_bounds = [key for key in x.keys() if key not in fixed_games]
|
||||
|
||||
model.chgbounds([x[key] for key in fixed_games],['L' for _ in range(len(fixed_games))],[1 for _ in range(len(fixed_games))])
|
||||
model.chgbounds([x[key] for key in reset_bounds],['L' for _ in range(len(reset_bounds))],[0 for _ in range(len(reset_bounds))])
|
||||
|
||||
tt =time.time()
|
||||
model.solve()
|
||||
comp_time = time.time()-tt
|
||||
|
||||
if model.getProbStatus() != 6:
|
||||
# print("INFEASIBLE FOUND")
|
||||
return False, comp_time
|
||||
return False
|
||||
else:
|
||||
return True, comp_time
|
||||
return True
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
import itertools
|
||||
from itertools import permutations , product
|
||||
|
||||
def simulate_draws(filename,n):
|
||||
|
||||
print("RUNNING ASYNC",filename)
|
||||
fixed_games=None
|
||||
for i_sim in range(1, n):
|
||||
if i_sim % 100 == 0:
|
||||
print("RUNNING ASYNC",filename,i_sim)
|
||||
# start_time = time.time()
|
||||
# n_computations = 0
|
||||
# check_time = 0
|
||||
# total_comp_time = 0
|
||||
|
||||
|
||||
possible_opps = {}
|
||||
for pos in range(8):
|
||||
p = pos//2+1
|
||||
teams_from_pot = list(teamObjects.filter(pot=p).values('id','country'))
|
||||
possible_opps[pos] = {
|
||||
t['id']: [t2['id'] for t2 in teams_from_pot if t2['country'] != t['country']] for t in teams
|
||||
}
|
||||
|
||||
sol_opps = {
|
||||
(t['id'],p):None
|
||||
for t in teams for p in range(8)
|
||||
}
|
||||
|
||||
sol_countries = {
|
||||
(t['id'],c):0
|
||||
for t in teams for c in countries if c != t['country']
|
||||
}
|
||||
|
||||
fixed_games = []
|
||||
feasible = True
|
||||
|
||||
for p in range(1,2):
|
||||
currentPot = list(teamObjects.filter(pot=p).values_list('id', flat=True))
|
||||
|
||||
while(feasible and currentPot):
|
||||
new_team = currentPot.pop(random.randint(0,len(currentPot)-1))
|
||||
for current_pos in range(0,8,2):
|
||||
if sol_opps[new_team,current_pos] != None and sol_opps[new_team,current_pos+1] != None:
|
||||
continue
|
||||
|
||||
|
||||
possible_opps[current_pos][new_team] = [t for t in possible_opps[current_pos][new_team] if sol_countries[new_team,getCountryById[t]] < 2 and sol_countries[t,getCountryById[new_team]] < 2]
|
||||
possible_opps[current_pos+1][new_team] = [t for t in possible_opps[current_pos+1][new_team] if sol_countries[new_team,getCountryById[t]] < 2 and sol_countries[t,getCountryById[new_team]] < 2]
|
||||
|
||||
list_1 = [None]
|
||||
list_2 = [None]
|
||||
if sol_opps[new_team,current_pos] == None:
|
||||
list_1 = possible_opps[current_pos][new_team]
|
||||
if sol_opps[new_team,current_pos+1] == None:
|
||||
list_2 = possible_opps[current_pos+1][new_team]
|
||||
|
||||
# unique_combinations = []
|
||||
# for i in range(len(list_1)):
|
||||
# for j in range(len(list_2)):
|
||||
# unique_combinations.append((list_1[i], list_2[j]))
|
||||
unique_combinations = list(itertools.product(list_1, list_2))
|
||||
random.shuffle(unique_combinations)
|
||||
|
||||
|
||||
no_solution_found = True
|
||||
while (no_solution_found):
|
||||
new_games = []
|
||||
# if sol_opps[new_team,current_pos] == None:
|
||||
# new_opponent1 = random.choice(possible_opps[current_pos][new_team])
|
||||
# new_games.append((new_team,new_opponent1))
|
||||
|
||||
# if sol_opps[new_team,current_pos+1] == None:
|
||||
# new_opponent2 = random.choice(possible_opps[current_pos+1][new_team])
|
||||
# new_games.append((new_opponent2,new_team))
|
||||
|
||||
new_opponent1,new_opponent2 = unique_combinations.pop()
|
||||
|
||||
if new_opponent1:
|
||||
new_games.append((new_team,new_opponent1))
|
||||
|
||||
if new_opponent2:
|
||||
new_games.append((new_opponent2,new_team))
|
||||
|
||||
# n_computations += 1
|
||||
# tt = time.time()
|
||||
check, comp_time = check_feasible_gurobi(fixed_games+new_games)
|
||||
# check_time += time.time()-tt
|
||||
# total_comp_time += comp_time
|
||||
if check:
|
||||
no_solution_found = False
|
||||
if sol_opps[new_team,current_pos] == None:
|
||||
sol_opps[new_team,current_pos] = new_opponent1
|
||||
sol_countries[new_team,getCountryById[new_opponent1]] += 1
|
||||
sol_opps[new_opponent1,(2*p-1)] = new_team
|
||||
sol_countries[new_opponent1,getCountryById[new_team]] += 1
|
||||
|
||||
if new_team in possible_opps[(2*p-1)-1][new_opponent1]:
|
||||
possible_opps[(2*p-1)-1][new_opponent1].remove(new_team)
|
||||
if sol_opps[new_team,current_pos+1] == None:
|
||||
sol_opps[new_team,current_pos+1] = new_opponent2
|
||||
sol_countries[new_team,getCountryById[new_opponent2]] += 1
|
||||
sol_opps[new_opponent2,(2*p-1)-(1)] = new_team
|
||||
sol_countries[new_opponent2,getCountryById[new_team]] += 1
|
||||
if new_team in possible_opps[(2*p-1)][new_opponent2]:
|
||||
possible_opps[(2*p-1)][new_opponent2].remove(new_team)
|
||||
fixed_games += new_games
|
||||
|
||||
|
||||
for p in range(2,5):
|
||||
currentPot = list(teamObjects.filter(pot=p).values_list('id', flat=True))
|
||||
|
||||
|
||||
while(feasible and currentPot):
|
||||
new_team = currentPot.pop(random.randint(0,len(currentPot)-1))
|
||||
|
||||
|
||||
unique_combinations = {}
|
||||
for current_pos in range(2*(p-1),8,2):
|
||||
|
||||
possible_opps[current_pos][new_team] = [t for t in possible_opps[current_pos][new_team] if sol_countries[new_team,getCountryById[t]] < 2 and
|
||||
sol_countries[t,getCountryById[new_team]] < 2 and sol_opps[t,(2*p-1)] == None]
|
||||
possible_opps[current_pos+1][new_team] = [t for t in possible_opps[current_pos+1][new_team] if sol_countries[new_team,getCountryById[t]] < 2 and
|
||||
sol_countries[t,getCountryById[new_team]] < 2 and sol_opps[t,(2*p-1)-1] == None]
|
||||
|
||||
list_1 = [0]
|
||||
list_2 = [0]
|
||||
if sol_opps[new_team,current_pos] == None:
|
||||
list_1 = possible_opps[current_pos][new_team]
|
||||
if sol_opps[new_team,current_pos+1] == None:
|
||||
list_2 = possible_opps[current_pos+1][new_team]
|
||||
|
||||
unique_combinations[current_pos] = []
|
||||
for i in list_1:
|
||||
for j in list_2:
|
||||
if i != j or (i == 0 and j == 0):
|
||||
unique_combinations[current_pos].append((i, j))
|
||||
|
||||
combi_list = list(itertools.product(*unique_combinations.values()))
|
||||
random.shuffle(combi_list)
|
||||
|
||||
|
||||
|
||||
|
||||
# print("STOP")
|
||||
# for current_pos in range(2*(p-1),8,2):
|
||||
# print(current_pos,possible_opps[current_pos][new_team])
|
||||
# print(current_pos+1,possible_opps[current_pos+1][new_team])
|
||||
# list_1 = [0]
|
||||
# list_2 = [0]
|
||||
# if sol_opps[new_team,current_pos] == None:
|
||||
# list_1 = possible_opps[current_pos][new_team]
|
||||
# if sol_opps[new_team,current_pos+1] == None:
|
||||
# list_2 = possible_opps[current_pos+1][new_team]
|
||||
|
||||
# unique_combinations[current_pos] = []
|
||||
# for i in list_1:
|
||||
# for j in list_2:
|
||||
# if i != j or (i == 0 and j == 0):
|
||||
# unique_combinations[current_pos].append((i, j))
|
||||
# print(unique_combinations)
|
||||
# exit()
|
||||
|
||||
|
||||
no_solution_found = True
|
||||
while (no_solution_found):
|
||||
# print("\tPOP",len(combi_list))
|
||||
new_games = []
|
||||
new_opponents = combi_list.pop()
|
||||
for o1,o2 in new_opponents:
|
||||
if o1:
|
||||
new_games.append((new_team,o1))
|
||||
if o2:
|
||||
new_games.append((o2,new_team))
|
||||
|
||||
|
||||
# n_computations += 1
|
||||
# tt = time.time()
|
||||
check, comp_time = check_feasible_gurobi(fixed_games+new_games)
|
||||
# check_time += time.time()-tt
|
||||
# total_comp_time += comp_time
|
||||
if check:
|
||||
no_solution_found = False
|
||||
fixed_games += new_games
|
||||
for i,(new_opponent1,new_opponent2) in enumerate(new_opponents):
|
||||
current_pos = 2*(p-1)+2*i
|
||||
if sol_opps[new_team,current_pos] == None:
|
||||
sol_opps[new_team,current_pos] = new_opponent1
|
||||
sol_countries[new_team,getCountryById[new_opponent1]] += 1
|
||||
sol_opps[new_opponent1 ,(2*p-1)] = new_team
|
||||
sol_countries[new_opponent1,getCountryById[new_team]] += 1
|
||||
if new_team in possible_opps[(2*p-1)-1][new_opponent1]:
|
||||
possible_opps[(2*p-1)-1][new_opponent1].remove(new_team)
|
||||
if sol_opps[new_team,current_pos+1] == None:
|
||||
sol_opps[new_team,current_pos+1] = new_opponent2
|
||||
sol_countries[new_team,getCountryById[new_opponent2]] += 1
|
||||
sol_opps[new_opponent2,(2*p-1)-(1)] = new_team
|
||||
sol_countries[new_opponent2,getCountryById[new_team]] += 1
|
||||
if new_team in possible_opps[(2*p-1)][new_opponent2]:
|
||||
possible_opps[(2*p-1)][new_opponent2].remove(new_team)
|
||||
|
||||
# print("COMPUTATIONS",n_computations)
|
||||
# print("TIME\t",time.time()-start_time)
|
||||
# print("CHECK\t",check_time)
|
||||
# print("COMP\t",total_comp_time)
|
||||
|
||||
|
||||
|
||||
with open(filename+'.csv', "a") as f:
|
||||
for t in teams:
|
||||
f.write(f"{i_sim},{t['id']},{';'.join([str(sol_opps[t['id'],p]) for p in range(8)])}\n")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# # WRITE SOL '.html'
|
||||
# sol = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
|
||||
# sol += " \
|
||||
# <style> \
|
||||
# table, th, td { \
|
||||
# border: 1px solid black; \
|
||||
# border-collapse: collapse; \
|
||||
# text-align: center; \
|
||||
# min-width:40px; \
|
||||
# padding:3px; \
|
||||
# margin: 3px; \
|
||||
# font-family : Arial;\
|
||||
# } \
|
||||
# h1 {\
|
||||
# font-family : Arial;\
|
||||
# }\
|
||||
# \
|
||||
# #etable td:nth-child(10),#etable th:nth-child(10) { border-right: 5px solid black; }\
|
||||
# #etable td:nth-child(19),#etable th:nth-child(19) { border-right: 5px solid black; }\
|
||||
# #etable td:nth-child(28),#etable th:nth-child(28) { border-right: 5px solid black; }\
|
||||
# tr:nth-child(9) { border-bottom: 5px solid black; }\
|
||||
# tr:nth-child(18) { border-bottom: 5px solid black; }\
|
||||
# tr:nth-child(27) { border-bottom: 5px solid black; }\
|
||||
# </style> \
|
||||
# "
|
||||
# sol += "<table id='etable' style='border:5px solid black'>\n"
|
||||
# sol += "<thead>\n"
|
||||
# sol += "<tr>"
|
||||
# sol += "<th></th>"
|
||||
# sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot A</th>"
|
||||
# sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot B</th>"
|
||||
# sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot C</th>"
|
||||
# sol += "<th colspan=9>Pot D</th>"
|
||||
# sol += "</tr>"
|
||||
# sol += "<tr>\n"
|
||||
# sol += f"<th></th>\n"
|
||||
# for t in teams:
|
||||
# sol += f"<th>{getTeamById[t['id']]}</th>\n"
|
||||
# sol += "</tr>\n"
|
||||
# sol += "</thead>\n"
|
||||
# sol += "<tbody>\n"
|
||||
# for t1 in teams:
|
||||
# sol += "<tr>\n"
|
||||
# sol += f"<td>{getTeamById[t1['id']]}</td>"
|
||||
# for t2 in teams:
|
||||
# if (t1['id'],t2['id']) in fixed_games:
|
||||
# sol += f"<td>{t2['country']}</td>"
|
||||
# elif (t2['id'],t1['id']) in fixed_games:
|
||||
# sol += f"<td>@{t2['country']}</td>"
|
||||
# else:
|
||||
# sol += f"<td></td>"
|
||||
# sol += "</tr>\n"
|
||||
# sol += "</tbody>\n"
|
||||
# sol += "</table>\n"
|
||||
|
||||
# with open(f'debug.html', 'w') as f:
|
||||
# f.write(sol)
|
||||
|
||||
|
||||
# n = sys.maxsize
|
||||
|
||||
# pool = Pool()
|
||||
# result = {}
|
||||
# answer = {}
|
||||
# n_threads = cpu_count()
|
||||
# # n_threads = 1
|
||||
|
||||
# for cpu in range(n_threads):
|
||||
# result[cpu] = pool.apply_async(simulate_draws, args=(f'thread_{cpu}_pot_by_pot', n,))
|
||||
|
||||
# for cpu in range(n_threads):
|
||||
# answer[cpu] = result[cpu].get()
|
||||
|
||||
|
||||
# %%
|
||||
n = 2
|
||||
simulate_draws('test', n)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# %%
|
||||
506
uefa/cycle24/simulations/drawsimulation_october_gurobi_double.py
Executable file
506
uefa/cycle24/simulations/drawsimulation_october_gurobi_double.py
Executable file
@ -0,0 +1,506 @@
|
||||
# %%
|
||||
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"
|
||||
|
||||
from leagues import settings
|
||||
settings.DATABASES['default']['NAME'] = PROJECT_PATH+'/db.sqlite3'
|
||||
# settings.DATABASES['default']['ENGINE'] = 'django.db.backends.postgresql_psycopg2'
|
||||
# settings.DATABASES['default']['HOST'] = '0.0.0.0'
|
||||
# settings.DATABASES['default']['PORT'] = '5432'
|
||||
# settings.DATABASES['default']['USER'] = 'postgres'
|
||||
# settings.DATABASES['default']['PASSWORD'] = 'secret123'
|
||||
# settings.DATABASES['default']['NAME'] = 'mypgsqldb'
|
||||
# settings.DATABASES['default']['ATOMIC_REQUESTS'] = False
|
||||
# settings.DATABASES['default']['AUTOCOMMIT'] = True
|
||||
# settings.DATABASES['default']['CONN_MAX_AGE'] = 0
|
||||
# settings.DATABASES['default']['CONN_HEALTH_CHECKS'] = False
|
||||
# settings.DATABASES['default']['OPTIONS'] = {}
|
||||
|
||||
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["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["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprs.jar"
|
||||
os.environ["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprb.jar" + os.pathsep + os.environ["CLASSPATH"]
|
||||
os.environ["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprm.jar" + os.pathsep + os.environ["CLASSPATH"]
|
||||
os.environ["PATH"] = os.environ["XPRESSDIR"] + "/bin" + os.pathsep + os.environ["PATH"]
|
||||
|
||||
|
||||
import django
|
||||
django.setup()
|
||||
|
||||
from scheduler.models import *
|
||||
from draws.models import *
|
||||
import csv
|
||||
from multiprocessing import Pool, cpu_count
|
||||
import random
|
||||
import time
|
||||
import pulp
|
||||
from pulp import lpSum, value, XPRESS, GUROBI, PULP_CBC_CMD
|
||||
import gurobipy as gp
|
||||
from gurobipy import GRB
|
||||
import xpress as xp
|
||||
# xp.controls.outputlog = 0
|
||||
|
||||
|
||||
|
||||
scenario = Scenario.objects.get(id=4)
|
||||
|
||||
# %%
|
||||
|
||||
teamObjects = Team.objects.filter(season=scenario.season,active=True).order_by('pot')
|
||||
teams = teamObjects.values('id','country','pot','name')
|
||||
|
||||
getTeamById = {}
|
||||
for t in teamObjects:
|
||||
getTeamById[t.id] = f"({t.pot}) {t.name}"
|
||||
|
||||
getCountryById = {}
|
||||
for t in teamObjects:
|
||||
getCountryById[t.id] = t.country
|
||||
|
||||
|
||||
countries = list(set(teamObjects.values_list('country', flat=True)))
|
||||
teams_from_country = {
|
||||
c:[t for t in teams if t['country']==c] for c in countries
|
||||
}
|
||||
|
||||
pot = {}
|
||||
for i in teamObjects.values_list('pot',flat=True).distinct():
|
||||
pot[i] = list(teams.filter(pot=i))
|
||||
|
||||
teams = list(teams)
|
||||
|
||||
|
||||
|
||||
|
||||
# fixed_games = [(3940, 3894), (3933, 3940), (3940, 3937), (3765, 3940), (3940, 3895), (3700, 3940), (3940, 3696), (3925, 3940), (3702, 3935), (3894, 3702), (3702, 3926), (3937, 3702), (3702, 3700), (3758, 3702), (3702, 3699), (3757, 3702), (3932, 3762), (3732, 3932), (3932, 3938), (3761, 3932), (3932, 3730), (3701, 3932), (3932, 3870), (3853, 3932), (3764, 3933), (3935, 3764), (3764, 3936), (3898, 3764), (3764, 3756), (3928, 3764), (3764, 3925), (3904, 3764), (3762, 3732), (3762, 3761), (3930, 3762), (3762, 3701), (3760, 3762), (3762, 3697), (3698, 3762), (3732, 3765), (3926, 3732), (3732, 3928), (3730, 3732), (3732, 3698), (3870, 3732), (3894, 3930), (3938, 3894), (3894, 3758)]
|
||||
|
||||
|
||||
|
||||
def check_feasible_pulp(fixed_games):
|
||||
|
||||
model = pulp.LpProblem(f"Draws", pulp.LpMinimize)
|
||||
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
x[t1['id'], t2['id']] = pulp.LpVariable('x_'+str(t1['id'])+'_'+str(t2['id']),lowBound=0, upBound=1, cat=pulp.LpInteger)
|
||||
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
# model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
model += lpSum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1
|
||||
model += lpSum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1
|
||||
|
||||
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 3)
|
||||
model += lpSum(x[t['id'],t2['id']] for t2 in teams_from_country[c]) <= 2
|
||||
|
||||
# FIXATIONS
|
||||
for (t1,t2) in fixed_games:
|
||||
# print("FIXING",t1,t2)
|
||||
# model.addConstraint(x[t1,t2] == 1)
|
||||
model += x[t1,t2] == 1
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
model += x[t1,t2] + x[t2,t1] <= 1, f'directed_{t1}_{t2}'
|
||||
# model.addConstraint(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
model += lpSum(random.uniform(0,1)*x[key] for key in x.keys())
|
||||
tt =time.time()
|
||||
model.solve(XPRESS(msg=0,timeLimit=120,keepFiles=0))
|
||||
comp_time = time.time()-tt
|
||||
|
||||
if model.status in [-1,-2]:
|
||||
return False, comp_time
|
||||
else:
|
||||
return True, comp_time
|
||||
|
||||
|
||||
|
||||
|
||||
model = gp.Model('Draws')
|
||||
model.Params.OutputFlag = 0
|
||||
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
# x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer)
|
||||
x[t1['id'], t2['id']] = model.addVar(vtype=GRB.BINARY)
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
model.addConstr(gp.quicksum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
model.addConstr(gp.quicksum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
model.addConstr(gp.quicksum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2)
|
||||
|
||||
|
||||
|
||||
for clash in Clash.objects.filter(draw__season=scenario.season):
|
||||
for c1 in clash.countries.all():
|
||||
for c2 in clash.countries.all():
|
||||
if c1 != c2 and teams_from_country.get(c1.shortname) and teams_from_country.get(c2.shortname):
|
||||
model.addConstr(gp.quicksum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t in teams_from_country[c1.shortname] for t2 in teams_from_country[c2.shortname]) <= 0)
|
||||
print("CLASH",c1,c2)
|
||||
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
model.addConstr(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
|
||||
|
||||
|
||||
def check_feasible_gurobi(fixed_games):
|
||||
|
||||
# FIXATIONS
|
||||
for key in x.keys():
|
||||
if key in fixed_games:
|
||||
x[key].lb = 1
|
||||
else:
|
||||
x[key].lb = 0
|
||||
|
||||
model.update()
|
||||
|
||||
# tt =time.time()
|
||||
# model.solve()
|
||||
model.optimize()
|
||||
# comp_time = time.time()-tt
|
||||
|
||||
|
||||
if model.Status == GRB.OPTIMAL:
|
||||
return True, 0
|
||||
else:
|
||||
# print("INFEASIBLE FOUND")
|
||||
return False, 0
|
||||
|
||||
|
||||
def check_feasible(fixed_games):
|
||||
model = xp.problem(name='Draws', sense=xp.minimize)
|
||||
model.setControl ('outputlog', 1)
|
||||
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer)
|
||||
|
||||
model.addVariable(x)
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 5)
|
||||
|
||||
# FIXATIONS
|
||||
for (t1,t2) in fixed_games:
|
||||
# print("FIXING",t1,t2)
|
||||
model.addConstraint(x[t1,t2] == 1)
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
model.addConstraint(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
|
||||
tt =time.time()
|
||||
model.solve()
|
||||
comp_time = time.time()-tt
|
||||
|
||||
|
||||
if model.getProbStatus() != 6:
|
||||
# print("INFEASIBLE FOUND")
|
||||
return False, comp_time
|
||||
else:
|
||||
return True, comp_time
|
||||
|
||||
|
||||
|
||||
|
||||
# model = xp.problem(name='Draws', sense=xp.minimize)
|
||||
# model.setControl ('outputlog', 0)
|
||||
|
||||
# x = {}
|
||||
# for t1 in teams:
|
||||
# for t2 in teams:
|
||||
# if t1['country'] != t2['country']:
|
||||
# x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer)
|
||||
|
||||
# model.addVariable(x)
|
||||
|
||||
# # REQUIREMENTS
|
||||
# for t in teams:
|
||||
# for r in range(1,5):
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
# model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
# for c in countries:
|
||||
# if c != t['country']:
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2)
|
||||
|
||||
# for (t1,t2) in x.keys():
|
||||
# model.addConstraint(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
def check_feasible_fix(fixed_games):
|
||||
# FIXATIONS
|
||||
# for key in x.keys():
|
||||
# if key in fixed_games:
|
||||
# # x[key].lb = 1
|
||||
# model.chgbounds([x[key]],['L'],[1])
|
||||
# else:
|
||||
# # x[key].lb = 0
|
||||
# model.chgbounds([x[key]],['L'],[0])
|
||||
|
||||
reset_bounds = [key for key in x.keys() if key not in fixed_games]
|
||||
|
||||
model.chgbounds([x[key] for key in fixed_games],['L' for _ in range(len(fixed_games))],[1 for _ in range(len(fixed_games))])
|
||||
model.chgbounds([x[key] for key in reset_bounds],['L' for _ in range(len(reset_bounds))],[0 for _ in range(len(reset_bounds))])
|
||||
|
||||
tt =time.time()
|
||||
model.solve()
|
||||
comp_time = time.time()-tt
|
||||
|
||||
if model.getProbStatus() != 6:
|
||||
# print("INFEASIBLE FOUND")
|
||||
return False, comp_time
|
||||
return False
|
||||
else:
|
||||
return True, comp_time
|
||||
return True
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
import itertools
|
||||
from itertools import permutations , product
|
||||
|
||||
def simulate_draws(filename,n):
|
||||
|
||||
print("RUNNING ASYNC",filename)
|
||||
fixed_games=None
|
||||
for i in range(1, n):
|
||||
if i % 100 == 0:
|
||||
print("RUNNING ASYNC",filename,i)
|
||||
# start_time = time.time()
|
||||
# n_computations = 0
|
||||
# check_time = 0
|
||||
# total_comp_time = 0
|
||||
|
||||
|
||||
possible_opps = {}
|
||||
for pos in range(8):
|
||||
p = pos//2+1
|
||||
teams_from_pot = list(teamObjects.filter(pot=p).values('id','country'))
|
||||
possible_opps[pos] = {
|
||||
t['id']: [t2['id'] for t2 in teams_from_pot if t2['country'] != t['country']] for t in teams
|
||||
}
|
||||
|
||||
sol_opps = {
|
||||
(t['id'],p):None
|
||||
for t in teams for p in range(8)
|
||||
}
|
||||
|
||||
sol_countries = {
|
||||
(t['id'],c):0
|
||||
for t in teams for c in countries if c != t['country']
|
||||
}
|
||||
|
||||
fixed_games = []
|
||||
feasible = True
|
||||
|
||||
for p in range(1,5):
|
||||
currentPot = list(teamObjects.filter(pot=p).values_list('id', flat=True))
|
||||
|
||||
while(feasible and currentPot):
|
||||
new_team = currentPot.pop(random.randint(0,len(currentPot)-1))
|
||||
for current_pos in range(2*(p-1),8,2):
|
||||
if sol_opps[new_team,current_pos] != None and sol_opps[new_team,current_pos+1] != None:
|
||||
continue
|
||||
|
||||
possible_opps[current_pos][new_team] = [t for t in possible_opps[current_pos][new_team] if sol_countries[new_team,getCountryById[t]] < 2 and
|
||||
sol_countries[t,getCountryById[new_team]] < 2 and sol_opps[t,(2*p-1)] == None]
|
||||
possible_opps[current_pos+1][new_team] = [t for t in possible_opps[current_pos+1][new_team] if sol_countries[new_team,getCountryById[t]] < 2 and
|
||||
sol_countries[t,getCountryById[new_team]] < 2 and sol_opps[t,(2*p-1)-1] == None]
|
||||
|
||||
list_1 = [None]
|
||||
list_2 = [None]
|
||||
if sol_opps[new_team,current_pos] == None:
|
||||
list_1 = possible_opps[current_pos][new_team]
|
||||
if sol_opps[new_team,current_pos+1] == None:
|
||||
list_2 = possible_opps[current_pos+1][new_team]
|
||||
|
||||
# unique_combinations = []
|
||||
# for i in range(len(list_1)):
|
||||
# for j in range(len(list_2)):
|
||||
# unique_combinations.append((list_1[i], list_2[j]))
|
||||
unique_combinations = list(itertools.product(list_1, list_2))
|
||||
random.shuffle(unique_combinations)
|
||||
|
||||
|
||||
no_solution_found = True
|
||||
while (no_solution_found):
|
||||
new_games = []
|
||||
# if sol_opps[new_team,current_pos] == None:
|
||||
# new_opponent1 = random.choice(possible_opps[current_pos][new_team])
|
||||
# new_games.append((new_team,new_opponent1))
|
||||
|
||||
# if sol_opps[new_team,current_pos+1] == None:
|
||||
# new_opponent2 = random.choice(possible_opps[current_pos+1][new_team])
|
||||
# new_games.append((new_opponent2,new_team))
|
||||
|
||||
new_opponent1,new_opponent2 = unique_combinations.pop()
|
||||
print(new_opponent1,new_opponent2)
|
||||
|
||||
if new_opponent1:
|
||||
new_games.append((new_team,new_opponent1))
|
||||
|
||||
if new_opponent2:
|
||||
new_games.append((new_opponent2,new_team))
|
||||
|
||||
# n_computations += 1
|
||||
# tt = time.time()
|
||||
check, comp_time = check_feasible_gurobi(fixed_games+new_games)
|
||||
# check_time += time.time()-tt
|
||||
# total_comp_time += comp_time
|
||||
if check:
|
||||
no_solution_found = False
|
||||
if sol_opps[new_team,current_pos] == None:
|
||||
sol_opps[new_team,current_pos] = new_opponent1
|
||||
sol_countries[new_team,getCountryById[new_opponent1]] += 1
|
||||
sol_opps[new_opponent1,(2*p-1)] = new_team
|
||||
sol_countries[new_opponent1,getCountryById[new_team]] += 1
|
||||
if new_team in possible_opps[(2*p-1)-1][new_opponent1]:
|
||||
possible_opps[(2*p-1)-1][new_opponent1].remove(new_team)
|
||||
if sol_opps[new_team,current_pos+1] == None:
|
||||
sol_opps[new_team,current_pos+1] = new_opponent2
|
||||
sol_countries[new_team,getCountryById[new_opponent2]] += 1
|
||||
sol_opps[new_opponent2,(2*p-1)-(1)] = new_team
|
||||
sol_countries[new_opponent2,getCountryById[new_team]] += 1
|
||||
if new_team in possible_opps[(2*p-1)][new_opponent2]:
|
||||
possible_opps[(2*p-1)][new_opponent2].remove(new_team)
|
||||
fixed_games += new_games
|
||||
|
||||
|
||||
|
||||
# print("COMPUTATIONS",n_computations)
|
||||
# print("TIME\t",time.time()-start_time)
|
||||
# print("CHECK\t",check_time)
|
||||
# print("COMP\t",total_comp_time)
|
||||
|
||||
|
||||
|
||||
with open(filename+'.csv', "a") as f:
|
||||
for t in teams:
|
||||
f.write(f"{i},{t['id']},{';'.join([str(sol_opps[t['id'],p]) for p in range(8)])}\n")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# WRITE SOL '.html'
|
||||
sol = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
|
||||
sol += " \
|
||||
<style> \
|
||||
table, th, td { \
|
||||
border: 1px solid black; \
|
||||
border-collapse: collapse; \
|
||||
text-align: center; \
|
||||
min-width:40px; \
|
||||
padding:3px; \
|
||||
margin: 3px; \
|
||||
font-family : Arial;\
|
||||
} \
|
||||
h1 {\
|
||||
font-family : Arial;\
|
||||
}\
|
||||
\
|
||||
#etable td:nth-child(10),#etable th:nth-child(10) { border-right: 5px solid black; }\
|
||||
#etable td:nth-child(19),#etable th:nth-child(19) { border-right: 5px solid black; }\
|
||||
#etable td:nth-child(28),#etable th:nth-child(28) { border-right: 5px solid black; }\
|
||||
tr:nth-child(9) { border-bottom: 5px solid black; }\
|
||||
tr:nth-child(18) { border-bottom: 5px solid black; }\
|
||||
tr:nth-child(27) { border-bottom: 5px solid black; }\
|
||||
</style> \
|
||||
"
|
||||
sol += "<table id='etable' style='border:5px solid black'>\n"
|
||||
sol += "<thead>\n"
|
||||
sol += "<tr>"
|
||||
sol += "<th></th>"
|
||||
sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot A</th>"
|
||||
sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot B</th>"
|
||||
sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot C</th>"
|
||||
sol += "<th colspan=9>Pot D</th>"
|
||||
sol += "</tr>"
|
||||
sol += "<tr>\n"
|
||||
sol += f"<th></th>\n"
|
||||
for t in teams:
|
||||
sol += f"<th>{getTeamById[t['id']]}</th>\n"
|
||||
sol += "</tr>\n"
|
||||
sol += "</thead>\n"
|
||||
sol += "<tbody>\n"
|
||||
for t1 in teams:
|
||||
sol += "<tr>\n"
|
||||
sol += f"<td>{getTeamById[t1['id']]}</td>"
|
||||
for t2 in teams:
|
||||
if (t1['id'],t2['id']) in fixed_games:
|
||||
sol += f"<td>{t2['country']}</td>"
|
||||
elif (t2['id'],t1['id']) in fixed_games:
|
||||
sol += f"<td>@{t2['country']}</td>"
|
||||
else:
|
||||
sol += f"<td></td>"
|
||||
sol += "</tr>\n"
|
||||
sol += "</tbody>\n"
|
||||
sol += "</table>\n"
|
||||
|
||||
with open(f'debug.html', 'w') as f:
|
||||
f.write(sol)
|
||||
|
||||
|
||||
# n = sys.maxsize
|
||||
|
||||
# pool = Pool()
|
||||
# result = {}
|
||||
# answer = {}
|
||||
# n_threads = cpu_count()
|
||||
# # n_threads = 1
|
||||
|
||||
# for cpu in range(n_threads):
|
||||
# result[cpu] = pool.apply_async(simulate_draws, args=(f'thread_{cpu}_pot_by_pot', n,))
|
||||
|
||||
# for cpu in range(n_threads):
|
||||
# answer[cpu] = result[cpu].get()
|
||||
|
||||
|
||||
# %%
|
||||
n = 2
|
||||
simulate_draws('test', n)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# %%
|
||||
582
uefa/cycle24/simulations/mixed_draws/drawsimulation_october_gurobi_all.py
Executable file
582
uefa/cycle24/simulations/mixed_draws/drawsimulation_october_gurobi_all.py
Executable file
@ -0,0 +1,582 @@
|
||||
# %%
|
||||
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"
|
||||
|
||||
from leagues import settings
|
||||
settings.DATABASES['default']['NAME'] = PROJECT_PATH+'/db.sqlite3'
|
||||
# settings.DATABASES['default']['ENGINE'] = 'django.db.backends.postgresql_psycopg2'
|
||||
# settings.DATABASES['default']['HOST'] = '0.0.0.0'
|
||||
# settings.DATABASES['default']['PORT'] = '5432'
|
||||
# settings.DATABASES['default']['USER'] = 'postgres'
|
||||
# settings.DATABASES['default']['PASSWORD'] = 'secret123'
|
||||
# settings.DATABASES['default']['NAME'] = 'mypgsqldb'
|
||||
# settings.DATABASES['default']['ATOMIC_REQUESTS'] = False
|
||||
# settings.DATABASES['default']['AUTOCOMMIT'] = True
|
||||
# settings.DATABASES['default']['CONN_MAX_AGE'] = 0
|
||||
# settings.DATABASES['default']['CONN_HEALTH_CHECKS'] = False
|
||||
# settings.DATABASES['default']['OPTIONS'] = {}
|
||||
|
||||
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["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["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprs.jar"
|
||||
os.environ["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprb.jar" + os.pathsep + os.environ["CLASSPATH"]
|
||||
os.environ["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprm.jar" + os.pathsep + os.environ["CLASSPATH"]
|
||||
os.environ["PATH"] = os.environ["XPRESSDIR"] + "/bin" + os.pathsep + os.environ["PATH"]
|
||||
|
||||
|
||||
import django
|
||||
django.setup()
|
||||
|
||||
from scheduler.models import *
|
||||
import csv
|
||||
from multiprocessing import Pool, cpu_count
|
||||
import random
|
||||
import time
|
||||
import pulp
|
||||
from pulp import lpSum, value, XPRESS, GUROBI, PULP_CBC_CMD
|
||||
import gurobipy as gp
|
||||
from gurobipy import GRB
|
||||
import xpress as xp
|
||||
# xp.controls.outputlog = 0
|
||||
|
||||
|
||||
|
||||
scenario = Scenario.objects.get(id=34)
|
||||
|
||||
# %%
|
||||
|
||||
teamObjects = Team.objects.filter(season=scenario.season,active=True).order_by('pot')
|
||||
teams = teamObjects.values('id','country','pot','name')
|
||||
|
||||
getTeamById = {}
|
||||
for t in teamObjects:
|
||||
getTeamById[t.id] = f"({t.pot}) {t.name}"
|
||||
|
||||
getCountryById = {}
|
||||
for t in teamObjects:
|
||||
getCountryById[t.id] = t.country
|
||||
|
||||
countries = list(set(teamObjects.values_list('country', flat=True)))
|
||||
teams_from_country = {
|
||||
c:[t for t in teams if t['country']==c] for c in countries
|
||||
}
|
||||
|
||||
pot = {}
|
||||
for i in teamObjects.values_list('pot',flat=True).distinct():
|
||||
pot[i] = list(teams.filter(pot=i))
|
||||
|
||||
teams = list(teams)
|
||||
|
||||
|
||||
|
||||
|
||||
# fixed_games = [(3940, 3894), (3933, 3940), (3940, 3937), (3765, 3940), (3940, 3895), (3700, 3940), (3940, 3696), (3925, 3940), (3702, 3935), (3894, 3702), (3702, 3926), (3937, 3702), (3702, 3700), (3758, 3702), (3702, 3699), (3757, 3702), (3932, 3762), (3732, 3932), (3932, 3938), (3761, 3932), (3932, 3730), (3701, 3932), (3932, 3870), (3853, 3932), (3764, 3933), (3935, 3764), (3764, 3936), (3898, 3764), (3764, 3756), (3928, 3764), (3764, 3925), (3904, 3764), (3762, 3732), (3762, 3761), (3930, 3762), (3762, 3701), (3760, 3762), (3762, 3697), (3698, 3762), (3732, 3765), (3926, 3732), (3732, 3928), (3730, 3732), (3732, 3698), (3870, 3732), (3894, 3930), (3938, 3894), (3894, 3758)]
|
||||
|
||||
|
||||
|
||||
def check_feasible_pulp(fixed_games):
|
||||
|
||||
model = pulp.LpProblem(f"Draws", pulp.LpMinimize)
|
||||
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
x[t1['id'], t2['id']] = pulp.LpVariable('x_'+str(t1['id'])+'_'+str(t2['id']),lowBound=0, upBound=1, cat=pulp.LpInteger)
|
||||
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
# model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
model += lpSum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1
|
||||
model += lpSum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1
|
||||
|
||||
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 3)
|
||||
model += lpSum(x[t['id'],t2['id']] for t2 in teams_from_country[c]) <= 2
|
||||
|
||||
# FIXATIONS
|
||||
for (t1,t2) in fixed_games:
|
||||
# print("FIXING",t1,t2)
|
||||
# model.addConstraint(x[t1,t2] == 1)
|
||||
model += x[t1,t2] == 1
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
model += x[t1,t2] + x[t2,t1] <= 1, f'directed_{t1}_{t2}'
|
||||
# model.addConstraint(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
model += lpSum(random.uniform(0,1)*x[key] for key in x.keys())
|
||||
tt =time.time()
|
||||
model.solve(XPRESS(msg=0,timeLimit=120,keepFiles=0))
|
||||
comp_time = time.time()-tt
|
||||
|
||||
if model.status in [-1,-2]:
|
||||
return False, comp_time
|
||||
else:
|
||||
return True, comp_time
|
||||
|
||||
|
||||
|
||||
|
||||
model = gp.Model('Draws')
|
||||
model.Params.OutputFlag = 0
|
||||
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
# x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer)
|
||||
x[t1['id'], t2['id']] = model.addVar(vtype=GRB.BINARY)
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
model.addConstr(gp.quicksum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
model.addConstr(gp.quicksum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
model.addConstr(gp.quicksum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2)
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
model.addConstr(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
|
||||
|
||||
|
||||
def check_feasible_gurobi(fixed_games):
|
||||
|
||||
# FIXATIONS
|
||||
for key in x.keys():
|
||||
if key in fixed_games:
|
||||
x[key].lb = 1
|
||||
else:
|
||||
x[key].lb = 0
|
||||
|
||||
model.update()
|
||||
|
||||
# tt =time.time()
|
||||
# model.solve()
|
||||
model.optimize()
|
||||
# comp_time = time.time()-tt
|
||||
|
||||
|
||||
if model.Status == GRB.OPTIMAL:
|
||||
return True, 0
|
||||
else:
|
||||
# print("INFEASIBLE FOUND")
|
||||
return False, 0
|
||||
|
||||
|
||||
def check_feasible(fixed_games):
|
||||
model = xp.problem(name='Draws', sense=xp.minimize)
|
||||
model.setControl ('outputlog', 1)
|
||||
|
||||
x = {}
|
||||
for t1 in teams:
|
||||
for t2 in teams:
|
||||
if t1['country'] != t2['country']:
|
||||
x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer)
|
||||
|
||||
model.addVariable(x)
|
||||
|
||||
# REQUIREMENTS
|
||||
for t in teams:
|
||||
for r in range(1,5):
|
||||
model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
for c in countries:
|
||||
if c != t['country']:
|
||||
model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2)
|
||||
|
||||
# FIXATIONS
|
||||
for (t1,t2) in fixed_games:
|
||||
# print("FIXING",t1,t2)
|
||||
model.addConstraint(x[t1,t2] == 1)
|
||||
|
||||
for (t1,t2) in x.keys():
|
||||
model.addConstraint(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
|
||||
tt =time.time()
|
||||
model.solve()
|
||||
comp_time = time.time()-tt
|
||||
|
||||
|
||||
if model.getProbStatus() != 6:
|
||||
# print("INFEASIBLE FOUND")
|
||||
return False, comp_time
|
||||
else:
|
||||
return True, comp_time
|
||||
|
||||
|
||||
|
||||
|
||||
# model = xp.problem(name='Draws', sense=xp.minimize)
|
||||
# model.setControl ('outputlog', 0)
|
||||
|
||||
# x = {}
|
||||
# for t1 in teams:
|
||||
# for t2 in teams:
|
||||
# if t1['country'] != t2['country']:
|
||||
# x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer)
|
||||
|
||||
# model.addVariable(x)
|
||||
|
||||
# # REQUIREMENTS
|
||||
# for t in teams:
|
||||
# for r in range(1,5):
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1)
|
||||
# model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1)
|
||||
# for c in countries:
|
||||
# if c != t['country']:
|
||||
# model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2)
|
||||
|
||||
# for (t1,t2) in x.keys():
|
||||
# model.addConstraint(x[t1,t2] + x[t2,t1] <= 1)
|
||||
|
||||
def check_feasible_fix(fixed_games):
|
||||
# FIXATIONS
|
||||
# for key in x.keys():
|
||||
# if key in fixed_games:
|
||||
# # x[key].lb = 1
|
||||
# model.chgbounds([x[key]],['L'],[1])
|
||||
# else:
|
||||
# # x[key].lb = 0
|
||||
# model.chgbounds([x[key]],['L'],[0])
|
||||
|
||||
reset_bounds = [key for key in x.keys() if key not in fixed_games]
|
||||
|
||||
model.chgbounds([x[key] for key in fixed_games],['L' for _ in range(len(fixed_games))],[1 for _ in range(len(fixed_games))])
|
||||
model.chgbounds([x[key] for key in reset_bounds],['L' for _ in range(len(reset_bounds))],[0 for _ in range(len(reset_bounds))])
|
||||
|
||||
tt =time.time()
|
||||
model.solve()
|
||||
comp_time = time.time()-tt
|
||||
|
||||
if model.getProbStatus() != 6:
|
||||
# print("INFEASIBLE FOUND")
|
||||
return False, comp_time
|
||||
return False
|
||||
else:
|
||||
return True, comp_time
|
||||
return True
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
import itertools
|
||||
from itertools import permutations , product
|
||||
|
||||
def simulate_draws(filename,n):
|
||||
|
||||
print("RUNNING ASYNC",filename)
|
||||
fixed_games=None
|
||||
for i_sim in range(1, n):
|
||||
if i_sim % 100 == 0:
|
||||
print("RUNNING ASYNC",filename,i_sim)
|
||||
# start_time = time.time()
|
||||
# n_computations = 0
|
||||
# check_time = 0
|
||||
# total_comp_time = 0
|
||||
|
||||
|
||||
possible_opps = {}
|
||||
for pos in range(8):
|
||||
p = pos//2+1
|
||||
teams_from_pot = list(teamObjects.filter(pot=p).values('id','country'))
|
||||
possible_opps[pos] = {
|
||||
t['id']: [t2['id'] for t2 in teams_from_pot if t2['country'] != t['country']] for t in teams
|
||||
}
|
||||
|
||||
sol_opps = {
|
||||
(t['id'],p):None
|
||||
for t in teams for p in range(8)
|
||||
}
|
||||
|
||||
sol_countries = {
|
||||
(t['id'],c):0
|
||||
for t in teams for c in countries if c != t['country']
|
||||
}
|
||||
|
||||
fixed_games = []
|
||||
feasible = True
|
||||
|
||||
for p in range(1,2):
|
||||
currentPot = list(teamObjects.filter(pot=p).values_list('id', flat=True))
|
||||
|
||||
while(feasible and currentPot):
|
||||
new_team = currentPot.pop(random.randint(0,len(currentPot)-1))
|
||||
for current_pos in range(0,8,2):
|
||||
if sol_opps[new_team,current_pos] != None and sol_opps[new_team,current_pos+1] != None:
|
||||
continue
|
||||
|
||||
|
||||
possible_opps[current_pos][new_team] = [t for t in possible_opps[current_pos][new_team] if sol_countries[new_team,getCountryById[t]] < 2 and sol_countries[t,getCountryById[new_team]] < 2]
|
||||
possible_opps[current_pos+1][new_team] = [t for t in possible_opps[current_pos+1][new_team] if sol_countries[new_team,getCountryById[t]] < 2 and sol_countries[t,getCountryById[new_team]] < 2]
|
||||
|
||||
list_1 = [None]
|
||||
list_2 = [None]
|
||||
if sol_opps[new_team,current_pos] == None:
|
||||
list_1 = possible_opps[current_pos][new_team]
|
||||
if sol_opps[new_team,current_pos+1] == None:
|
||||
list_2 = possible_opps[current_pos+1][new_team]
|
||||
|
||||
# unique_combinations = []
|
||||
# for i in range(len(list_1)):
|
||||
# for j in range(len(list_2)):
|
||||
# unique_combinations.append((list_1[i], list_2[j]))
|
||||
unique_combinations = list(itertools.product(list_1, list_2))
|
||||
random.shuffle(unique_combinations)
|
||||
|
||||
|
||||
no_solution_found = True
|
||||
while (no_solution_found):
|
||||
new_games = []
|
||||
# if sol_opps[new_team,current_pos] == None:
|
||||
# new_opponent1 = random.choice(possible_opps[current_pos][new_team])
|
||||
# new_games.append((new_team,new_opponent1))
|
||||
|
||||
# if sol_opps[new_team,current_pos+1] == None:
|
||||
# new_opponent2 = random.choice(possible_opps[current_pos+1][new_team])
|
||||
# new_games.append((new_opponent2,new_team))
|
||||
|
||||
new_opponent1,new_opponent2 = unique_combinations.pop()
|
||||
|
||||
if new_opponent1:
|
||||
new_games.append((new_team,new_opponent1))
|
||||
|
||||
if new_opponent2:
|
||||
new_games.append((new_opponent2,new_team))
|
||||
|
||||
# n_computations += 1
|
||||
# tt = time.time()
|
||||
check, comp_time = check_feasible_gurobi(fixed_games+new_games)
|
||||
# check_time += time.time()-tt
|
||||
# total_comp_time += comp_time
|
||||
if check:
|
||||
no_solution_found = False
|
||||
if sol_opps[new_team,current_pos] == None:
|
||||
sol_opps[new_team,current_pos] = new_opponent1
|
||||
sol_countries[new_team,getCountryById[new_opponent1]] += 1
|
||||
sol_opps[new_opponent1,(2*p-1)] = new_team
|
||||
sol_countries[new_opponent1,getCountryById[new_team]] += 1
|
||||
|
||||
if new_team in possible_opps[(2*p-1)-1][new_opponent1]:
|
||||
possible_opps[(2*p-1)-1][new_opponent1].remove(new_team)
|
||||
if sol_opps[new_team,current_pos+1] == None:
|
||||
sol_opps[new_team,current_pos+1] = new_opponent2
|
||||
sol_countries[new_team,getCountryById[new_opponent2]] += 1
|
||||
sol_opps[new_opponent2,(2*p-1)-(1)] = new_team
|
||||
sol_countries[new_opponent2,getCountryById[new_team]] += 1
|
||||
if new_team in possible_opps[(2*p-1)][new_opponent2]:
|
||||
possible_opps[(2*p-1)][new_opponent2].remove(new_team)
|
||||
fixed_games += new_games
|
||||
|
||||
|
||||
for p in range(2,5):
|
||||
currentPot = list(teamObjects.filter(pot=p).values_list('id', flat=True))
|
||||
|
||||
|
||||
while(feasible and currentPot):
|
||||
new_team = currentPot.pop(random.randint(0,len(currentPot)-1))
|
||||
|
||||
|
||||
unique_combinations = {}
|
||||
for current_pos in range(2*(p-1),8,2):
|
||||
|
||||
possible_opps[current_pos][new_team] = [t for t in possible_opps[current_pos][new_team] if sol_countries[new_team,getCountryById[t]] < 2 and
|
||||
sol_countries[t,getCountryById[new_team]] < 2 and sol_opps[t,(2*p-1)] == None]
|
||||
possible_opps[current_pos+1][new_team] = [t for t in possible_opps[current_pos+1][new_team] if sol_countries[new_team,getCountryById[t]] < 2 and
|
||||
sol_countries[t,getCountryById[new_team]] < 2 and sol_opps[t,(2*p-1)-1] == None]
|
||||
|
||||
list_1 = [0]
|
||||
list_2 = [0]
|
||||
if sol_opps[new_team,current_pos] == None:
|
||||
list_1 = possible_opps[current_pos][new_team]
|
||||
if sol_opps[new_team,current_pos+1] == None:
|
||||
list_2 = possible_opps[current_pos+1][new_team]
|
||||
|
||||
unique_combinations[current_pos] = []
|
||||
for i in list_1:
|
||||
for j in list_2:
|
||||
if i != j or (i == 0 and j == 0):
|
||||
unique_combinations[current_pos].append((i, j))
|
||||
|
||||
combi_list = list(itertools.product(*unique_combinations.values()))
|
||||
random.shuffle(combi_list)
|
||||
|
||||
|
||||
|
||||
|
||||
# print("STOP")
|
||||
# for current_pos in range(2*(p-1),8,2):
|
||||
# print(current_pos,possible_opps[current_pos][new_team])
|
||||
# print(current_pos+1,possible_opps[current_pos+1][new_team])
|
||||
# list_1 = [0]
|
||||
# list_2 = [0]
|
||||
# if sol_opps[new_team,current_pos] == None:
|
||||
# list_1 = possible_opps[current_pos][new_team]
|
||||
# if sol_opps[new_team,current_pos+1] == None:
|
||||
# list_2 = possible_opps[current_pos+1][new_team]
|
||||
|
||||
# unique_combinations[current_pos] = []
|
||||
# for i in list_1:
|
||||
# for j in list_2:
|
||||
# if i != j or (i == 0 and j == 0):
|
||||
# unique_combinations[current_pos].append((i, j))
|
||||
# print(unique_combinations)
|
||||
# exit()
|
||||
|
||||
|
||||
no_solution_found = True
|
||||
while (no_solution_found):
|
||||
# print("\tPOP",len(combi_list))
|
||||
new_games = []
|
||||
new_opponents = combi_list.pop()
|
||||
for o1,o2 in new_opponents:
|
||||
if o1:
|
||||
new_games.append((new_team,o1))
|
||||
if o2:
|
||||
new_games.append((o2,new_team))
|
||||
|
||||
|
||||
# n_computations += 1
|
||||
# tt = time.time()
|
||||
check, comp_time = check_feasible_gurobi(fixed_games+new_games)
|
||||
# check_time += time.time()-tt
|
||||
# total_comp_time += comp_time
|
||||
if check:
|
||||
no_solution_found = False
|
||||
fixed_games += new_games
|
||||
for i,(new_opponent1,new_opponent2) in enumerate(new_opponents):
|
||||
current_pos = 2*(p-1)+2*i
|
||||
if sol_opps[new_team,current_pos] == None:
|
||||
sol_opps[new_team,current_pos] = new_opponent1
|
||||
sol_countries[new_team,getCountryById[new_opponent1]] += 1
|
||||
sol_opps[new_opponent1 ,(2*p-1)] = new_team
|
||||
sol_countries[new_opponent1,getCountryById[new_team]] += 1
|
||||
if new_team in possible_opps[(2*p-1)-1][new_opponent1]:
|
||||
possible_opps[(2*p-1)-1][new_opponent1].remove(new_team)
|
||||
if sol_opps[new_team,current_pos+1] == None:
|
||||
sol_opps[new_team,current_pos+1] = new_opponent2
|
||||
sol_countries[new_team,getCountryById[new_opponent2]] += 1
|
||||
sol_opps[new_opponent2,(2*p-1)-(1)] = new_team
|
||||
sol_countries[new_opponent2,getCountryById[new_team]] += 1
|
||||
if new_team in possible_opps[(2*p-1)][new_opponent2]:
|
||||
possible_opps[(2*p-1)][new_opponent2].remove(new_team)
|
||||
|
||||
# print("COMPUTATIONS",n_computations)
|
||||
# print("TIME\t",time.time()-start_time)
|
||||
# print("CHECK\t",check_time)
|
||||
# print("COMP\t",total_comp_time)
|
||||
|
||||
|
||||
|
||||
with open(filename+'.csv', "a") as f:
|
||||
for t in teams:
|
||||
f.write(f"{i_sim},{t['id']},{';'.join([str(sol_opps[t['id'],p]) for p in range(8)])}\n")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# # WRITE SOL '.html'
|
||||
# sol = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
|
||||
# sol += " \
|
||||
# <style> \
|
||||
# table, th, td { \
|
||||
# border: 1px solid black; \
|
||||
# border-collapse: collapse; \
|
||||
# text-align: center; \
|
||||
# min-width:40px; \
|
||||
# padding:3px; \
|
||||
# margin: 3px; \
|
||||
# font-family : Arial;\
|
||||
# } \
|
||||
# h1 {\
|
||||
# font-family : Arial;\
|
||||
# }\
|
||||
# \
|
||||
# #etable td:nth-child(10),#etable th:nth-child(10) { border-right: 5px solid black; }\
|
||||
# #etable td:nth-child(19),#etable th:nth-child(19) { border-right: 5px solid black; }\
|
||||
# #etable td:nth-child(28),#etable th:nth-child(28) { border-right: 5px solid black; }\
|
||||
# tr:nth-child(9) { border-bottom: 5px solid black; }\
|
||||
# tr:nth-child(18) { border-bottom: 5px solid black; }\
|
||||
# tr:nth-child(27) { border-bottom: 5px solid black; }\
|
||||
# </style> \
|
||||
# "
|
||||
# sol += "<table id='etable' style='border:5px solid black'>\n"
|
||||
# sol += "<thead>\n"
|
||||
# sol += "<tr>"
|
||||
# sol += "<th></th>"
|
||||
# sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot A</th>"
|
||||
# sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot B</th>"
|
||||
# sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot C</th>"
|
||||
# sol += "<th colspan=9>Pot D</th>"
|
||||
# sol += "</tr>"
|
||||
# sol += "<tr>\n"
|
||||
# sol += f"<th></th>\n"
|
||||
# for t in teams:
|
||||
# sol += f"<th>{getTeamById[t['id']]}</th>\n"
|
||||
# sol += "</tr>\n"
|
||||
# sol += "</thead>\n"
|
||||
# sol += "<tbody>\n"
|
||||
# for t1 in teams:
|
||||
# sol += "<tr>\n"
|
||||
# sol += f"<td>{getTeamById[t1['id']]}</td>"
|
||||
# for t2 in teams:
|
||||
# if (t1['id'],t2['id']) in fixed_games:
|
||||
# sol += f"<td>{t2['country']}</td>"
|
||||
# elif (t2['id'],t1['id']) in fixed_games:
|
||||
# sol += f"<td>@{t2['country']}</td>"
|
||||
# else:
|
||||
# sol += f"<td></td>"
|
||||
# sol += "</tr>\n"
|
||||
# sol += "</tbody>\n"
|
||||
# sol += "</table>\n"
|
||||
|
||||
# with open(f'debug.html', 'w') as f:
|
||||
# f.write(sol)
|
||||
|
||||
|
||||
n = sys.maxsize
|
||||
|
||||
pool = Pool()
|
||||
result = {}
|
||||
answer = {}
|
||||
n_threads = cpu_count()
|
||||
# n_threads = 1
|
||||
|
||||
for cpu in range(n_threads):
|
||||
result[cpu] = pool.apply_async(simulate_draws, args=(f'thread_{cpu}_pot_by_pot', n,))
|
||||
|
||||
for cpu in range(n_threads):
|
||||
answer[cpu] = result[cpu].get()
|
||||
|
||||
|
||||
# %%
|
||||
# n = 2
|
||||
# simulate_draws('test', n)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
316
uefa/cycle24/simulations/mixed_draws/probabilities_october.py
Executable file
316
uefa/cycle24/simulations/mixed_draws/probabilities_october.py
Executable file
@ -0,0 +1,316 @@
|
||||
# %%
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
||||
scenario = Scenario.objects.get(id=34)
|
||||
|
||||
# %%
|
||||
|
||||
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
|
||||
}
|
||||
random_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_undirected = 0
|
||||
simulations_directed = 0
|
||||
maxVal = 1
|
||||
minVal = 99999999
|
||||
maxCVal = 1
|
||||
minCVal = 9999999
|
||||
maxRVal = 1
|
||||
minRVal = 9999999
|
||||
maxCRVal = 1
|
||||
minCRVal = 9999999
|
||||
|
||||
old_c = "START"
|
||||
for i in range(16):
|
||||
with open(f'thread_{i}_pot_by_pot.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_undirected +=1
|
||||
|
||||
team = getTeamByID[int(row[1])]
|
||||
Aopps = [getTeamByID[int(t)] for t in row[2].split(";")][:2]
|
||||
for o in Aopps:
|
||||
stats[team,o] += 1
|
||||
pots[team][getPotByID[o.id]] += 1
|
||||
played_countries[team,o.country] += 1
|
||||
Bopps = [getTeamByID[int(t)] for t in row[2].split(";")][2:4]
|
||||
for o in Bopps:
|
||||
stats[team,o] += 1
|
||||
pots[team][getPotByID[o.id]] += 1
|
||||
played_countries[team,o.country] += 1
|
||||
Copps = [getTeamByID[int(t)] for t in row[2].split(";")][4:6]
|
||||
for o in Copps:
|
||||
stats[team,o] += 1
|
||||
pots[team][getPotByID[o.id]] += 1
|
||||
played_countries[team,o.country] += 1
|
||||
Dopps = [getTeamByID[int(t)] for t in row[2].split(";")][6:]
|
||||
for o in Dopps:
|
||||
stats[team,o] += 1
|
||||
pots[team][getPotByID[o.id]] += 1
|
||||
played_countries[team,o.country] += 1
|
||||
|
||||
if stats[team,o] > maxVal:
|
||||
maxVal = stats[team,o]
|
||||
|
||||
if played_countries[team,o.country] > maxCVal:
|
||||
maxCVal = played_countries[team,o.country]
|
||||
|
||||
|
||||
diff = {}
|
||||
mindval = 999999
|
||||
maxdval = 0
|
||||
# simulations_undirected = 1
|
||||
simulations_directed = 1
|
||||
|
||||
for key in random_stats.keys():
|
||||
diff[key] = stats[key]/simulations_undirected - 2*random_stats[key]/simulations_directed
|
||||
if diff[key] > maxdval:
|
||||
maxdval = diff[key]
|
||||
if diff[key] > 0 and diff[key] < mindval:
|
||||
mindval = diff[key]
|
||||
|
||||
|
||||
|
||||
for key, val in stats.items():
|
||||
if val > 0 and val < minVal:
|
||||
minVal = val
|
||||
|
||||
|
||||
for key, val in random_stats.items():
|
||||
if val > 0 and val < minRVal:
|
||||
minRVal = val
|
||||
|
||||
|
||||
for key, val in played_countries.items():
|
||||
if val > 0 and val < minCVal:
|
||||
minCVal = val
|
||||
|
||||
|
||||
for key, val in random_played_countries.items():
|
||||
if val > 0 and val < minCRVal:
|
||||
minCRVal = 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 = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
|
||||
sol += " \
|
||||
<style> \
|
||||
table, th, td { \
|
||||
border: 1px solid black; \
|
||||
border-collapse: collapse; \
|
||||
text-align: center; \
|
||||
min-width:40px; \
|
||||
padding:3px; \
|
||||
margin: 3px; \
|
||||
font-family : Arial;\
|
||||
} \
|
||||
h1 {\
|
||||
font-family : Arial;\
|
||||
}\
|
||||
\
|
||||
#etable td:nth-child(10),#etable th:nth-child(10) { border-right: 5px solid black; }\
|
||||
#etable td:nth-child(19),#etable th:nth-child(19) { border-right: 5px solid black; }\
|
||||
#etable td:nth-child(28),#etable th:nth-child(28) { border-right: 5px solid black; }\
|
||||
tr:nth-child(9) { border-bottom: 5px solid black; }\
|
||||
tr:nth-child(18) { border-bottom: 5px solid black; }\
|
||||
tr:nth-child(27) { border-bottom: 5px solid black; }\
|
||||
</style> \
|
||||
"
|
||||
sol += "</head><body>"
|
||||
sol += "<h2>Probabilities of games - drawn simultaneously</h2>"
|
||||
sol += "<table id='etable' style='border:5px solid black'>\n"
|
||||
sol += "<thead>\n"
|
||||
sol += "<tr>"
|
||||
sol += f"<th>{simulations_undirected}</th>"
|
||||
sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot A</th>"
|
||||
sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot B</th>"
|
||||
sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot C</th>"
|
||||
sol += "<th colspan=9>Pot D</th>"
|
||||
sol += "</tr>"
|
||||
sol += "<tr>\n"
|
||||
sol += f"<th></th>\n"
|
||||
# for o in order:
|
||||
for t in teams:
|
||||
# t = getTeamByName[o]
|
||||
sol += f"<th>({t.country}) {t.shortname}</th>\n"
|
||||
sol += "</tr>\n"
|
||||
sol += "</thead>\n"
|
||||
sol += "<tbody>\n"
|
||||
# for o1 in order:
|
||||
for t1 in teams:
|
||||
# t1 = getTeamByName[o1]
|
||||
sol += "<tr>\n"
|
||||
sol += f"<td>({t1.country}) {t1.shortname}</td>"
|
||||
# for o2 in order:
|
||||
for t2 in teams:
|
||||
# t2 = getTeamByName[o2]
|
||||
color = heatmap_color_for((stats[t1,t2]-minVal)/((maxVal-minVal) or 1))
|
||||
if stats[t1,t2] == 0:
|
||||
color = 'grey'
|
||||
val = f"{round((stats[t1,t2]/simulations_undirected)*100)}%"
|
||||
# val = stats[t1,t2]
|
||||
sol += f"<td style='background-color:{color}'>{val}</td>"
|
||||
sol += "</tr>\n"
|
||||
|
||||
sol += "</tbody>\n"
|
||||
sol += "</table>\n"
|
||||
|
||||
|
||||
with open(f'probabilities_simultaneously.html', 'w') as f:
|
||||
f.write(sol)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# %%
|
||||
559
uefa/cycle24/simulations/probabilities_october.py
Executable file
559
uefa/cycle24/simulations/probabilities_october.py
Executable file
@ -0,0 +1,559 @@
|
||||
# %%
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
||||
scenario = Scenario.objects.get(id=34)
|
||||
|
||||
# %%
|
||||
|
||||
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
|
||||
}
|
||||
random_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_undirected = 0
|
||||
simulations_directed = 0
|
||||
maxVal = 1
|
||||
minVal = 99999999
|
||||
maxCVal = 1
|
||||
minCVal = 9999999
|
||||
maxRVal = 1
|
||||
minRVal = 9999999
|
||||
maxCRVal = 1
|
||||
minCRVal = 9999999
|
||||
|
||||
old_c = "START"
|
||||
for i in range(16):
|
||||
with open(f'thread_{i}_pot_by_pot.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_undirected +=1
|
||||
|
||||
team = getTeamByID[int(row[1])]
|
||||
Aopps = [getTeamByID[int(t)] for t in row[2].split(";")][:2]
|
||||
for o in Aopps:
|
||||
stats[team,o] += 1
|
||||
pots[team][getPotByID[o.id]] += 1
|
||||
played_countries[team,o.country] += 1
|
||||
Bopps = [getTeamByID[int(t)] for t in row[2].split(";")][2:4]
|
||||
for o in Bopps:
|
||||
stats[team,o] += 1
|
||||
pots[team][getPotByID[o.id]] += 1
|
||||
played_countries[team,o.country] += 1
|
||||
Copps = [getTeamByID[int(t)] for t in row[2].split(";")][4:6]
|
||||
for o in Copps:
|
||||
stats[team,o] += 1
|
||||
pots[team][getPotByID[o.id]] += 1
|
||||
played_countries[team,o.country] += 1
|
||||
Dopps = [getTeamByID[int(t)] for t in row[2].split(";")][6:]
|
||||
for o in Dopps:
|
||||
stats[team,o] += 1
|
||||
pots[team][getPotByID[o.id]] += 1
|
||||
played_countries[team,o.country] += 1
|
||||
|
||||
if stats[team,o] > maxVal:
|
||||
maxVal = stats[team,o]
|
||||
|
||||
if played_countries[team,o.country] > maxCVal:
|
||||
maxCVal = played_countries[team,o.country]
|
||||
|
||||
# with open(f'test.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_undirected +=1
|
||||
|
||||
# team = getTeamByID[int(row[1])]
|
||||
# Aopps = [getTeamByID[int(t)] for t in row[2].split(";")][:2]
|
||||
# for o in Aopps:
|
||||
# stats[team,o] += 1
|
||||
# pots[team][getPotByID[o.id]] += 1
|
||||
# played_countries[team,o.country] += 1
|
||||
# Bopps = [getTeamByID[int(t)] for t in row[2].split(";")][2:4]
|
||||
# for o in Bopps:
|
||||
# stats[team,o] += 1
|
||||
# pots[team][getPotByID[o.id]] += 1
|
||||
# played_countries[team,o.country] += 1
|
||||
# Copps = [getTeamByID[int(t)] for t in row[2].split(";")][4:6]
|
||||
# for o in Copps:
|
||||
# stats[team,o] += 1
|
||||
# pots[team][getPotByID[o.id]] += 1
|
||||
# played_countries[team,o.country] += 1
|
||||
# Dopps = [getTeamByID[int(t)] for t in row[2].split(";")][6:]
|
||||
# for o in Dopps:
|
||||
# stats[team,o] += 1
|
||||
# pots[team][getPotByID[o.id]] += 1
|
||||
# played_countries[team,o.country] += 1
|
||||
|
||||
# if stats[team,o] > maxVal:
|
||||
# maxVal = stats[team,o]
|
||||
|
||||
# if played_countries[team,o.country] > maxCVal:
|
||||
# maxCVal = played_countries[team,o.country]
|
||||
|
||||
# %%
|
||||
|
||||
|
||||
|
||||
|
||||
# old_c = "START"
|
||||
|
||||
# # with open('verteilung_draw.csv', newline='') as csvfile:
|
||||
# with open('draw_options_HA_2country.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_directed +=1
|
||||
|
||||
|
||||
# team = getTeamByID[int(row[1])]
|
||||
# Aopps = [getTeamByID[int(t)] for t in row[2].split(";")][:1]
|
||||
# for o in Aopps:
|
||||
# random_stats[team,o] += 1
|
||||
# # pots[team][getPotByID[o.id]] += 1
|
||||
# random_played_countries[team,o.country] += 1
|
||||
# Bopps = [getTeamByID[int(t)] for t in row[2].split(";")][2:3]
|
||||
# for o in Bopps:
|
||||
# random_stats[team,o] += 1
|
||||
# # pots[team][getPotByID[o.id]] += 1
|
||||
# random_played_countries[team,o.country] += 1
|
||||
# Copps = [getTeamByID[int(t)] for t in row[2].split(";")][4:5]
|
||||
# for o in Copps:
|
||||
# random_stats[team,o] += 1
|
||||
# # pots[team][getPotByID[o.id]] += 1
|
||||
# random_played_countries[team,o.country] += 1
|
||||
# Dopps = [getTeamByID[int(t)] for t in row[2].split(";")][6:7]
|
||||
# for o in Dopps:
|
||||
# random_stats[team,o] += 1
|
||||
# # pots[team][getPotByID[o.id]] += 1
|
||||
# random_played_countries[team,o.country] += 1
|
||||
|
||||
# if random_stats[team,o] > maxRVal:
|
||||
# maxRVal = random_stats[team,o]
|
||||
|
||||
|
||||
# if random_played_countries[team,o.country] > maxCRVal:
|
||||
# maxCRVal = random_played_countries[team,o.country]
|
||||
|
||||
|
||||
diff = {}
|
||||
mindval = 999999
|
||||
maxdval = 0
|
||||
# simulations_undirected = 1
|
||||
simulations_directed = 1
|
||||
|
||||
for key in random_stats.keys():
|
||||
diff[key] = stats[key]/simulations_undirected - 2*random_stats[key]/simulations_directed
|
||||
if diff[key] > maxdval:
|
||||
maxdval = diff[key]
|
||||
if diff[key] > 0 and diff[key] < mindval:
|
||||
mindval = diff[key]
|
||||
|
||||
|
||||
|
||||
for key, val in stats.items():
|
||||
if val > 0 and val < minVal:
|
||||
minVal = val
|
||||
|
||||
|
||||
for key, val in random_stats.items():
|
||||
if val > 0 and val < minRVal:
|
||||
minRVal = val
|
||||
|
||||
|
||||
for key, val in played_countries.items():
|
||||
if val > 0 and val < minCVal:
|
||||
minCVal = val
|
||||
|
||||
|
||||
for key, val in random_played_countries.items():
|
||||
if val > 0 and val < minCRVal:
|
||||
minCRVal = 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 = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
|
||||
sol += " \
|
||||
<style> \
|
||||
table, th, td { \
|
||||
border: 1px solid black; \
|
||||
border-collapse: collapse; \
|
||||
text-align: center; \
|
||||
min-width:40px; \
|
||||
padding:3px; \
|
||||
margin: 3px; \
|
||||
font-family : Arial;\
|
||||
} \
|
||||
h1 {\
|
||||
font-family : Arial;\
|
||||
}\
|
||||
\
|
||||
#etable td:nth-child(10),#etable th:nth-child(10) { border-right: 5px solid black; }\
|
||||
#etable td:nth-child(19),#etable th:nth-child(19) { border-right: 5px solid black; }\
|
||||
#etable td:nth-child(28),#etable th:nth-child(28) { border-right: 5px solid black; }\
|
||||
tr:nth-child(9) { border-bottom: 5px solid black; }\
|
||||
tr:nth-child(18) { border-bottom: 5px solid black; }\
|
||||
tr:nth-child(27) { border-bottom: 5px solid black; }\
|
||||
</style> \
|
||||
"
|
||||
sol += "</head><body>"
|
||||
sol += "<h1>Probabilities of games - undirected vs directed</h1>"
|
||||
sol += "<ul><li>Table 1: Probability of two teams to be drawn against each other (symmetric)</li>"
|
||||
sol += "<li>Table 2: Probability of a home or away encounter (asymmetric)</li>"
|
||||
sol += "<li>Table 3: Difference of the two options from above. Moving from undirected to directed</li></ul>"
|
||||
sol += "Each options data is based on approximately 5000 random draws. Both options are restricted to at most 2 opponents from the same country."
|
||||
sol += "<hr>"
|
||||
sol += "<h2>Table 1: Probabilities of games - undirected</h2>"
|
||||
sol += "Home/Away games are assigned in the calendar phase, therefore this table is symmetric."
|
||||
sol += "<table id='etable' style='border:5px solid black'>\n"
|
||||
sol += "<thead>\n"
|
||||
sol += "<tr>"
|
||||
sol += f"<th>{simulations_undirected}</th>"
|
||||
sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot A</th>"
|
||||
sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot B</th>"
|
||||
sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot C</th>"
|
||||
sol += "<th colspan=9>Pot D</th>"
|
||||
sol += "</tr>"
|
||||
sol += "<tr>\n"
|
||||
sol += f"<th></th>\n"
|
||||
# for o in order:
|
||||
for t in teams:
|
||||
# t = getTeamByName[o]
|
||||
sol += f"<th>({t.country}) {t.shortname}</th>\n"
|
||||
sol += "</tr>\n"
|
||||
sol += "</thead>\n"
|
||||
sol += "<tbody>\n"
|
||||
# for o1 in order:
|
||||
for t1 in teams:
|
||||
# t1 = getTeamByName[o1]
|
||||
sol += "<tr>\n"
|
||||
sol += f"<td>({t1.country}) {t1.shortname}</td>"
|
||||
# for o2 in order:
|
||||
for t2 in teams:
|
||||
# t2 = getTeamByName[o2]
|
||||
color = heatmap_color_for((stats[t1,t2]-minVal)/((maxVal-minVal) or 1))
|
||||
if stats[t1,t2] == 0:
|
||||
color = 'grey'
|
||||
val = f"{round(round(stats[t1,t2]/simulations_undirected,2)*100)}%"
|
||||
# val = stats[t1,t2]
|
||||
sol += f"<td style='background-color:{color}'>{val}</td>"
|
||||
sol += "</tr>\n"
|
||||
|
||||
sol += "</tbody>\n"
|
||||
sol += "</table>\n"
|
||||
|
||||
sol += "<br>"
|
||||
sol += "<br>"
|
||||
sol += "<br>"
|
||||
sol += "<hr>"
|
||||
|
||||
sol += "<h2>Table 2: Probabilities of games - directed</h2>"
|
||||
sol += "Home/Away games are assigned during the draw, therefore this table is asymmetric."
|
||||
sol += "<table id='etable' style='border:5px solid black'>\n"
|
||||
sol += "<thead>\n"
|
||||
sol += "<tr>"
|
||||
sol += "<th></th>"
|
||||
sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot A</th>"
|
||||
sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot B</th>"
|
||||
sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot C</th>"
|
||||
sol += "<th colspan=9>Pot D</th>"
|
||||
sol += "</tr>"
|
||||
sol += "<tr>\n"
|
||||
sol += f"<th></th>\n"
|
||||
# for o in order:
|
||||
for t in teams:
|
||||
# t = getTeamByName[o]
|
||||
sol += f"<th>({t.country}) {t.shortname}</th>\n"
|
||||
sol += "</tr>\n"
|
||||
sol += "</thead>\n"
|
||||
sol += "<tbody>\n"
|
||||
# for o1 in order:
|
||||
for t1 in teams:
|
||||
# t1 = getTeamByName[o1]
|
||||
sol += "<tr>\n"
|
||||
sol += f"<td>({t1.country}) {t1.shortname}</td>"
|
||||
# for o2 in order:
|
||||
for t2 in teams:
|
||||
# t2 = getTeamByName[o2]
|
||||
color = heatmap_color_for((random_stats[t1,t2]-minRVal)/((maxRVal-minRVal) or 1))
|
||||
if random_stats[t1,t2] == 0:
|
||||
color = 'grey'
|
||||
val = f"{round(round(random_stats[t1,t2]/simulations_directed,2)*100)}%"
|
||||
# val = stats[t1,t2]
|
||||
sol += f"<td style='background-color:{color}'>{val}</td>"
|
||||
sol += "</tr>\n"
|
||||
|
||||
sol += "</tbody>\n"
|
||||
sol += "</table>\n"
|
||||
|
||||
|
||||
sol += "<br>"
|
||||
sol += "<br>"
|
||||
sol += "<br>"
|
||||
sol += "<hr>"
|
||||
|
||||
sol += "<h2>Table 3: Difference of probabilities (moving from undirected to directed)</h2>"
|
||||
sol += "<table style='border:5px solid black'>\n"
|
||||
sol += "<thead>\n"
|
||||
sol += "<tr>\n"
|
||||
sol += f"<th></th>\n"
|
||||
# for o in order:
|
||||
for t in teams:
|
||||
# t = getTeamByName[o]
|
||||
sol += f"<th>({t.country}) {t.shortname}</th>\n"
|
||||
sol += "</tr>\n"
|
||||
sol += "</thead>\n"
|
||||
sol += "<tbody>\n"
|
||||
# for o1 in order:
|
||||
for t1 in teams:
|
||||
# t1 = getTeamByName[o1]
|
||||
sol += "<tr>\n"
|
||||
sol += f"<td>({t1.country}) {t1.shortname}</td>"
|
||||
# for o2 in order:
|
||||
for t2 in teams:
|
||||
# t2 = getTeamByName[o2]
|
||||
color = heatmap_color_for((abs(diff[t1,t2])-mindval)/((maxdval-mindval) or 1))
|
||||
if stats[t1,t2] == 0:
|
||||
color = 'grey'
|
||||
val = f"{diff[t1,t2]}%"
|
||||
# val = stats[t1,t2]
|
||||
sol += f"<td style='background-color:{color}'>{round(round(diff[t1,t2],2)*100)}%</td>"
|
||||
sol += "</tr>\n"
|
||||
|
||||
sol += "</tbody>\n"
|
||||
sol += "</table>\n"
|
||||
|
||||
# sol += "<br>"
|
||||
# sol += "<br>"
|
||||
# sol += "<br>"
|
||||
# sol += "<hr>"
|
||||
|
||||
# sol += "<h2>Average number of games against other countries - undirected</h2>"
|
||||
# sol += "<table style='border:5px solid black'>\n"
|
||||
# sol += "<thead>\n"
|
||||
# sol += "<tr>"
|
||||
# sol += "<tr>\n"
|
||||
# sol += f"<th></th>\n"
|
||||
# for c in countries:
|
||||
# sol += f"<th>{c}</th>\n"
|
||||
# sol += "</tr>\n"
|
||||
# sol += "</thead>\n"
|
||||
# sol += "<tbody>\n"
|
||||
# # for o1 in order:
|
||||
# for t1 in teams:
|
||||
# # t1 = getTeamByName[o1]
|
||||
# sol += "<tr>\n"
|
||||
# sol += f"<td>{t1.shortname}</td>"
|
||||
# for c in countries:
|
||||
# # color = heatmap_color_for((played_countries[t1,c]-minCVal)/(maxCVal-minCVal))
|
||||
# color = 'lightsteelblue'
|
||||
# if played_countries[t1,c] == 0:
|
||||
# color = 'grey'
|
||||
# # val = f"{round(round(played_played_countries[t1][c]/simulations,2)*100)}%"
|
||||
# val = f"{round(played_countries[t1,c]/(simulations_undirected),2)}"
|
||||
# # val = stats[t1,t2]
|
||||
# sol += f"<td style='background-color:{color}'>{val}</td>"
|
||||
# sol += "</tr>\n"
|
||||
|
||||
# sol += "</tbody>\n"
|
||||
# sol += "</table>\n"
|
||||
|
||||
|
||||
# sol += "<br>"
|
||||
# sol += "<br>"
|
||||
# sol += "<br>"
|
||||
# sol += "<hr>"
|
||||
|
||||
# sol += "<h2>Average number of games against other countries - directed</h2>"
|
||||
# sol += "<table style='border:5px solid black'>\n"
|
||||
# sol += "<thead>\n"
|
||||
# sol += "<tr>"
|
||||
# sol += "<tr>\n"
|
||||
# sol += f"<th></th>\n"
|
||||
# for c in countries:
|
||||
# sol += f"<th>{c}</th>\n"
|
||||
# sol += "</tr>\n"
|
||||
# sol += "</thead>\n"
|
||||
# sol += "<tbody>\n"
|
||||
# # for o1 in order:
|
||||
# for t1 in teams:
|
||||
# # t1 = getTeamByName[o1]
|
||||
# sol += "<tr>\n"
|
||||
# sol += f"<td>{t1.shortname}</td>"
|
||||
# for c in countries:
|
||||
# # color = heatmap_color_for((played_countries[t1,c]-minCVal)/(maxCVal-minCVal))
|
||||
# color = 'lightsteelblue'
|
||||
# if random_played_countries[t1,c] == 0:
|
||||
# color = 'grey'
|
||||
# # val = f"{round(round(played_played_countries[t1][c]/simulations,2)*100)}%"
|
||||
# val = f"{round(random_played_countries[t1,c]/(simulations_directed),2)}"
|
||||
# # val = stats[t1,t2]
|
||||
# sol += f"<td style='background-color:{color}'>{val}</td>"
|
||||
# sol += "</tr>\n"
|
||||
|
||||
sol += "</tbody>\n"
|
||||
sol += "</table>\n"
|
||||
|
||||
|
||||
|
||||
with open(f'probabilities.html', 'w') as f:
|
||||
f.write(sol)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# %%
|
||||
316
uefa/cycle24/simulations/single_draws/probabilities_october.py
Executable file
316
uefa/cycle24/simulations/single_draws/probabilities_october.py
Executable file
@ -0,0 +1,316 @@
|
||||
# %%
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
||||
scenario = Scenario.objects.get(id=34)
|
||||
|
||||
# %%
|
||||
|
||||
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
|
||||
}
|
||||
random_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_undirected = 0
|
||||
simulations_directed = 0
|
||||
maxVal = 1
|
||||
minVal = 99999999
|
||||
maxCVal = 1
|
||||
minCVal = 9999999
|
||||
maxRVal = 1
|
||||
minRVal = 9999999
|
||||
maxCRVal = 1
|
||||
minCRVal = 9999999
|
||||
|
||||
old_c = "START"
|
||||
for i in range(16):
|
||||
with open(f'thread_{i}_pot_by_pot.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_undirected +=1
|
||||
|
||||
team = getTeamByID[int(row[1])]
|
||||
Aopps = [getTeamByID[int(t)] for t in row[2].split(";")][:2]
|
||||
for o in Aopps:
|
||||
stats[team,o] += 1
|
||||
pots[team][getPotByID[o.id]] += 1
|
||||
played_countries[team,o.country] += 1
|
||||
Bopps = [getTeamByID[int(t)] for t in row[2].split(";")][2:4]
|
||||
for o in Bopps:
|
||||
stats[team,o] += 1
|
||||
pots[team][getPotByID[o.id]] += 1
|
||||
played_countries[team,o.country] += 1
|
||||
Copps = [getTeamByID[int(t)] for t in row[2].split(";")][4:6]
|
||||
for o in Copps:
|
||||
stats[team,o] += 1
|
||||
pots[team][getPotByID[o.id]] += 1
|
||||
played_countries[team,o.country] += 1
|
||||
Dopps = [getTeamByID[int(t)] for t in row[2].split(";")][6:]
|
||||
for o in Dopps:
|
||||
stats[team,o] += 1
|
||||
pots[team][getPotByID[o.id]] += 1
|
||||
played_countries[team,o.country] += 1
|
||||
|
||||
if stats[team,o] > maxVal:
|
||||
maxVal = stats[team,o]
|
||||
|
||||
if played_countries[team,o.country] > maxCVal:
|
||||
maxCVal = played_countries[team,o.country]
|
||||
|
||||
|
||||
diff = {}
|
||||
mindval = 999999
|
||||
maxdval = 0
|
||||
# simulations_undirected = 1
|
||||
simulations_directed = 1
|
||||
|
||||
for key in random_stats.keys():
|
||||
diff[key] = stats[key]/simulations_undirected - 2*random_stats[key]/simulations_directed
|
||||
if diff[key] > maxdval:
|
||||
maxdval = diff[key]
|
||||
if diff[key] > 0 and diff[key] < mindval:
|
||||
mindval = diff[key]
|
||||
|
||||
|
||||
|
||||
for key, val in stats.items():
|
||||
if val > 0 and val < minVal:
|
||||
minVal = val
|
||||
|
||||
|
||||
for key, val in random_stats.items():
|
||||
if val > 0 and val < minRVal:
|
||||
minRVal = val
|
||||
|
||||
|
||||
for key, val in played_countries.items():
|
||||
if val > 0 and val < minCVal:
|
||||
minCVal = val
|
||||
|
||||
|
||||
for key, val in random_played_countries.items():
|
||||
if val > 0 and val < minCRVal:
|
||||
minCRVal = 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 = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
|
||||
sol += " \
|
||||
<style> \
|
||||
table, th, td { \
|
||||
border: 1px solid black; \
|
||||
border-collapse: collapse; \
|
||||
text-align: center; \
|
||||
min-width:40px; \
|
||||
padding:3px; \
|
||||
margin: 3px; \
|
||||
font-family : Arial;\
|
||||
} \
|
||||
h1 {\
|
||||
font-family : Arial;\
|
||||
}\
|
||||
\
|
||||
#etable td:nth-child(10),#etable th:nth-child(10) { border-right: 5px solid black; }\
|
||||
#etable td:nth-child(19),#etable th:nth-child(19) { border-right: 5px solid black; }\
|
||||
#etable td:nth-child(28),#etable th:nth-child(28) { border-right: 5px solid black; }\
|
||||
tr:nth-child(9) { border-bottom: 5px solid black; }\
|
||||
tr:nth-child(18) { border-bottom: 5px solid black; }\
|
||||
tr:nth-child(27) { border-bottom: 5px solid black; }\
|
||||
</style> \
|
||||
"
|
||||
sol += "</head><body>"
|
||||
sol += "<h2>Probabilities of games - drawn team by team</h2>"
|
||||
sol += "<table id='etable' style='border:5px solid black'>\n"
|
||||
sol += "<thead>\n"
|
||||
sol += "<tr>"
|
||||
sol += f"<th>{simulations_undirected}</th>"
|
||||
sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot A</th>"
|
||||
sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot B</th>"
|
||||
sol += "<th colspan=9 style='border-right: 5px solid black;'>Pot C</th>"
|
||||
sol += "<th colspan=9>Pot D</th>"
|
||||
sol += "</tr>"
|
||||
sol += "<tr>\n"
|
||||
sol += f"<th></th>\n"
|
||||
# for o in order:
|
||||
for t in teams:
|
||||
# t = getTeamByName[o]
|
||||
sol += f"<th>({t.country}) {t.shortname}</th>\n"
|
||||
sol += "</tr>\n"
|
||||
sol += "</thead>\n"
|
||||
sol += "<tbody>\n"
|
||||
# for o1 in order:
|
||||
for t1 in teams:
|
||||
# t1 = getTeamByName[o1]
|
||||
sol += "<tr>\n"
|
||||
sol += f"<td>({t1.country}) {t1.shortname}</td>"
|
||||
# for o2 in order:
|
||||
for t2 in teams:
|
||||
# t2 = getTeamByName[o2]
|
||||
color = heatmap_color_for((stats[t1,t2]-minVal)/((maxVal-minVal) or 1))
|
||||
if stats[t1,t2] == 0:
|
||||
color = 'grey'
|
||||
val = f"{round((stats[t1,t2]/simulations_undirected)*100)}%"
|
||||
# val = stats[t1,t2]
|
||||
sol += f"<td style='background-color:{color}'>{val}</td>"
|
||||
sol += "</tr>\n"
|
||||
|
||||
sol += "</tbody>\n"
|
||||
sol += "</table>\n"
|
||||
|
||||
|
||||
with open(f'probabilities_team_by_team.html', 'w') as f:
|
||||
f.write(sol)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# %%
|
||||
@ -96,6 +96,8 @@ for scenario in season.scenarios.all():
|
||||
violated_blockings[b.team]['comments'][f"{b.type} - {b.day}"] += 1
|
||||
|
||||
|
||||
violated_blockings = dict(sorted(violated_blockings.items(), key=lambda x: x[1]['violations'], reverse=True))
|
||||
|
||||
violated_wishes = dict(sorted(violated_wishes.items(), key=lambda x: x[1]['violations'], reverse=True))
|
||||
|
||||
for key,val in violated_wishes.items():
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user