312 lines
11 KiB
Python
Executable File
312 lines
11 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")
|
|
|
|
from leagues import settings
|
|
settings.DATABASES['default']['NAME'] = PROJECT_PATH+'/db.sqlite3'
|
|
|
|
import django
|
|
django.setup()
|
|
|
|
from scheduler.models import *
|
|
from common.functions import distanceInKmByGPS
|
|
import pandas as pd
|
|
import numpy as np
|
|
from django.db.models import Count, F, Value
|
|
|
|
|
|
thisScenario = Scenario.objects.get(id = 2)
|
|
thisSeason = thisScenario.season
|
|
thisLeague = thisSeason.league
|
|
|
|
|
|
mathModelName=thisLeague.name
|
|
if thisSeason.optimizationParameters!="":
|
|
mathModelName=thisSeason.optimizationParameters
|
|
|
|
|
|
|
|
otherScenGames=[]
|
|
if thisSeason.improvementObjective!="--":
|
|
for otherScenario in Scenario.objects.filter(season=thisSeason):
|
|
impObjWeight = 5
|
|
if thisSeason.improvementObjective=="stick to old solutions":
|
|
impObjWeight = -5
|
|
if otherScenario.solutionlist() != [['']]:
|
|
for g in otherScenario.solutionlist():
|
|
otherScenGames.append((int(g[1]),int(g[2]),int(g[3]), impObjWeight ))
|
|
|
|
getGlobalCountry={ gc['uefa']: gc['id'] for gc in GlobalCountry.objects.values() }
|
|
|
|
teamObjects = Team.objects.filter(season=thisSeason,active=True).order_by('position').values()
|
|
teams=[]
|
|
realteams=[]
|
|
faketeams=[]
|
|
importantteams=[]
|
|
shortteams=[]
|
|
t_pos={}
|
|
t_pot={}
|
|
t_color={}
|
|
t_country={}
|
|
t_globalCountry={}
|
|
t_stadium = {}
|
|
t_shortname = {}
|
|
t_usePhases = {}
|
|
t_lon = {}
|
|
t_lat = {}
|
|
t_attractivity ={}
|
|
getTeamById={}
|
|
getTeamIdByName={}
|
|
getTeamIdByShortName={}
|
|
getTeamByName={}
|
|
getStadiumById={}
|
|
teamByShort={}
|
|
top4 = []
|
|
for t in teamObjects:
|
|
# print (t['name'], t['id'])
|
|
teams.append(t['id'])
|
|
shortteams.append(t['shortname'])
|
|
teamByShort[t['shortname']]= t['name']
|
|
getTeamIdByShortName[t['shortname']]=t['id']
|
|
if t['name']!='-':
|
|
realteams.append(t['id'])
|
|
else:
|
|
faketeams.append(t['id'])
|
|
if t['very_important']:
|
|
importantteams.append(t['id'])
|
|
t_country[t['id']]= t['country']
|
|
t_globalCountry[t['id']]= t['globalCountry_id']
|
|
if not t_globalCountry[t['id']] and t_country[t['id']] in getGlobalCountry.keys() :
|
|
t_globalCountry[t['id']] = getGlobalCountry[t_country[t['id']]]
|
|
t_pos[t['name']]= t['position']
|
|
t_color[t['name']]="lightyellow"
|
|
t_pot[t['id']]= t['pot']
|
|
t_stadium[t['id']]=t['stadium']
|
|
t_attractivity[t['id']]=t['attractivity']
|
|
t_lon[t['id']]=t['longitude']
|
|
t_lat[t['id']]=t['latitude']
|
|
t_shortname[t['id']]=t['shortname']
|
|
t_usePhases[t['id']]= thisScenario.usePhases
|
|
getTeamById[t['id']]=t['name']
|
|
getStadiumById[t['id']]=t['stadium']
|
|
getTeamIdByName[t['name']]=t['id']
|
|
getTeamByName[t['name']]=t
|
|
if t['attractivity'] >= thisSeason.topTeamMinCoefficient :
|
|
top4.append(t['id'])
|
|
|
|
inactive_teams=[]
|
|
for t in Team.objects.filter(season=thisSeason,active=False).order_by('position').values():
|
|
inactive_teams.append(t['id'])
|
|
t_attractivity[t['id']]=t['attractivity']
|
|
t_lon[t['id']]=t['longitude']
|
|
t_lat[t['id']]=t['latitude']
|
|
t_country[t['id']]= t['country']
|
|
getTeamById[t['id']]=t['name']
|
|
|
|
|
|
lowerBoundFound = False
|
|
distance ={}
|
|
attractivity ={}
|
|
distanceById={}
|
|
distanceInDaysById={}
|
|
stadium_names = set([t['stadium'] for t in teamObjects if t['stadium']!=''])
|
|
stadium_id={}
|
|
stadium_name={}
|
|
sid=0
|
|
for stadium in stadium_names :
|
|
stadium_name[sid]=stadium
|
|
stadium_id[stadium]=sid
|
|
sid+=1
|
|
stadiums = list(stadium_name.keys())
|
|
teamsOfStadium ={ st:[] for st in stadiums }
|
|
|
|
travelDict= thisSeason.travelDict()
|
|
for t1 in teamObjects:
|
|
if t1['stadium']!='':
|
|
teamsOfStadium[stadium_id[t1['stadium']]].append(t1['id'])
|
|
for t2 in teamObjects:
|
|
# distance[t1['name'],t2['name']] = distanceInKm(t1,t2)
|
|
# print (t1['name'],t2['name'],distance[t1['name'],t2['name']] ," -> ", travelDict[t1['id']][t2['id']]['distance'] )
|
|
distance[t1['name'],t2['name']] = travelDict[t1['id']][t2['id']]['distance']
|
|
distanceById[t1['id'],t2['id']] = distance[t1['name'],t2['name']]
|
|
distanceInDaysById[t1['id'],t2['id']] = int(distance[t1['name'],t2['name']]/350 +0.99)
|
|
attractivity[t1['id'],t2['id']] = int(100*t1['attractivity']*t2['attractivity'])
|
|
|
|
|
|
dayObjects = Day.objects.filter(season=thisSeason).values()
|
|
days = [ d['id'] for d in dayObjects if d['round']>0 ]
|
|
|
|
higherSeasons = thisSeason.higherSeasons()
|
|
higherGames = thisSeason.higherGames()
|
|
|
|
this_season_team_names = list(getTeamByName.keys())
|
|
|
|
higherTeamObjects = Team.objects.filter(season__in=higherSeasons,active=True).values()
|
|
higherDayObjects = Day.objects.filter(season__in=higherSeasons,maxGames__gte=1).values()
|
|
higherTeams = [ t['id'] for t in higherTeamObjects]
|
|
higherTeamsOf={ t: [] for t in teams}
|
|
for t in higherTeamObjects:
|
|
getTeamById[t['id']]=t['name']
|
|
t_country[t['id']]=t['country']
|
|
if t['name'] in this_season_team_names:
|
|
higherTeamsOf[getTeamIdByName[t['name']]].append(t['id'])
|
|
|
|
print ("Teams : " , teams)
|
|
print ("VIP Teams : " , importantteams)
|
|
print ("TOP Teams : " , top4)
|
|
|
|
allConferences = Conference.objects.filter(scenario=s2)
|
|
sharedStadiums = False
|
|
for ff in thisSeason.federationmember.all():
|
|
sharedStadiums= ff.federation.sharedStadiums
|
|
|
|
# print ("\nGroups : ")
|
|
t_conference = {t : 0 for t in teams }
|
|
conf_teams={}
|
|
for c in Conference.objects.filter(scenario=s2,regional=False).order_by('name'):
|
|
# print ("A" , c)
|
|
cteams = c.teams.filter(active=True)
|
|
conf_teams[c.name]=[]
|
|
for t in cteams:
|
|
conf_teams[c.name].append(t.id)
|
|
# print ("group for ", t)
|
|
# if t_conference[t.id]!=0:
|
|
# print (getTeamById[t.id] , " in several groups")
|
|
if t_conference[t.id]==0 or len(cteams)< len(t_conference[t.id].teams.filter(active=True)):
|
|
t_conference[t.id]=c
|
|
# print (" is " , c )
|
|
# for t in set([t for t in teams if t_conference[t]==0 ]):
|
|
# print (" no group " , getTeamById[ t])
|
|
# return ''
|
|
|
|
prioVal ={'A': 25 , 'B': 5 , 'C': 1, 'Hard' : 1000}
|
|
|
|
sw_prio = {}
|
|
sw_float1 = {}
|
|
sw_float2 = {}
|
|
sw_int1 = {}
|
|
sw_int2 = {}
|
|
sw_text = {}
|
|
for sw in SpecialWish.objects.filter(scenario=s2):
|
|
sw_prio[sw.name]=prioVal[sw.prio] if sw.active else 0
|
|
sw_float1[sw.name]=sw.float1
|
|
sw_float2[sw.name]=sw.float2
|
|
sw_int1[sw.name]=sw.int1
|
|
sw_int2[sw.name]=sw.int2
|
|
sw_text[sw.name]=sw.text
|
|
special_wishes=list(sw_prio.keys())
|
|
special_wishes_active = [ sw for sw in special_wishes if sw_prio[sw]>0 ]
|
|
|
|
print (special_wishes_active)
|
|
|
|
noBreakLimitTeams = []
|
|
if "allowManyBreaksInRow" in special_wishes_active :
|
|
noBreakLimitTeams = sw_text["allowManyBreaksInRow"].split(",")
|
|
print (noBreakLimitTeams)
|
|
noBreakLimitTeams = [t for t in teams if getTeamById[t] in noBreakLimitTeams]
|
|
print (noBreakLimitTeams)
|
|
|
|
pairings_tmp = Pairing.objects.filter(scenario=s2, active=True).values()
|
|
pairings_tmp2 = Pairing.objects.filter(scenario__is_published=True, team1__id__in=teams, team2__id__in=higherTeams, active=True).values()
|
|
pairings_tmp3 = Pairing.objects.filter(scenario__is_published=True, team2__id__in=teams, team1__id__in=higherTeams, active=True).values()
|
|
pairings = []
|
|
for p in [ p for p in pairings_tmp if p['team1_id'] in teams and p['team2_id'] in teams+higherTeams ] + [ p for p in pairings_tmp2 ] + [ p for p in pairings_tmp3]:
|
|
if p not in pairings:
|
|
pairings.append(p)
|
|
breaks = Break.objects.filter(season=thisSeason).values()
|
|
blockings_tmp = Blocking.objects.filter(scenario=s2,active=True).values()
|
|
blockings = [ bl for bl in blockings_tmp if bl['team_id'] in teams ]
|
|
|
|
# times = ['Early', 'Late']
|
|
timeObjects = TimeSlot.objects.filter(season=thisSeason).values()
|
|
times = [ str(t['id']) for t in timeObjects]
|
|
getTimeById = {str(t['id']):t['name'] for t in timeObjects}
|
|
getIdByTime = {t['name']:str(t['id']) for t in timeObjects}
|
|
|
|
blocked_arena = {(t,d, tm) : False for t in teams for d in days for tm in ["----"] + times }
|
|
hidden_arena = {(t,d, tm) : False for t in teams for d in days for tm in ["----"] + times }
|
|
nBlockingHome=0
|
|
nBlockingAway=0
|
|
|
|
for bl in blockings:
|
|
if bl['type'] in ["Hide"]:
|
|
hidden_arena[(bl['team_id'],bl['day_id'], bl['time'] )]=True
|
|
|
|
if bl['type'] in ["Home","Hide"]:
|
|
nBlockingHome+=1
|
|
blocked_arena[(bl['team_id'],bl['day_id'], bl['time'] )]=True
|
|
else:
|
|
nBlockingAway+=1
|
|
|
|
nTeams=len(teams)
|
|
nPhases =thisSeason.numPhases
|
|
groupView = thisSeason.groupBased
|
|
|
|
gameCntr={(t1,t2) : 0 for t1 in teams for t2 in teams}
|
|
undirectedGameCntr={(t1,t2) : 0 for t1 in teams for t2 in teams}
|
|
|
|
if thisSeason.useFeatureOpponentMatrix:
|
|
gameRequirements = GameRequirement.objects.filter(season=thisSeason, team1__active=True, team2__active=True)
|
|
# print (len(gameRequirements))
|
|
for gm in gameRequirements:
|
|
if thisSeason.undirectedGames:
|
|
undirectedGameCntr[(gm.team1.id,gm.team2.id)]+=gm.number
|
|
undirectedGameCntr[(gm.team2.id,gm.team1.id)]+=gm.number
|
|
# print ( "found undirected game " , (gm.team1.id,gm.team2.id) , gm.number )
|
|
else:
|
|
gameCntr[(gm.team1.id,gm.team2.id)]+=gm.number
|
|
# print ( "found directed game " , (gm.team1.id,gm.team2.id) , gm.number )
|
|
else:
|
|
for t1 in teams:
|
|
for t2 in teams:
|
|
if t1!=t2:
|
|
gameCntr[(t1,t2)]+=nPhases/2
|
|
|
|
for c in Conference.objects.filter(scenario=s2):
|
|
cteams = c.teams.filter(active=True)
|
|
for t1 in cteams:
|
|
for t2 in cteams:
|
|
if t1!=t2:
|
|
gameCntr[(t1.id,t2.id)]+=c.deltaGames/2
|
|
|
|
for (t1,t2) in gameCntr.keys():
|
|
if gameCntr[(t1,t2)]%1!=0 :
|
|
undirectedGameCntr[(t1,t2)]=1
|
|
gameCntr[(t1,t2)] = int(gameCntr[(t1,t2)])
|
|
|
|
games = [ gm for gm in gameCntr.keys() if gameCntr[gm]+undirectedGameCntr[gm]>0]
|
|
|
|
objectiveFunctionWeights = ObjectiveFunctionWeight.objects.filter(scenario=s2).values()
|
|
|
|
gew={}
|
|
gew['Trips'] = 5
|
|
gew['Derbies'] = 5
|
|
gew['Pairings'] = 5
|
|
for ow in objectiveFunctionWeights:
|
|
gew[ow['name']]= ow['use'] * ow['prio']
|
|
|
|
objectivePrio = 'Breaks'
|
|
if gew['Trips']>gew['Breaks'] :
|
|
objectivePrio = 'Trips'
|
|
|
|
print("objectivePrio:", objectivePrio)
|
|
|
|
specialGameControl= mathModelName in ["Florida State League"]
|
|
|
|
if len(games)==0:
|
|
games = [ (t1,t2) for t1 in teams for t2 in teams if t1!=t2 ]
|
|
specialGameControl=True
|
|
|
|
realgames= [(t1,t2) for (t1,t2) in games if getTeamById[t1]!="-" and getTeamById[t2]!="-"]
|
|
|
|
# nur wenn die solutionlist alle spiele enthält, wird dieser modus aktiviert
|
|
evalRun = ( runMode == "Improve" and localsearch_time==0
|
|
and len(thisScenario.solutionlist())==sum([gameCntr[gm]+0.5*undirectedGameCntr[gm] for gm in realgames]) )
|
|
|
|
opponents = { t: set([]) for t in realteams}
|
|
|
|
for (t1,t2) in games:
|
|
if t1 in realteams and t2 in realteams:
|
|
opponents[t1].add(t2)
|
|
opponents[t2].add(t1) |