302 lines
13 KiB
Python
Executable File
302 lines
13 KiB
Python
Executable File
# %%
|
|
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 pulp
|
|
from pulp import lpSum, value, XPRESS, GUROBI, PULP_CBC_CMD
|
|
from django.db.models import Q
|
|
from django.template.loader import render_to_string
|
|
|
|
from qualifiers.models import *
|
|
from common.models import GlobalTeam, GlobalCountry
|
|
from common.functions import getRandomHexColor
|
|
from scheduler.models import Season, Scenario, Team, DayObj, CountryClash, Country
|
|
|
|
from qualifiers.draws import groupTeams, optimize_inversions4
|
|
from scheduler.solver.tasks.optimize import optimize
|
|
|
|
import random
|
|
import time
|
|
import json
|
|
import csv
|
|
import networkx as nx
|
|
import matplotlib.pyplot as plt
|
|
from datetime import timedelta
|
|
|
|
# %%
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import requests
|
|
|
|
data = json.loads(b'{\r\n "season": "UCL 24/25",\r\n "team": 52277,\r\n "pots": [1,2,3,4],\r\n "games":[[50051, 52747], [50138, 50051], [50051, 50147]]\r\n}')
|
|
headers = {'Content-type': 'application/json', 'Authorization': 'R6v1e9Q5W8aS3b7C4x2KpZqL9yFmXnDz'}
|
|
|
|
requests.post('http://localhost:8000/draws/checker/',json=data, headers=headers)
|
|
|
|
|
|
|
|
|
|
# %%
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# %%
|
|
|
|
|
|
scenario = Scenario.objects.get(id=9340)
|
|
|
|
scenario.sol_solution
|
|
|
|
|
|
# %%
|
|
season = scenario.season
|
|
|
|
|
|
|
|
all_rounds = []
|
|
getDateByIso = {}
|
|
|
|
season = scenario.season
|
|
teams = Team.objects.filter(season=scenario.season,active=True)
|
|
higherHomeGames = defaultdict(lambda: [])
|
|
higherAwayGames = defaultdict(lambda: [])
|
|
higherDates = scenario.season.higherDates()
|
|
for game in scenario.season.higherGames():
|
|
higherHomeGames[game[1]].append(game)
|
|
higherAwayGames[game[2]].append(game)
|
|
higherRound = f"{higherDates[game[0]].isocalendar().year}-{higherDates[game[0]].isocalendar().week}"
|
|
all_rounds.append(higherRound)
|
|
getDateByIso[higherRound] = higherDates[game[0]]
|
|
|
|
higherTeams = set(list(higherHomeGames.keys()) + list(higherAwayGames.keys()))
|
|
|
|
gameRequirements = GameRequirement.objects.filter(scenario=scenario)
|
|
# stadium_clashes = Pairing.objects.filter(scenario=scenario,type="Home",prio="Hard",active=True,team2__in=teams)
|
|
pairings = Pairing.objects.filter(scenario=scenario,active=True,team2__in=teams,prio__in=['Hard','A'])
|
|
pairings_dependencies = Pairing.objects.filter(scenario=scenario,active=True,team2__in=higherTeams,prio__in=['Hard','A'])
|
|
days = Day.objects.filter(season=scenario.season, maxGames__gt=0)
|
|
blockings = Blocking.objects.filter(scenario=scenario)
|
|
seedgames = EncWish.objects.filter(scenario=scenario,active=True,reason__contains='SEED')
|
|
encwishes = EncWish.objects.filter(scenario=scenario,active=True,prio__in=['Hard','A'],timeframe=1,forOneDay=False,forOneDayNum=1)
|
|
hawishes = HAWish.objects.filter(scenario=scenario,active=True,prio__in=['Hard','A'],forEachDay=False,forOneDay=False)
|
|
uclpatterns = SpecialWish.objects.filter(scenario=scenario,name='UCL24Patterns',active=True).exists()
|
|
alternatestart = SpecialWish.objects.filter(scenario=scenario,name='AlternateStart',active=True).exists()
|
|
maxTourLength = season.maxTourLength
|
|
groups = Conference.objects.filter(scenario=scenario).filter(name__in=["UEL","UECL"])
|
|
uel_teams = list(groups.filter(name="UEL").first().teams.order_by('pot','country').values_list('id',flat=True))
|
|
uecl_teams = list(groups.filter(name="UECL").first().teams.order_by('pot','country').values_list('id',flat=True))
|
|
|
|
prioVal ={'A': 25 , 'B': 5 , 'C': 1, 'Hard' : 1000}
|
|
pairings_prio = {
|
|
(p.team1.id,p.team2.id):prioVal[p.prio] for p in pairings
|
|
}
|
|
encwish_prio = {
|
|
p.id:prioVal[p.prio] for p in encwishes
|
|
}
|
|
hawish_prio = {
|
|
p.id:prioVal[p.prio] for p in hawishes
|
|
}
|
|
dependency_prio = {
|
|
(p.team1.id,p.team2.id):prioVal[p.prio] for p in pairings_dependencies
|
|
}
|
|
|
|
daysPerRound = defaultdict(lambda:[])
|
|
# getRoundByDay = {}
|
|
# for d in days:
|
|
# daysPerRound[d.round].append(d)
|
|
# getRoundByDay[d.id] = d.round
|
|
|
|
getRoundByIso = {}
|
|
getIsoByRound = {}
|
|
getDateByDay = {}
|
|
for d in days:
|
|
getDateByDay[d] = datetime.datetime.strptime(d.day,"%Y-%m-%d")
|
|
iso = datetime.datetime.strptime(d.day,"%Y-%m-%d").isocalendar()
|
|
getRoundByIso[f"{iso.year}-{iso.week}"] = d.round
|
|
getIsoByRound[d.round] = f"{iso.year}-{iso.week}"
|
|
all_rounds.append(f"{iso.year}-{iso.week}")
|
|
getDateByIso[f"{iso.year}-{iso.week}"] = getDateByDay[d]
|
|
daysPerRound[f"{iso.year}-{iso.week}"].append(d)
|
|
|
|
all_rounds = sorted(list(set(all_rounds)))
|
|
|
|
|
|
single_day_rounds = [r for r in daysPerRound if len(daysPerRound[r]) == 1]
|
|
two_day_rounds = [r for r in daysPerRound if len(daysPerRound[r]) == 2 ]
|
|
multi_day_rounds = [r for r in daysPerRound if len(daysPerRound[r]) >= 3 ]
|
|
team_ids = list(teams.values_list('id',flat=True))
|
|
getTeamByID = {
|
|
t.id:t for t in teams
|
|
}
|
|
# list all rounds where each day is blocked for a team
|
|
blockedRounds = {(t.id,r):True for r in all_rounds for t in teams}
|
|
for t in teams:
|
|
tblocks = blockings.filter(team=t)
|
|
for r in all_rounds:
|
|
for d in daysPerRound[r]:
|
|
if not tblocks.filter(day=d).exists():
|
|
blockedRounds[(t.id,r)] = False
|
|
break
|
|
|
|
|
|
gamereqs = []
|
|
opponents_from_pot = defaultdict(lambda:defaultdict(lambda:[]))
|
|
for req in gameRequirements:
|
|
gamereqs.append((req.team1.id,req.team2.id))
|
|
opponents_from_pot[req.team1.id][req.team2.pot].append(req.team2.id)
|
|
opponents_from_pot[req.team2.id][req.team1.pot].append(req.team1.id)
|
|
pot = {}
|
|
teams_in_pot = {}
|
|
for i in teams.values_list('pot',flat=True).distinct():
|
|
pot[i] = teams.filter(pot=i)
|
|
teams_in_pot[i] = list(teams.filter(pot=i).values_list('id',flat=True))
|
|
|
|
topTeams = teams.filter(attractivity__gte=4)
|
|
topGames = [(t1.id,t2.id) for t1 in topTeams for t2 in topTeams if (t1.id,t2.id) in gamereqs]
|
|
topTeam_clashes = {t.id:[] for t in topTeams}
|
|
# for t in topTeams:
|
|
# for pair in stadium_clashes.filter(team1=t):
|
|
# topTeam_clashes[t.id].append(pair.team2.id)
|
|
# for pair in stadium_clashes.filter(team2=t):
|
|
# topTeam_clashes[t.id].append(pair.team1.id)
|
|
|
|
|
|
rounds = all_rounds
|
|
# ucl_rounds = [r for i,r in enumerate(rounds) if i in [0,2,3,4,5,6,8,9]]
|
|
uel_rounds = [r for i,r in enumerate(rounds) if i in [1,2,3,4,5,6,8,9]]
|
|
uecl_rounds = [r for i,r in enumerate(rounds) if i in [2,3,4,5,6,7]]
|
|
|
|
|
|
|
|
|
|
# BASICWISHES
|
|
# for e in hawishes.order_by('prio'):
|
|
# if e.timeslots.count() > 0:
|
|
# continue
|
|
# elemTeams = [[t] for t in e.get_teams()] if e.forEachTeam else [e.get_teams()]
|
|
# elemRounds = [set([f"{d.date.isocalendar()[0]}-{d.date.isocalendar()[1]}" for d in e.get_days()])]
|
|
# if e.minGames > 0:
|
|
# for teamset in elemTeams:
|
|
# for roundset in elemRounds:
|
|
# if e.homeAway == "Home":
|
|
# print("ADDED HA MIN",e.id,e.prio,e.homeAway,e.reason,teamset,roundset,e.minGames)
|
|
# elif e.homeAway == "Away":
|
|
# print("ADDED HA MIN",e.id,e.prio,e.homeAway,e.reason,teamset,roundset,e.minGames)
|
|
# else:
|
|
# print("ADDED HA MIN",e.id,e.prio,e.homeAway,e.reason,teamset,roundset,e.minGames)
|
|
# if e.maxGames >= 0:
|
|
# for teamset in elemTeams:
|
|
# for roundset in elemRounds:
|
|
# if e.homeAway == "Home":
|
|
# print("ADDED HA MAX",e.id,e.prio,e.homeAway,e.reason,teamset,roundset,e.maxGames)
|
|
# elif e.homeAway == "Away":
|
|
# print("ADDED HA MAX",e.id,e.prio,e.homeAway,e.reason,teamset,roundset,e.maxGames)
|
|
# else:
|
|
# print("ADDED HA MAX",e.id,e.prio,e.homeAway,e.reason,teamset,roundset,e.maxGames)
|
|
|
|
for e in encwishes.filter(id=134891).order_by('prio'):
|
|
if e.timeslots.count() > 0:
|
|
continue
|
|
elemTeams1 = [[t] for t in e.get_teams1()] if e.forEachTeam1 else [e.get_teams1()]
|
|
elemTeams2 = [[t] for t in e.get_teams2()] if e.forEachTeam2 else [e.get_teams2()]
|
|
|
|
|
|
if all(t.id in uel_teams for t in e.get_teams1()):
|
|
elemRounds = [[f"{d.date.isocalendar()[0]}-{d.date.isocalendar()[1]}"] for d in e.get_days() if f"{d.date.isocalendar()[0]}-{d.date.isocalendar()[1]}" in uel_rounds] if e.forEachDay else \
|
|
[set([f"{d.date.isocalendar()[0]}-{d.date.isocalendar()[1]}" for d in e.get_days() if f"{d.date.isocalendar()[0]}-{d.date.isocalendar()[1]}" in uel_rounds])]
|
|
elif all(t.id in uecl_teams for t in e.get_teams1()):
|
|
elemRounds = [[f"{d.date.isocalendar()[0]}-{d.date.isocalendar()[1]}"] for d in e.get_days() if f"{d.date.isocalendar()[0]}-{d.date.isocalendar()[1]}" in uecl_rounds] if e.forEachDay else \
|
|
[set([f"{d.date.isocalendar()[0]}-{d.date.isocalendar()[1]}" for d in e.get_days() if f"{d.date.isocalendar()[0]}-{d.date.isocalendar()[1]}" in uecl_rounds])]
|
|
else:
|
|
elemRounds = [[f"{d.date.isocalendar()[0]}-{d.date.isocalendar()[1]}"] for d in e.get_days()] if e.forEachDay else \
|
|
[set([f"{d.date.isocalendar()[0]}-{d.date.isocalendar()[1]}" for d in e.get_days()])]
|
|
|
|
|
|
|
|
if e.minGames > 0:
|
|
if e.useEncounterGroups:
|
|
for i,roundset in enumerate(elemRounds):
|
|
encounters = Encounter.objects.filter(encounterGroup__in=e.encounterGroups.all())
|
|
if e.symmetry:
|
|
print("ADDED ENC (SYMMETRY) MIN",e.id,e.prio,e.reason,[(t1,t2) for enc in encounters for t1 in enc.homeTeams.all() for t2 in enc.awayTeams.all()],roundset,e.minGames,e.symmetry,i)
|
|
else:
|
|
print("ADDED ENC MIN",e.id,e.prio,e.reason,[(t1,t2) for enc in encounters for t1 in enc.homeTeams.all() for t2 in enc.awayTeams.all()],roundset,e.minGames,e.symmetry,i)
|
|
|
|
else:
|
|
for teamset1 in elemTeams1:
|
|
for teamset2 in elemTeams2:
|
|
for i,roundset in enumerate(elemRounds):
|
|
print(roundset)
|
|
print(teamset1)
|
|
print(teamset2)
|
|
if e.symmetry:
|
|
print("\tADDED ENC (SYMMETRY) MIN",e.id,e.prio,e.reason,teamset1,teamset2,roundset,e.minGames,e.symmetry,i)
|
|
else:
|
|
print("\tADDED ENC MIN",e.id,e.prio,e.reason,teamset1,teamset2,roundset,e.minGames,e.symmetry,i)
|
|
if e.maxGames >= 0:
|
|
if e.useEncounterGroups:
|
|
for i,roundset in enumerate(elemRounds):
|
|
print(roundset)
|
|
encounters = Encounter.objects.filter(encounterGroup__in=e.encounterGroups.all())
|
|
for enc in encounters:
|
|
print(enc)
|
|
if e.symmetry:
|
|
print("\tADDED ENC (SYMMETRY) MAX",e.id,e.prio,e.reason,[(t1,t2) for enc in encounters for t1 in enc.homeTeams.all() for t2 in enc.awayTeams.all()],roundset,e.maxGames,e.symmetry,i)
|
|
else:
|
|
print("\tADDED ENC MAX",e.id,e.prio,e.reason,[(t1,t2) for enc in encounters for t1 in enc.homeTeams.all() for t2 in enc.awayTeams.all()],roundset,e.maxGames,e.symmetry,i)
|
|
else:
|
|
for teamset1 in elemTeams1:
|
|
for teamset2 in elemTeams2:
|
|
for i,roundset in enumerate(elemRounds):
|
|
print(roundset)
|
|
print(teamset1)
|
|
print(teamset2)
|
|
if e.symmetry:
|
|
print("\tADDED ENC (SYMMETRY) MAX",e.id,e.prio,e.reason,teamset1,teamset2,roundset,e.maxGames,e.symmetry,i)
|
|
else:
|
|
print("\tADDED ENC MAX",e.id,e.prio,e.reason,teamset1,teamset2,roundset,e.maxGames,e.symmetry,i)
|
|
|
|
# %%
|