diff --git a/chl/draw_func.py b/chl/draw_func.py index f2a1501..2a762ef 100755 --- a/chl/draw_func.py +++ b/chl/draw_func.py @@ -1,15 +1,15 @@ - # %% import os, sys from dotenv import load_dotenv + load_dotenv() # %% -if os.environ.get('SERVER', None): - PROJECT_PATH = '/home/django/leagues/' +if os.environ.get("SERVER", None): + PROJECT_PATH = "/home/django/leagues/" else: - PROJECT_PATH = '/home/md/Work/ligalytics/leagues_stable/' + PROJECT_PATH = "/home/md/Work/ligalytics/leagues_stable/" import os, sys import json @@ -21,27 +21,28 @@ 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' -if os.environ.get('SERVER', None): - settings.DATABASES['default']['ENGINE'] = 'django.db.backends.postgresql' - settings.DATABASES['default']['HOST'] = '0.0.0.0' - settings.DATABASES['default']['PORT'] = '5433' - settings.DATABASES['default']['USER'] = 'leagues_user' - settings.DATABASES['default']['PASSWORD'] = 'ligalytics' - settings.DATABASES['default']['NAME'] = 'prod_16' +if os.environ.get("SERVER", None): + settings.DATABASES["default"]["ENGINE"] = "django.db.backends.postgresql" + settings.DATABASES["default"]["HOST"] = "0.0.0.0" + settings.DATABASES["default"]["PORT"] = "5433" + settings.DATABASES["default"]["USER"] = "leagues_user" + settings.DATABASES["default"]["PASSWORD"] = "ligalytics" + settings.DATABASES["default"]["NAME"] = "prod_16" else: - settings.DATABASES['default']['NAME'] = PROJECT_PATH+'/db.sqlite3' - settings.DATABASES['default']['ENGINE'] = 'django.db.backends.postgresql' - 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'] = {} + settings.DATABASES["default"]["NAME"] = PROJECT_PATH + "/db.sqlite3" + settings.DATABASES["default"]["ENGINE"] = "django.db.backends.postgresql" + 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" @@ -52,12 +53,17 @@ 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["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() @@ -70,7 +76,6 @@ from scheduler.helpers import * from scheduler.solver.tasks.optimize import optimize - # %% import copy @@ -86,60 +91,75 @@ from math import sqrt, sin, cos, atan2, pi import numpy as np # XPRESS ENVIRONMENT -os.environ['XPRESSDIR'] = "/opt/xpressmp_9.5.0" -os.environ['XPRESS'] = "/opt/xpressmp_9.5.0/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["XPRESSDIR"] = "/opt/xpressmp_9.5.0" +os.environ["XPRESS"] = "/opt/xpressmp_9.5.0/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'] +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"] import xpress as xp -xp.controls.outputlog = 0 +xp.controls.outputlog = 0 import datetime from dateutil.parser import parse -def Availabilities(scenario_id,showSolution = "0"): - tt = time.time() - sc = Scenario.objects.get(id=scenario_id) - teams = Team.objects.filter(season=sc.season,active=True).order_by('name').exclude(name='-') - realteams= [ t.id for t in teams] - getTeamById= { t.id : t for t in teams} - t_short= { t.id : t.shortname for t in teams} - blockings = Blocking.objects.filter(scenario=sc,team__active=True).exclude(day__round=0).order_by('day', 'team').annotate( - dayID=F('day__id'), - teamID=F('team__id'), - ) - days = Day.objects.filter(season=sc.season).order_by('day','round') - getDay = { d.id : d for d in days} - getDateTimeDay = { d.id : '' for d in days} +def Availabilities(scenario_id, showSolution="0"): + tt = time.time() + sc = Scenario.objects.get(id=scenario_id) + teams = ( + Team.objects.filter(season=sc.season, active=True) + .order_by("name") + .exclude(name="-") + ) + realteams = [t.id for t in teams] + getTeamById = {t.id: t for t in teams} + t_short = {t.id: t.shortname for t in teams} + blockings = ( + Blocking.objects.filter(scenario=sc, team__active=True) + .exclude(day__round=0) + .order_by("day", "team") + .annotate( + dayID=F("day__id"), + teamID=F("team__id"), + ) + ) + days = Day.objects.filter(season=sc.season).order_by("day", "round") + + getDay = {d.id: d for d in days} + getDateTimeDay = {d.id: "" for d in days} for d in days: - if d.day[0]!='R' : + if d.day[0] != "R": getDateTimeDay[d.id] = parse(d.day) - getDayByDateTime = { getDateTimeDay[d.id] : d for d in days} - daysSorted =[] - for dt in sorted([ getDateTimeDay[d.id] for d in days]): - daysSorted.append ( getDayByDateTime[dt] ) + getDayByDateTime = {getDateTimeDay[d.id]: d for d in days} + daysSorted = [] + for dt in sorted([getDateTimeDay[d.id] for d in days]): + daysSorted.append(getDayByDateTime[dt]) - usedDays =getDateTimeDay.values() + usedDays = getDateTimeDay.values() for d in daysSorted: - d.firstDayInSequence = (getDateTimeDay[d.id] - datetime.timedelta(days=1)) not in usedDays + d.firstDayInSequence = ( + getDateTimeDay[d.id] - datetime.timedelta(days=1) + ) not in usedDays nRounds = sc.season.nRounds - rounds=range(1,nRounds+1) + rounds = range(1, nRounds + 1) breaks = Break.objects.filter(season=sc.season).values() # SLOWING VIEW DOWN @@ -149,43 +169,56 @@ def Availabilities(scenario_id,showSolution = "0"): # print ("blocking not assigned to round: deleting " , bl) blockings.filter(day__round=0).exclude(team__active=False).delete() - blockRefreshNecessary = False + blockRefreshNecessary = False blockDict = defaultdict(dict) for bl in blockings: - if not blockDict[(bl.dayID,bl.teamID)]: - blockDict[(bl.dayID,bl.teamID)]=bl + if not blockDict[(bl.dayID, bl.teamID)]: + blockDict[(bl.dayID, bl.teamID)] = bl else: - if (blockDict[(bl.dayID,bl.teamID)].type=="Home" and bl.type=="Away") or (blockDict[(bl.dayID,bl.teamID)].type=="Away" and bl.type=="Home"): - blockDict[(bl.dayID,bl.teamID)].type="Game" - blockDict[(bl.dayID,bl.teamID)].tag=None - blockDict[(bl.dayID,bl.teamID)].save() + if ( + blockDict[(bl.dayID, bl.teamID)].type == "Home" and bl.type == "Away" + ) or ( + blockDict[(bl.dayID, bl.teamID)].type == "Away" and bl.type == "Home" + ): + blockDict[(bl.dayID, bl.teamID)].type = "Game" + blockDict[(bl.dayID, bl.teamID)].tag = None + blockDict[(bl.dayID, bl.teamID)].save() bl.delete() - blockRefreshNecessary = True + blockRefreshNecessary = True if blockRefreshNecessary: - blockings = Blocking.objects.filter(scenario=sc, team__active=True).exclude(day__round=0).order_by('day', 'team').annotate( - dayID=F('day__id'), - teamID=F('team__id'), + blockings = ( + Blocking.objects.filter(scenario=sc, team__active=True) + .exclude(day__round=0) + .order_by("day", "team") + .annotate( + dayID=F("day__id"), + teamID=F("team__id"), + ) ) - isBlocked = { (d.id,t.id,ha) : False for t in teams for d in days for ha in ['H','A'] } - isBlockedTags = { (d.id,t.id,ha) : [] for t in teams for d in days for ha in ['H','A'] } + isBlocked = { + (d.id, t.id, ha): False for t in teams for d in days for ha in ["H", "A"] + } + isBlockedTags = { + (d.id, t.id, ha): [] for t in teams for d in days for ha in ["H", "A"] + } blockComment = defaultdict(dict) for bl in blockings: if bl.tag: - if bl.tag.blocking_weight <0.0: + if bl.tag.blocking_weight < 0.0: continue - isBlockedTags[ (bl.day.id, bl.team.id, "H")].append(bl.tag.name) - if bl.comment not in ["","-"]: + isBlockedTags[(bl.day.id, bl.team.id, "H")].append(bl.tag.name) + if bl.comment not in ["", "-"]: blockComment[int(bl.day.id)][int(bl.team.id)] = bl.comment - if bl.type!="Home": - isBlocked[ (int(bl.day.id), int(bl.team.id), "A")]=True - if bl.type!="Away": - isBlocked[ (bl.day.id, bl.team.id, "H")]=True + if bl.type != "Home": + isBlocked[(int(bl.day.id), int(bl.team.id), "A")] = True + if bl.type != "Away": + isBlocked[(bl.day.id, bl.team.id, "H")] = True # print ("isBlocked",isBlocked) - for b in blockings.exclude(comment__in=["","-"]): + for b in blockings.exclude(comment__in=["", "-"]): blockComment[int(b.day.id)][int(b.team.id)] = b.comment stadiums = Stadium.objects.filter(season=sc.season) @@ -193,117 +226,178 @@ def Availabilities(scenario_id,showSolution = "0"): # print ("stadiumblockings",stadiumblockings) - groups = Conference.objects.filter(scenario=sc,display_group=True).order_by('name') + groups = Conference.objects.filter(scenario=sc, display_teams=True).order_by("name") # firstTeams = [ g.teams.all().order_by('name').first().id for g in groups] firstTeams = [] for g in groups: - tms = [(t.name, t.id ) for t in g.teams.all()] + tms = [(t.name, t.id) for t in g.teams.all()] tms.sort() firstTeams.append(tms[0][1]) - - wd = {"Mondays":0 , "Tuesdays":1 , "Wednesdays":2 , "Thursdays":3 , "Fridays":4 , "Saturdays":5 , "Sundays":6} - t_possible_weekdays={ t.id : [] for t in teams} - t_available_slot_per_weekday={ (t.id,w) : 0 for t in teams for w in wd.keys() } - t_stadiums = { t.id : [] for t in teams} - t_site_available = { (t.id,d.id):0 for t in teams for d in days } - for t in teams: + wd = { + "Mondays": 0, + "Tuesdays": 1, + "Wednesdays": 2, + "Thursdays": 3, + "Fridays": 4, + "Saturdays": 5, + "Sundays": 6, + } + t_possible_weekdays = {t.id: [] for t in teams} + t_available_slot_per_weekday = {(t.id, w): 0 for t in teams for w in wd.keys()} + t_stadiums = {t.id: [] for t in teams} + t_site_available = {(t.id, d.id): 0 for t in teams for d in days} + for t in teams: # print ("checking stadium availabilities for " , t.name) t_stadiums[t.id] = [sts.stadium for sts in t.stadiumpreferences.all()] for stsp in t.stadiumTimeSlotPreferences.all(): t_possible_weekdays[t.id].append(wd[stsp.stadiumTimeSlot.weekday]) - blockedDays = [ sb.day for sb in stsp.stadiumTimeSlot.stadiumtimeslotblockings.all().exclude(homeTeam_id__in=teams)] - for d in days: - if getDateTimeDay[d.id].weekday() == wd[stsp.stadiumTimeSlot.weekday] and d.day not in blockedDays: - t_site_available[(t.id,d.id)]+=1 - stadiumBlocks = [ (tid,did) for (tid,did) in t_site_available.keys() if t_site_available[(tid,did)]==0 and t_possible_weekdays[tid]!=[]] + blockedDays = [ + sb.day + for sb in stsp.stadiumTimeSlot.stadiumtimeslotblockings.all().exclude( + homeTeam_id__in=teams + ) + ] + for d in days: + if ( + getDateTimeDay[d.id].weekday() == wd[stsp.stadiumTimeSlot.weekday] + and d.day not in blockedDays + ): + t_site_available[(t.id, d.id)] += 1 + stadiumBlocks = [ + (tid, did) + for (tid, did) in t_site_available.keys() + if t_site_available[(tid, did)] == 0 and t_possible_weekdays[tid] != [] + ] # for t,d in stadiumBlocks: # print (getDateTimeDay[d], [ t2.name for t2 in teams if t2.id==t]) competitions = InternationalGame.objects.filter(season=sc.season, active=True) - playDays = [day.id for day in days if day.maxGames>0 and day.round>0] + playDays = [day.id for day in days if day.maxGames > 0 and day.round > 0] compDays = {} competitionBlocks = [] for c in competitions: c.blocking_weight = 0.5 compDays[c.id] = [] - dayBefore=datetime.timedelta(days=c.nDaysNotPlayBefore) - dayAfter=datetime.timedelta(days=c.nDaysNotPlayAfter) + dayBefore = datetime.timedelta(days=c.nDaysNotPlayBefore) + dayAfter = datetime.timedelta(days=c.nDaysNotPlayAfter) for d in c.days.all(): - firstDay = getDateTimeDay[d.id]-dayBefore - lastDay = getDateTimeDay[d.id]+dayAfter - compDays[c.id] += [ d2 for d2 in playDays if firstDay<= getDateTimeDay[d2] <= lastDay ] + firstDay = getDateTimeDay[d.id] - dayBefore + lastDay = getDateTimeDay[d.id] + dayAfter + compDays[c.id] += [ + d2 for d2 in playDays if firstDay <= getDateTimeDay[d2] <= lastDay + ] compDays[c.id] = list(set(compDays[c.id])) for t in c.teams.all(): for d in compDays[c.id]: - competitionBlocks.append((t.id,d)) - for tp in ["H", "A"]: - isBlocked[ (d, t.id, tp)]=True - isBlockedTags[ (d, t.id, tp)].append(c.name) + competitionBlocks.append((t.id, d)) + for tp in ["H", "A"]: + isBlocked[(d, t.id, tp)] = True + isBlockedTags[(d, t.id, tp)].append(c.name) if sc.season.useFeatureKickOffTime: - currentSolution= [ (int(sl[1]),int(sl[2]),int(sl[3]),int(sl[0]),sl[4]) for sl in sc.solutionlist() if len(sl)>4] + currentSolution = [ + (int(sl[1]), int(sl[2]), int(sl[3]), int(sl[0]), sl[4]) + for sl in sc.solutionlist() + if len(sl) > 4 + ] else: - currentSolution= [ (int(sl[1]),int(sl[2]),int(sl[3]),int(sl[0])) for sl in sc.solutionlist() if len(sl)>3] + currentSolution = [ + (int(sl[1]), int(sl[2]), int(sl[3]), int(sl[0])) + for sl in sc.solutionlist() + if len(sl) > 3 + ] - currentSolutionOfDay = { d.id: [] for d in days } - currentSolutionInRound = { (t,r): "" for t in realteams for r in rounds } - currentSolutionAtDay = { (t,d.id): "" for t in realteams for d in days } - currentSolutionTimeAtDay = { (t,d.id): "" for t in realteams for d in days } - currentSolutionTimeAtDayCode = { (t,d.id): "" for t in realteams for d in days } - currentSolutionDayOfTeamRound = { (t,r) : 0 for t in realteams for r in rounds } - games={} + currentSolutionOfDay = {d.id: [] for d in days} + currentSolutionInRound = {(t, r): "" for t in realteams for r in rounds} + currentSolutionAtDay = {(t, d.id): "" for t in realteams for d in days} + currentSolutionTimeAtDay = {(t, d.id): "" for t in realteams for d in days} + currentSolutionTimeAtDayCode = {(t, d.id): "" for t in realteams for d in days} + currentSolutionDayOfTeamRound = {(t, r): 0 for t in realteams for r in rounds} + games = {} shortGames = defaultdict(dict) - violations =[] - fullHaName = {"H":"Home", "A":"Away"} + violations = [] + fullHaName = {"H": "Home", "A": "Away"} for cs in currentSolution: - (t1,t2,r,d)=(cs[0],cs[1],cs[2],cs[3]) + (t1, t2, r, d) = (cs[0], cs[1], cs[2], cs[3]) if d in currentSolutionOfDay.keys(): - currentSolutionInRound[(t1,r)]="H" - currentSolutionInRound[(t2,r)]="A" - currentSolutionAtDay[(t1,d)]="H" - currentSolutionAtDay[(t2,d)]="A" - currentSolutionOfDay[d].append((t1,t2,r)) - currentSolutionDayOfTeamRound[(t1,r)]= d - currentSolutionDayOfTeamRound[(t2,r)]= d - if sc.season.useFeatureKickOffTime : - currentSolutionTimeAtDay[(t1,d)]=cs[4] - currentSolutionTimeAtDay[(t2,d)]=cs[4] - ts = TimeSlot.objects.filter(season=sc.season,name=cs[4]).first() + currentSolutionInRound[(t1, r)] = "H" + currentSolutionInRound[(t2, r)] = "A" + currentSolutionAtDay[(t1, d)] = "H" + currentSolutionAtDay[(t2, d)] = "A" + currentSolutionOfDay[d].append((t1, t2, r)) + currentSolutionDayOfTeamRound[(t1, r)] = d + currentSolutionDayOfTeamRound[(t2, r)] = d + if sc.season.useFeatureKickOffTime: + currentSolutionTimeAtDay[(t1, d)] = cs[4] + currentSolutionTimeAtDay[(t2, d)] = cs[4] + ts = TimeSlot.objects.filter(season=sc.season, name=cs[4]).first() if ts: - currentSolutionTimeAtDayCode[(t1,d)]=ts.code - currentSolutionTimeAtDayCode[(t2,d)]=ts.code - for t3 in [t1,t2]: - color = "red" if isBlocked[ (d, t3, currentSolutionAtDay[(t3,d)])] else "" - games[ str(d)+"_"+str(t3)]= (currentSolutionAtDay[(t3,d)]+currentSolutionTimeAtDayCode[(t3,d)] , color) - shortGames[d][t3] = t_short[t1] +"-"+ t_short[t2] - if color=="red": - violations.append( ( getTeamById[t3], getDay[d] , fullHaName[currentSolutionAtDay[(t3,d)]] , currentSolutionTimeAtDay[(t3,d)] , ", ".join(isBlockedTags[(d,t3,currentSolutionAtDay[(t3,d)])]) )) + currentSolutionTimeAtDayCode[(t1, d)] = ts.code + currentSolutionTimeAtDayCode[(t2, d)] = ts.code + for t3 in [t1, t2]: + color = ( + "red" if isBlocked[(d, t3, currentSolutionAtDay[(t3, d)])] else "" + ) + games[str(d) + "_" + str(t3)] = ( + currentSolutionAtDay[(t3, d)] + + currentSolutionTimeAtDayCode[(t3, d)], + color, + ) + shortGames[d][t3] = t_short[t1] + "-" + t_short[t2] + if color == "red": + violations.append( + ( + getTeamById[t3], + getDay[d], + fullHaName[currentSolutionAtDay[(t3, d)]], + currentSolutionTimeAtDay[(t3, d)], + ", ".join( + isBlockedTags[(d, t3, currentSolutionAtDay[(t3, d)])] + ), + ) + ) for bl in blockings: - if bl.tag and bl.tag.blocking_weight <0.0 and currentSolutionAtDay[(bl.team.id,bl.day.id)]!="H": - violations.append( ( getTeamById[bl.team.id], getDay[bl.day.id] , "Home" , "" , bl.tag.name )) + if ( + bl.tag + and bl.tag.blocking_weight < 0.0 + and currentSolutionAtDay[(bl.team.id, bl.day.id)] != "H" + ): + violations.append( + (getTeamById[bl.team.id], getDay[bl.day.id], "Home", "", bl.tag.name) + ) redStripes = [] missingBreaks = [] - for bl in breaks : - for t in realteams: - if currentSolutionInRound[(t,bl['round1'])]== currentSolutionInRound[(t,bl['round2'])] and currentSolutionInRound[(t,bl['round1'])] in ["H","A"]: - redStripes.append(str(currentSolutionDayOfTeamRound[(t,bl['round1'])])+'_'+str(t) +'__'+str(currentSolutionDayOfTeamRound[(t,bl['round2'])])+'_'+str(t)) + for bl in breaks: + for t in realteams: + if currentSolutionInRound[(t, bl["round1"])] == currentSolutionInRound[ + (t, bl["round2"]) + ] and currentSolutionInRound[(t, bl["round1"])] in ["H", "A"]: + redStripes.append( + str(currentSolutionDayOfTeamRound[(t, bl["round1"])]) + + "_" + + str(t) + + "__" + + str(currentSolutionDayOfTeamRound[(t, bl["round2"])]) + + "_" + + str(t) + ) else: missingBreaks.append(t) - if showSolution=="0": - games=[] - redStripes=[] - violations=[] - shortGames={} + if showSolution == "0": + games = [] + redStripes = [] + violations = [] + shortGames = {} context = { # 'blockings1' : blockings1, # 'games' : games, # 'shortGames' : shortGames, - 'violations' : violations, + "violations": violations, # 'firstTeams' : firstTeams, # 'blockings' : blockings, # 'stadiumBlocks' : stadiumBlocks, @@ -316,184 +410,244 @@ def Availabilities(scenario_id,showSolution = "0"): # 'tags': Tag.objects.filter(season=sc.season).exclude(blocking_weight=0), # 'stadiums' : stadiums, # 'stadiumblockings' : stadiumblockings, - # 'showStadiums' : showSolution=="0", - 'missingBreaks': missingBreaks, + # 'showStadiums' : showSolution=="0", + "missingBreaks": missingBreaks, } - - + return context - class Draw_Simulator: - def __init__(self,algorithm, opponent_func, html_output, use_db=False, use_chess=False): + def __init__( + self, algorithm, opponent_func, html_output, use_db=False, use_chess=False, suffix="", opt_param="", scenario_id=None + ): self.chess = use_chess self.blue_groups = [] self.red_groups = [] + self.suffix = suffix + self.opt_param = opt_param + self.scenario_id = scenario_id if self.chess: - + # basepots {'D': [ # {'id': 47715, 'pot': 'D', 'name': 'Rouen Dragons', 'country': 'France', 'coeff': 2.0, 'lat': 49.443232, 'lon': 1.099971}, - # {'id': 47747, 'pot': 'D', 'name': 'Fehérvár AV19', 'country': 'Austria', 'coeff': 3.0, 'lat': 47.1860262, 'lon': 18.4221358}, - # {'id': 52169, 'pot': 'D', 'name': 'Sheffield Steelers', 'country': 'United Kingdom', 'coeff': 3.0, 'lat': 53.38112899999999, 'lon': -1.470085}, - # {'id': 52170, 'pot': 'D', 'name': 'SønderjyskE Vojens', 'country': 'Denmark', 'coeff': 1.0, 'lat': 55.249489, 'lon': 9.3019649}, - # {'id': 52171, 'pot': 'D', 'name': 'Unia Oświęcim', 'country': 'Poland', 'coeff': 1.0, 'lat': 50.0343982, 'lon': 19.2097782}, + # {'id': 47747, 'pot': 'D', 'name': 'Fehérvár AV19', 'country': 'Austria', 'coeff': 3.0, 'lat': 47.1860262, 'lon': 18.4221358}, + # {'id': 52169, 'pot': 'D', 'name': 'Sheffield Steelers', 'country': 'United Kingdom', 'coeff': 3.0, 'lat': 53.38112899999999, 'lon': -1.470085}, + # {'id': 52170, 'pot': 'D', 'name': 'SønderjyskE Vojens', 'country': 'Denmark', 'coeff': 1.0, 'lat': 55.249489, 'lon': 9.3019649}, + # {'id': 52171, 'pot': 'D', 'name': 'Unia Oświęcim', 'country': 'Poland', 'coeff': 1.0, 'lat': 50.0343982, 'lon': 19.2097782}, # {'id': 47741, 'pot': 'D', 'name': 'Storhamar Hamar', 'country': 'Norway', 'coeff': 1.0, 'lat': 60.794442, 'lon': 11.0442983}], 'C': [ - # {'id': 52167, 'pot': 'C', 'name': 'KAC Klagenfurt', 'country': 'Austria', 'coeff': 3.0, 'lat': 46.625704, 'lon': 14.3137371}, - # {'id': 47742, 'pot': 'C', 'name': 'Växjö Lakers', 'country': 'Sweden', 'coeff': 4.0, 'lat': 56.8790044, 'lon': 14.8058522}, - # {'id': 47743, 'pot': 'C', 'name': 'Straubing Tigers', 'country': 'Germany', 'coeff': 4.0, 'lat': 48.8777333, 'lon': 12.5801538}, - # {'id': 47755, 'pot': 'C', 'name': 'Sparta Prague', 'country': 'Czechia', 'coeff': 4.0, 'lat': 50.0755381, 'lon': 14.4378005}, - # {'id': 52168, 'pot': 'C', 'name': 'Lausanne HC', 'country': 'Switzerland', 'coeff': 3.0, 'lat': 46.5196535, 'lon': 6.6322734}, + # {'id': 52167, 'pot': 'C', 'name': 'KAC Klagenfurt', 'country': 'Austria', 'coeff': 3.0, 'lat': 46.625704, 'lon': 14.3137371}, + # {'id': 47742, 'pot': 'C', 'name': 'Växjö Lakers', 'country': 'Sweden', 'coeff': 4.0, 'lat': 56.8790044, 'lon': 14.8058522}, + # {'id': 47743, 'pot': 'C', 'name': 'Straubing Tigers', 'country': 'Germany', 'coeff': 4.0, 'lat': 48.8777333, 'lon': 12.5801538}, + # {'id': 47755, 'pot': 'C', 'name': 'Sparta Prague', 'country': 'Czechia', 'coeff': 4.0, 'lat': 50.0755381, 'lon': 14.4378005}, + # {'id': 52168, 'pot': 'C', 'name': 'Lausanne HC', 'country': 'Switzerland', 'coeff': 3.0, 'lat': 46.5196535, 'lon': 6.6322734}, # {'id': 47737, 'pot': 'C', 'name': 'Lahti Pelicans', 'country': 'Finland', 'coeff': 2.0, 'lat': 60.9826749, 'lon': 25.6612096}], 'B': [ - # {'id': 52166, 'pot': 'B', 'name': 'Pinguins Bremerhaven', 'country': 'Germany', 'coeff': 4.0, 'lat': 53.5395845, 'lon': 8.5809424}, - # {'id': 47761, 'pot': 'B', 'name': 'Red Bull Salzburg', 'country': 'Austria', 'coeff': 3.0, 'lat': 47.80949, 'lon': 13.05501}, - # {'id': 47724, 'pot': 'B', 'name': 'Ilves Tampere', 'country': 'Finland', 'coeff': 4.0, 'lat': 61.4977524, 'lon': 23.7609535}, - # {'id': 47735, 'pot': 'B', 'name': 'Dynamo Pardubice', 'country': 'Czechia', 'coeff': 4.0, 'lat': 50.0343092, 'lon': 15.7811994}, - # {'id': 47740, 'pot': 'B', 'name': 'Färjestad Karlstad', 'country': 'Sweden', 'coeff': 4.0, 'lat': 59.4002601, 'lon': 13.5009352}, + # {'id': 52166, 'pot': 'B', 'name': 'Pinguins Bremerhaven', 'country': 'Germany', 'coeff': 4.0, 'lat': 53.5395845, 'lon': 8.5809424}, + # {'id': 47761, 'pot': 'B', 'name': 'Red Bull Salzburg', 'country': 'Austria', 'coeff': 3.0, 'lat': 47.80949, 'lon': 13.05501}, + # {'id': 47724, 'pot': 'B', 'name': 'Ilves Tampere', 'country': 'Finland', 'coeff': 4.0, 'lat': 61.4977524, 'lon': 23.7609535}, + # {'id': 47735, 'pot': 'B', 'name': 'Dynamo Pardubice', 'country': 'Czechia', 'coeff': 4.0, 'lat': 50.0343092, 'lon': 15.7811994}, + # {'id': 47740, 'pot': 'B', 'name': 'Färjestad Karlstad', 'country': 'Sweden', 'coeff': 4.0, 'lat': 59.4002601, 'lon': 13.5009352}, # {'id': 47717, 'pot': 'B', 'name': 'Fribourg-Gottéron', 'country': 'Switzerland', 'coeff': 4.0, 'lat': 46.8064773, 'lon': 7.1619719}], 'A': [ - # {'id': 47721, 'pot': 'A', 'name': 'Eisbären Berlin', 'country': 'Germany', 'coeff': 4.0, 'lat': 52.5200066, 'lon': 13.404954}, - # {'id': 47719, 'pot': 'A', 'name': 'ZSC Lions Zurich', 'country': 'Switzerland', 'coeff': 4.0, 'lat': 47.4124497, 'lon': 8.5578995}, - # {'id': 47756, 'pot': 'A', 'name': 'Oceláři Třinec', 'country': 'Czechia', 'coeff': 4.0, 'lat': 49.677631, 'lon': 18.6707901}, - # {'id': 47757, 'pot': 'A', 'name': 'Skellefteå AIK', 'country': 'Sweden', 'coeff': 4.0, 'lat': 64.750244, 'lon': 20.950917}, - # {'id': 47725, 'pot': 'A', 'name': 'Tappara Tampere', 'country': 'Finland', 'coeff': 4.0, 'lat': 61.4977524, 'lon': 23.7609535}, + # {'id': 47721, 'pot': 'A', 'name': 'Eisbären Berlin', 'country': 'Germany', 'coeff': 4.0, 'lat': 52.5200066, 'lon': 13.404954}, + # {'id': 47719, 'pot': 'A', 'name': 'ZSC Lions Zurich', 'country': 'Switzerland', 'coeff': 4.0, 'lat': 47.4124497, 'lon': 8.5578995}, + # {'id': 47756, 'pot': 'A', 'name': 'Oceláři Třinec', 'country': 'Czechia', 'coeff': 4.0, 'lat': 49.677631, 'lon': 18.6707901}, + # {'id': 47757, 'pot': 'A', 'name': 'Skellefteå AIK', 'country': 'Sweden', 'coeff': 4.0, 'lat': 64.750244, 'lon': 20.950917}, + # {'id': 47725, 'pot': 'A', 'name': 'Tappara Tampere', 'country': 'Finland', 'coeff': 4.0, 'lat': 61.4977524, 'lon': 23.7609535}, # {'id': 47733, 'pot': 'A', 'name': 'Genève-Servette', 'country': 'Switzerland', 'coeff': 4.0, 'lat': 46.2043907, 'lon': 6.1431577}]} + # self.blue_teams = ['Sheffield Steelers', 'Fribourg-Gottéron', 'ZSC Lions Zurich'] + + # self.red_teams = ['Sparta Prague'] + self.blue_teams = [ - 52169, 47717, 47719 + 'Genève-Servette','Eisbären Berlin','Sheffield Steelers','ZSC Lions Zurich','Fribourg-Gottéron', ] - self.red_teams = [ - 47755 + 'Ilves Tampere','Sparta Prague','Tappara Tampere', ] - - - - - # self.blue_teams = [ - # 47733,47721,52169,47719,47717, - # ] - # self.red_teams = [ - # 47724,47755,47725, - # ] else: self.blue_teams = [] self.red_teams = [] - - self.pots = ['D','C','B','A'] + + self.pots = ["D", "C", "B", "A"] if use_db: - scenario_id = 12098 - scenario = Scenario.objects.get(id=scenario_id) + scenario = Scenario.objects.get(id=self.scenario_id) self.basepots = { - pot : [ + pot: [ { - 'id': team.id, - 'pot': pot, - 'name': team.name, - 'country': team.countryObj.name, - 'coeff': team.attractivity, - 'lat': team.latitude, - 'lon': team.longitude, + "id": team.id, + "pot": pot, + "name": team.name, + "country": team.countryObj.name, + "coeff": team.attractivity, + "lat": team.latitude, + "lon": team.longitude, } - for team in Team.objects.filter(season=scenario.season,pot=pot_n+1,active=True) + for team in Team.objects.filter( + season=scenario.season, pot=pot_n + 1, active=True + ) ] - for pot_n,pot in enumerate(self.pots) + for pot_n, pot in enumerate(self.pots) } - - df_rank = pd.read_csv('rankings_2.0.csv') + + df_rank = pd.read_csv("rankings_2.0.csv") for pot in self.basepots: for team in self.basepots[pot]: try: - ranking = df_rank[df_rank['TEAM'] == team['name']].iloc[0] - team['coeff'] = ranking['RANK'] + ranking = df_rank[df_rank["TEAM"] == team["name"]].iloc[0] + team["coeff"] = ranking["RANK"] except: - team['coeff'] = 0 + team["coeff"] = 0 + + self.blue_teams = [t.id for t in Team.objects.filter(season=scenario.season,name__in=self.blue_teams)] + self.red_teams = [t.id for t in Team.objects.filter(season=scenario.season,name__in=self.red_teams)] else: self.basepots = { - 'A': [ - - {'id': 0, 'pot': 'A', 'name': 'Rögle Ängelholm', 'country': 'Sweden'}, - - {'id': 1, 'pot': 'A', 'name': 'Färjestad Karlstad', 'country': 'Sweden'}, - - {'id': 2, 'pot': 'A', 'name': 'EV Zug', 'country': 'Switzerland'}, - - {'id': 3, 'pot': 'A', 'name': 'Eisbären Berlin', 'country': 'Germany'}, - - {'id': 4, 'pot': 'A', 'name': 'Tappara Tampere', 'country': 'Finland'}, - - {'id': 5, 'pot': 'A', 'name': 'Oceláři Třinec', - 'country': 'Czech Republic'}, + "A": [ + { + "id": 0, + "pot": "A", + "name": "Rögle Ängelholm", + "country": "Sweden", + }, + { + "id": 1, + "pot": "A", + "name": "Färjestad Karlstad", + "country": "Sweden", + }, + {"id": 2, "pot": "A", "name": "EV Zug", "country": "Switzerland"}, + { + "id": 3, + "pot": "A", + "name": "Eisbären Berlin", + "country": "Germany", + }, + { + "id": 4, + "pot": "A", + "name": "Tappara Tampere", + "country": "Finland", + }, + { + "id": 5, + "pot": "A", + "name": "Oceláři Třinec", + "country": "Czech Republic", + }, ], - 'B': [ - - {'id': 6, 'pot': 'B', 'name': 'Red Bull Salzburg', 'country': 'Austria'}, - - {'id': 7, 'pot': 'B', 'name': 'Lulea Hockey', 'country': 'Sweden'}, - - {'id': 8, 'pot': 'B', 'name': 'Fribourg-Gottéron', - 'country': 'Switzerland'}, - - {'id': 9, 'pot': 'B', 'name': 'Red Bull Munich', 'country': 'Germany'}, - - {'id': 10, 'pot': 'B', 'name': 'Jukurit Mikkeli', 'country': 'Finland'}, - - {'id': 11, 'pot': 'B', 'name': 'Mountfield HK', - 'country': 'Czech Republic'}, + "B": [ + { + "id": 6, + "pot": "B", + "name": "Red Bull Salzburg", + "country": "Austria", + }, + {"id": 7, "pot": "B", "name": "Lulea Hockey", "country": "Sweden"}, + { + "id": 8, + "pot": "B", + "name": "Fribourg-Gottéron", + "country": "Switzerland", + }, + { + "id": 9, + "pot": "B", + "name": "Red Bull Munich", + "country": "Germany", + }, + { + "id": 10, + "pot": "B", + "name": "Jukurit Mikkeli", + "country": "Finland", + }, + { + "id": 11, + "pot": "B", + "name": "Mountfield HK", + "country": "Czech Republic", + }, ], - 'C': [ - - {'id': 12, 'pot': 'C', 'name': 'VS Villach', - 'country': 'Austria'}, - - {'id': 13, 'pot': 'C', 'name': 'ZSC Lions Zürich', - 'country': 'Switzerland'}, - - {'id': 14, 'pot': 'C', 'name': 'Grizzlys Wolfsburg', 'country': 'Germany'}, - - {'id': 15, 'pot': 'C', 'name': 'Ilves Tampere', - 'country': 'Finland'}, - - {'id': 16, 'pot': 'C', 'name': 'Sparta Prague', - 'country': 'Czech Republic'}, - - {'id': 17, 'pot': 'C', 'name': 'Fehérvár AV19', - 'country': 'Austria'}, + "C": [ + {"id": 12, "pot": "C", "name": "VS Villach", "country": "Austria"}, + { + "id": 13, + "pot": "C", + "name": "ZSC Lions Zürich", + "country": "Switzerland", + }, + { + "id": 14, + "pot": "C", + "name": "Grizzlys Wolfsburg", + "country": "Germany", + }, + { + "id": 15, + "pot": "C", + "name": "Ilves Tampere", + "country": "Finland", + }, + { + "id": 16, + "pot": "C", + "name": "Sparta Prague", + "country": "Czech Republic", + }, + { + "id": 17, + "pot": "C", + "name": "Fehérvár AV19", + "country": "Austria", + }, + ], + "D": [ + { + "id": 18, + "pot": "D", + "name": "Belfast Giants", + "country": "United Kingdom", + }, + {"id": 19, "pot": "D", "name": "Grenoble", "country": "France"}, + {"id": 20, "pot": "D", "name": "GKS Katowice", "country": "Poland"}, + { + "id": 21, + "pot": "D", + "name": "Aalborg Pirates", + "country": "Denmark", + }, + { + "id": 22, + "pot": "D", + "name": "Stavanger Oilers", + "country": "Norway", + }, + { + "id": 23, + "pot": "D", + "name": "Slovan Bratislava", + "country": "Slovakia", + }, ], - 'D': [ - - {'id': 18, 'pot': 'D', 'name': 'Belfast Giants', - 'country': 'United Kingdom'}, - - {'id': 19, 'pot': 'D', 'name': 'Grenoble', 'country': 'France'}, - - {'id': 20, 'pot': 'D', 'name': 'GKS Katowice', 'country': 'Poland'}, - - {'id': 21, 'pot': 'D', 'name': 'Aalborg Pirates', 'country': 'Denmark'}, - - {'id': 22, 'pot': 'D', 'name': 'Stavanger Oilers', 'country': 'Norway'}, - - {'id': 23, 'pot': 'D', 'name': 'Slovan Bratislava', 'country': 'Slovakia'}, - ] } - df_rank = pd.read_csv('rankings.csv') - df_geo = pd.read_csv('geocoord.csv') + df_rank = pd.read_csv("rankings.csv") + df_geo = pd.read_csv("geocoord.csv") for pot in self.basepots: for team in self.basepots[pot]: - ranking = df_rank[df_rank['TEAM'] == team['name']].iloc[0] - team['coeff'] = ranking['RANK'] - geo = df_geo[df_geo['TEAM'] == team['name']].iloc[0] - team['lat'] = geo['LAT'] - team['lon'] = geo['LON'] + ranking = df_rank[df_rank["TEAM"] == team["name"]].iloc[0] + team["coeff"] = ranking["RANK"] + geo = df_geo[df_geo["TEAM"] == team["name"]].iloc[0] + team["lat"] = geo["LAT"] + team["lon"] = geo["LON"] - self.groups = range(1, len(self.basepots[self.pots[0]])+1) - self.empty_groups = { - g: {b: None for b in self.pots} for g in self.groups - } + self.groups = range(1, len(self.basepots[self.pots[0]]) + 1) + self.empty_groups = {g: {b: None for b in self.pots} for g in self.groups} teams = [] id = 0 @@ -503,17 +657,19 @@ class Draw_Simulator: id += 1 self.teams = teams - self.countries = set([t['country'] for t in teams]) + self.countries = set([t["country"] for t in teams]) self.teams_by_country = { - c: [v for v in teams if v['country'] == c] for c in self.countries + c: [v for v in teams if v["country"] == c] for c in self.countries } self.distance_matrix = { - (t1['id'],t2['id']): Draw_Simulator.distanceInKmByGPS(t1['lat'],t1['lon'],t2['lat'],t2['lon']) - for t1 in self.teams for t2 in self.teams + (t1["id"], t2["id"]): Draw_Simulator.distanceInKmByGPS( + t1["lat"], t1["lon"], t2["lat"], t2["lon"] + ) + for t1 in self.teams + for t2 in self.teams } - self.opponent_func = opponent_func self.opponents, self.homeGames, self.awayGames = opponent_func(self) @@ -527,13 +683,14 @@ class Draw_Simulator: return degrees * pi / 180 earthRadiusKm = 6371 - dLat = degreesToRadians(lat2-lat1) - dLon = degreesToRadians(lon2-lon1) + dLat = degreesToRadians(lat2 - lat1) + dLon = degreesToRadians(lon2 - lon1) lat1 = degreesToRadians(lat1) lat2 = degreesToRadians(lat2) - a = sin(dLat/2) * sin(dLat/2) + sin(dLon/2) * \ - sin(dLon/2) * cos(lat1) * cos(lat2) - c = 2 * atan2(sqrt(a), sqrt(1-a)) + a = sin(dLat / 2) * sin(dLat / 2) + sin(dLon / 2) * sin(dLon / 2) * cos( + lat1 + ) * cos(lat2) + c = 2 * atan2(sqrt(a), sqrt(1 - a)) return int(earthRadiusKm * c) @staticmethod @@ -546,20 +703,19 @@ class Draw_Simulator: return "rgb(255,255,255)" if value <= 0.5: g = 256 - r = 2 * max(0,value) * 256 + r = 2 * max(0, value) * 256 if value > 0.5: - g = 2*(1-min(1,value))*256 + g = 2 * (1 - min(1, value)) * 256 r = 256 return f"rgb({r},{g},{0})" - def groups_6_4(self): """ 6 groups of 4 teams """ opponents = defaultdict(lambda: []) - homeGames = defaultdict(lambda:[]) - awayGames = defaultdict(lambda:[]) + homeGames = defaultdict(lambda: []) + awayGames = defaultdict(lambda: []) for i, g in enumerate(self.groups): for p in self.pots: other_pots = [k for k in self.pots if k != p] @@ -570,35 +726,34 @@ class Draw_Simulator: return opponents, homeGames, awayGames - def groups_3_8(self): """ 3 groups of 8 teams """ opponents = defaultdict(lambda: []) - homeGames = defaultdict(lambda:[]) - awayGames = defaultdict(lambda:[]) + homeGames = defaultdict(lambda: []) + awayGames = defaultdict(lambda: []) for i, g in enumerate(self.groups): if g % 2 == 0: - other_group = self.groups[i-1] + other_group = self.groups[i - 1] else: - other_group = self.groups[i+1] + other_group = self.groups[i + 1] for p in self.pots: other_pots = [k for k in self.pots if k != p] for l in other_pots: opponents[g, p].append((g, l)) opponents[g, p].append((other_group, l)) - if p == 'A' and l in ['B','C','D']: + if p == "A" and l in ["B", "C", "D"]: awayGames[g, p].append((g, l)) homeGames[g, l].append((g, p)) homeGames[g, p].append((other_group, l)) awayGames[other_group, l].append((g, p)) - if p == 'B' and l in ['C','D']: + if p == "B" and l in ["C", "D"]: awayGames[g, p].append((g, l)) homeGames[g, l].append((g, p)) homeGames[g, p].append((other_group, l)) awayGames[other_group, l].append((g, p)) - if p == 'C' and l in ['D']: + if p == "C" and l in ["D"]: awayGames[g, p].append((g, l)) homeGames[g, l].append((g, p)) homeGames[g, p].append((other_group, l)) @@ -611,90 +766,95 @@ class Draw_Simulator: 3 groups of 8 teams - stephan """ opponents = defaultdict(lambda: []) - homeGames = defaultdict(lambda:[]) - awayGames = defaultdict(lambda:[]) - - for i,g in enumerate(self.groups): + homeGames = defaultdict(lambda: []) + awayGames = defaultdict(lambda: []) + + for i, g in enumerate(self.groups): if g % 2 == 0: - other_group = self.groups[i-1] + other_group = self.groups[i - 1] else: - other_group = self.groups[i+1] - for i2,p in enumerate(self.pots): + other_group = self.groups[i + 1] + for i2, p in enumerate(self.pots): other_pots = [k for k in self.pots] - for j2,l in enumerate(other_pots): - if p == l: + for j2, l in enumerate(other_pots): + if p == l: opponents[g, p].append((other_group, l)) - elif i2+j2 == 3: + elif i2 + j2 == 3: opponents[g, p].append((g, l)) else: opponents[g, p].append((g, l)) opponents[g, p].append((other_group, l)) - - + if g % 2 == 0: - awayGames[g, 'A'] += [(g, 'D'),(g, 'B'),(g, 'C')] - homeGames[g, 'A'] += [(other_group, 'A'),(other_group, 'B'),(other_group, 'C')] - - awayGames[g, 'B'] += [(other_group, 'A'),(g, 'C'),(g, 'D')] - homeGames[g, 'B'] += [(g, 'A'),(other_group, 'B'),(other_group, 'D')] - - awayGames[g, 'C'] += [(other_group, 'A'),(other_group, 'C'),(g, 'D')] - homeGames[g, 'C'] += [(g, 'B'),(other_group, 'D'),(g, 'A')] - - awayGames[g, 'D'] += [(other_group, 'D'),(other_group, 'C'),(other_group, 'B')] - homeGames[g, 'D'] += [(g, 'A'),(g, 'B'),(g, 'C')] - + awayGames[g, "A"] += [(g, "D"), (g, "B"), (g, "C")] + homeGames[g, "A"] += [ + (other_group, "A"), + (other_group, "B"), + (other_group, "C"), + ] + + awayGames[g, "B"] += [(other_group, "A"), (g, "C"), (g, "D")] + homeGames[g, "B"] += [(g, "A"), (other_group, "B"), (other_group, "D")] + + awayGames[g, "C"] += [(other_group, "A"), (other_group, "C"), (g, "D")] + homeGames[g, "C"] += [(g, "B"), (other_group, "D"), (g, "A")] + + awayGames[g, "D"] += [ + (other_group, "D"), + (other_group, "C"), + (other_group, "B"), + ] + homeGames[g, "D"] += [(g, "A"), (g, "B"), (g, "C")] + else: - awayGames[g, 'A'] += [(other_group, 'A'),(g, 'B'),(g, 'C')] - homeGames[g, 'A'] += [(g, 'D'),(other_group, 'B'),(other_group, 'C')] - - awayGames[g, 'B'] += [(other_group, 'B'),(other_group, 'A'),(g, 'D')] - homeGames[g, 'B'] += [(g, 'A'),(g, 'C'),(other_group, 'D')] - - awayGames[g, 'C'] += [(g, 'B'),(other_group, 'A'),(g, 'D')] - homeGames[g, 'C'] += [(g, 'A'),(other_group, 'C'),(other_group, 'D')] - - awayGames[g, 'D'] += [(g, 'A'),(other_group, 'C'),(other_group, 'B')] - homeGames[g, 'D'] += [(g, 'B'),(g, 'C'),(other_group, 'D')] - - - # if p == 'A': - # if l == 'A': - # awayGames[g, p].append((g, l)) - # if l in ['B','C']: - # awayGames[g, p].append((g, l)) - # homeGames[g, l].append((g, p)) - # homeGames[g, p].append((other_group, l)) - # awayGames[other_group, l].append((g, p)) - # if p == 'B' and l in ['C','D']: - # awayGames[g, p].append((g, l)) - # homeGames[g, l].append((g, p)) - # homeGames[g, p].append((other_group, l)) - # awayGames[other_group, l].append((g, p)) - # if p == 'C' and l in ['D']: - # awayGames[g, p].append((g, l)) - # homeGames[g, l].append((g, p)) - # homeGames[g, p].append((other_group, l)) - # awayGames[other_group, l].append((g, p)) + awayGames[g, "A"] += [(other_group, "A"), (g, "B"), (g, "C")] + homeGames[g, "A"] += [(g, "D"), (other_group, "B"), (other_group, "C")] + + awayGames[g, "B"] += [(other_group, "B"), (other_group, "A"), (g, "D")] + homeGames[g, "B"] += [(g, "A"), (g, "C"), (other_group, "D")] + + awayGames[g, "C"] += [(g, "B"), (other_group, "A"), (g, "D")] + homeGames[g, "C"] += [(g, "A"), (other_group, "C"), (other_group, "D")] + + awayGames[g, "D"] += [(g, "A"), (other_group, "C"), (other_group, "B")] + homeGames[g, "D"] += [(g, "B"), (g, "C"), (other_group, "D")] + + # if p == 'A': + # if l == 'A': + # awayGames[g, p].append((g, l)) + # if l in ['B','C']: + # awayGames[g, p].append((g, l)) + # homeGames[g, l].append((g, p)) + # homeGames[g, p].append((other_group, l)) + # awayGames[other_group, l].append((g, p)) + # if p == 'B' and l in ['C','D']: + # awayGames[g, p].append((g, l)) + # homeGames[g, l].append((g, p)) + # homeGames[g, p].append((other_group, l)) + # awayGames[other_group, l].append((g, p)) + # if p == 'C' and l in ['D']: + # awayGames[g, p].append((g, l)) + # homeGames[g, l].append((g, p)) + # homeGames[g, p].append((other_group, l)) + # awayGames[other_group, l].append((g, p)) return opponents, homeGames, awayGames - def groups_2_12_martin(self): """ 2 groups of 12 teams """ opponents = defaultdict(lambda: []) - homeGames = defaultdict(lambda:[]) - awayGames = defaultdict(lambda:[]) + homeGames = defaultdict(lambda: []) + awayGames = defaultdict(lambda: []) for i, g in enumerate(self.groups): - half = len(self.groups)//2 + half = len(self.groups) // 2 if g <= half: - left_group = self.groups[:half][i-1] - right_group = self.groups[:half][(i+1) % half] + left_group = self.groups[:half][i - 1] + right_group = self.groups[:half][(i + 1) % half] else: - left_group = self.groups[half:][(i-half-1)] - right_group = self.groups[half:][(i-half+1) % half] + left_group = self.groups[half:][(i - half - 1)] + right_group = self.groups[half:][(i - half + 1) % half] for p in self.pots: other_pots = [k for k in self.pots if k != p] for l in other_pots: @@ -705,77 +865,73 @@ class Draw_Simulator: return opponents, homeGames, awayGames - def groups_2_12_stephan(self): """ 2 groups of 12 teams """ opponents = defaultdict(lambda: []) - homeGames = defaultdict(lambda:[]) - awayGames = defaultdict(lambda:[]) + homeGames = defaultdict(lambda: []) + awayGames = defaultdict(lambda: []) for i, g in enumerate(self.groups): - half = len(self.groups)//2 + half = len(self.groups) // 2 if g <= half: - left_group = self.groups[:half][i-1] - right_group = self.groups[:half][(i+1) % half] + left_group = self.groups[:half][i - 1] + right_group = self.groups[:half][(i + 1) % half] else: - left_group = self.groups[half:][(i-half-1)] - right_group = self.groups[half:][(i-half+1) % half] + left_group = self.groups[half:][(i - half - 1)] + right_group = self.groups[half:][(i - half + 1) % half] for p in self.pots: other_pots = [k for k in self.pots if k != p] for l in other_pots: opponents[g, p].append((g, l)) - if p == "A" and l in ['B', 'C']: + if p == "A" and l in ["B", "C"]: opponents[g, p].append((right_group, l)) awayGames[g, p].append((g, l)) homeGames[g, p].append((right_group, l)) - elif p == "A" and l in ['D']: + elif p == "A" and l in ["D"]: opponents[g, p].append((left_group, l)) homeGames[g, p].append((g, l)) awayGames[g, p].append((left_group, l)) - elif p == "B" and l in ['C', 'D']: + elif p == "B" and l in ["C", "D"]: opponents[g, p].append((right_group, l)) awayGames[g, p].append((g, l)) homeGames[g, p].append((right_group, l)) - elif p == "B" and l in ['A']: + elif p == "B" and l in ["A"]: opponents[g, p].append((left_group, l)) awayGames[g, p].append((left_group, l)) homeGames[g, p].append((g, l)) - elif p == "C" and l in ['D']: + elif p == "C" and l in ["D"]: opponents[g, p].append((right_group, l)) awayGames[g, p].append((g, l)) homeGames[g, p].append((right_group, l)) - elif p == "C" and l in ['A', 'B']: + elif p == "C" and l in ["A", "B"]: opponents[g, p].append((left_group, l)) awayGames[g, p].append((left_group, l)) homeGames[g, p].append((g, l)) - elif p == "D" and l in ['A']: + elif p == "D" and l in ["A"]: opponents[g, p].append((right_group, l)) homeGames[g, p].append((right_group, l)) awayGames[g, p].append((g, l)) - elif p == "D" and l in ['B', 'C']: + elif p == "D" and l in ["B", "C"]: opponents[g, p].append((left_group, l)) awayGames[g, p].append((left_group, l)) homeGames[g, p].append((g, l)) return opponents, homeGames, awayGames + def groups_1_24_chess(self): + return self.groups_1_24() - def groups_1_24_martin_chess(self): - return self.groups_1_24_martin() - - - - def groups_1_24_martin(self): + def groups_1_24(self): """ 1 groups of 24 teams """ opponents = defaultdict(lambda: []) - homeGames = defaultdict(lambda:[]) - awayGames = defaultdict(lambda:[]) + homeGames = defaultdict(lambda: []) + awayGames = defaultdict(lambda: []) for i, g in enumerate(self.groups): - left_group = self.groups[i-1] - right_group = self.groups[(i+1) % len(self.groups)] + left_group = self.groups[i - 1] + right_group = self.groups[(i + 1) % len(self.groups)] for p in self.pots: other_pots = [k for k in self.pots if k != p] for l in other_pots: @@ -786,95 +942,93 @@ class Draw_Simulator: return opponents, homeGames, awayGames - def groups_1_24_stephan(self): """ 1 groups of 24 teams """ opponents = defaultdict(lambda: []) - homeGames = defaultdict(lambda:[]) - awayGames = defaultdict(lambda:[]) + homeGames = defaultdict(lambda: []) + awayGames = defaultdict(lambda: []) for i, g in enumerate(self.groups): - left_group = self.groups[i-1] - right_group = self.groups[(i+1) % len(self.groups)] + left_group = self.groups[i - 1] + right_group = self.groups[(i + 1) % len(self.groups)] for p in self.pots: other_pots = [k for k in self.pots if k != p] for l in other_pots: opponents[g, p].append((g, l)) - if p == "A" and l in ['B', 'C']: + if p == "A" and l in ["B", "C"]: opponents[g, p].append((right_group, l)) awayGames[g, p].append((g, l)) homeGames[g, p].append((right_group, l)) - elif p == "A" and l in ['D']: + elif p == "A" and l in ["D"]: opponents[g, p].append((left_group, l)) homeGames[g, p].append((g, l)) awayGames[g, p].append((left_group, l)) - elif p == "B" and l in ['C', 'D']: + elif p == "B" and l in ["C", "D"]: opponents[g, p].append((right_group, l)) awayGames[g, p].append((g, l)) homeGames[g, p].append((right_group, l)) - elif p == "B" and l in ['A']: + elif p == "B" and l in ["A"]: opponents[g, p].append((left_group, l)) awayGames[g, p].append((left_group, l)) homeGames[g, p].append((g, l)) - elif p == "C" and l in ['D']: + elif p == "C" and l in ["D"]: opponents[g, p].append((right_group, l)) awayGames[g, p].append((g, l)) homeGames[g, p].append((right_group, l)) - elif p == "C" and l in ['A', 'B']: + elif p == "C" and l in ["A", "B"]: opponents[g, p].append((left_group, l)) awayGames[g, p].append((left_group, l)) homeGames[g, p].append((g, l)) - elif p == "D" and l in ['A']: + elif p == "D" and l in ["A"]: opponents[g, p].append((right_group, l)) homeGames[g, p].append((right_group, l)) awayGames[g, p].append((g, l)) - elif p == "D" and l in ['B', 'C']: + elif p == "D" and l in ["B", "C"]: opponents[g, p].append((left_group, l)) awayGames[g, p].append((left_group, l)) homeGames[g, p].append((g, l)) return opponents, homeGames, awayGames - def check_feasibility(self, fixed_groups, nSim): model_time = time.time() - sol_dict = { - g: {b: None for b in self.pots} for g in self.groups - } + sol_dict = {g: {b: None for b in self.pots} for g in self.groups} - if self.algorithm == 'SAT': + if self.algorithm == "SAT": model_sat = cp_model.CpModel() x_sat = {} for g in self.groups: for t in self.teams: - t_id = t['id'] - x_sat[t_id, g] = model_sat.NewBoolVar(f'var_{t_id}_{g}') + t_id = t["id"] + x_sat[t_id, g] = model_sat.NewBoolVar(f"var_{t_id}_{g}") # one group for each team for t in self.teams: - model_sat.AddExactlyOne(x_sat[t['id'], g] for g in self.groups) + model_sat.AddExactlyOne(x_sat[t["id"], g] for g in self.groups) # one team from each pot for g in self.groups: for p in self.pots: - model_sat.AddExactlyOne(x_sat[t['id'], g] - for t in self.teams if t['pot'] == p) + model_sat.AddExactlyOne( + x_sat[t["id"], g] for t in self.teams if t["pot"] == p + ) # no country conflicts for c in self.countries: # print(c) for i, t1 in enumerate(self.teams_by_country[c]): - for t2 in self.teams_by_country[c][i+1:]: + for t2 in self.teams_by_country[c][i + 1 :]: for (g1, p1), other_games in self.opponents.items(): - if p1 == t1['pot']: - for (g2, p2) in other_games: - if p2 == t2['pot']: + if p1 == t1["pot"]: + for g2, p2 in other_games: + if p2 == t2["pot"]: model_sat.AddAtMostOne( - x_sat[t1['id'], g1], x_sat[t2['id'], g2]) + x_sat[t1["id"], g1], x_sat[t2["id"], g2] + ) # add fixations nFixed = 0 @@ -882,41 +1036,44 @@ class Draw_Simulator: for p in self.pots: if fixed_groups[g][p]: nFixed += 1 - model_sat.Add(x_sat[fixed_groups[g][p]['id'], g] >= 1) + model_sat.Add(x_sat[fixed_groups[g][p]["id"], g] >= 1) - - if self.algorithm == 'MIP': - model_mip = LpProblem( - "Xpress", LpMinimize) + if self.algorithm == "MIP": + model_mip = LpProblem("Xpress", LpMinimize) x_mip = {} for g in self.groups: for t in self.teams: - t_id = t['id'] - x_mip[t_id, g] = LpVariable(f'var_{t_id}_{g}', - lowBound=0, upBound=1, cat=LpContinuous) + t_id = t["id"] + x_mip[t_id, g] = LpVariable( + f"var_{t_id}_{g}", lowBound=0, upBound=1, cat=LpContinuous + ) # one group for each team for t in self.teams: - model_mip += lpSum([x_mip[t['id'], g] for g in self.groups]) == 1 + model_mip += lpSum([x_mip[t["id"], g] for g in self.groups]) == 1 # one team from each pot for g in self.groups: for p in self.pots: - model_mip += lpSum([x_mip[t['id'], g] - for t in self.teams if t['pot'] == p]) == 1 + model_mip += ( + lpSum([x_mip[t["id"], g] for t in self.teams if t["pot"] == p]) + == 1 + ) # no country conflicts for c in self.countries: # print(c) for i, t1 in enumerate(self.teams_by_country[c]): - for t2 in self.teams_by_country[c][i+1:]: + for t2 in self.teams_by_country[c][i + 1 :]: for (g1, p1), other_games in self.opponents.items(): - if p1 == t1['pot']: - for (g2, p2) in other_games: - if p2 == t2['pot']: - model_mip += x_mip[t1['id'], - g1] + x_mip[t2['id'], g2] <= 1 + if p1 == t1["pot"]: + for g2, p2 in other_games: + if p2 == t2["pot"]: + model_mip += ( + x_mip[t1["id"], g1] + x_mip[t2["id"], g2] + <= 1 + ) # add fixations nFixed = 0 @@ -924,71 +1081,87 @@ class Draw_Simulator: for p in self.pots: if fixed_groups[g][p]: nFixed += 1 - model_mip += x_mip[fixed_groups[g][p]['id'], g] >= 1 + model_mip += x_mip[fixed_groups[g][p]["id"], g] >= 1 model_mip += lpSum([x_mip[key] for key in x_mip.keys()]) - - if self.algorithm == 'XP': - model_xp = xp.problem(name='Xpress', sense=xp.minimize) + if self.algorithm == "XP": + model_xp = xp.problem(name="Xpress", sense=xp.minimize) x_xp = {} for g in self.groups: for t in self.teams: - t_id = t['id'] + t_id = t["id"] x_xp[t_id, g] = xp.var(ub=10, vartype=xp.integer) model_xp.addVariable(x_xp) # one group for each team for t in self.teams: - model_xp.addConstraint(xp.Sum([x_xp[t['id'], g] for g in self.groups]) == 1) + model_xp.addConstraint( + xp.Sum([x_xp[t["id"], g] for g in self.groups]) == 1 + ) # one team from each pot for g in self.groups: for p in self.pots: model_xp.addConstraint( - xp.Sum([x_xp[t['id'], g] for t in self.teams if t['pot'] == p]) == 1) + xp.Sum([x_xp[t["id"], g] for t in self.teams if t["pot"] == p]) + == 1 + ) # no country conflicts for c in self.countries: for i, t1 in enumerate(self.teams_by_country[c]): - for t2 in self.teams_by_country[c][i+1:]: + for t2 in self.teams_by_country[c][i + 1 :]: for (g1, p1), other_games in self.opponents.items(): - if p1 == t1['pot']: - for (g2, p2) in other_games: - if p2 == t2['pot']: + if p1 == t1["pot"]: + for g2, p2 in other_games: + if p2 == t2["pot"]: model_xp.addConstraint( - x_xp[t1['id'], g1] + x_xp[t2['id'], g2] <= 1) - + x_xp[t1["id"], g1] + x_xp[t2["id"], g2] <= 1 + ) + # no more than 2 teams from same country in one group - for c in self.countries: - for g in self.groups: - model_xp.addConstraint( - xp.Sum([x_xp[t['id'], g] for t in self.teams if t['country'] == c]) <= 2) - - - if self.chess: - model_xp.addConstraint(xp.Sum(x_xp[t,g] for t in self.red_teams for g in self.blue_groups) <= 0) - model_xp.addConstraint(xp.Sum(x_xp[t,g] for t in self.blue_teams for g in self.red_groups) <= 0) - - - - - # do not play other countries more than 3 times - # for t1 in self.teams: - # for c in ['Finland']: - # for (g1, p1), awayGames in self.awayGames.items(): - # if p1 == t1['pot']: + # for c in self.countries: + # for g in self.groups: + # model_xp.addConstraint( + # xp.Sum( + # [x_xp[t["id"], g] for t in self.teams if t["country"] == c] + # ) + # <= 2 + # ) + + if self.chess: + # print("BLUE",self.blue_groups) + model_xp.addConstraint( + xp.Sum(x_xp[t, g] for t in self.red_teams for g in self.blue_groups) + <= 0 + ) + # print("RED",self.red_groups) + model_xp.addConstraint( + xp.Sum(x_xp[t, g] for t in self.blue_teams for g in self.red_groups) + <= 0 + ) + + # do not play other countries more than 2 times + if self.opt_param == "max_2": + for t1 in self.teams: + for c in self.countries: + for (g1, p1), opponents in self.opponents.items(): + if p1 == t1['pot']: + model_xp.addConstraint( + xp.Sum([x_xp[t2['id'], g2] for (g2, p2) in opponents for t2 in self.teams if p2 == t2['pot'] and t2['country'] == c]) <= 2) + + + # print(t1['name'],t1['country'],t1['pot'],[t2['name'] for (g2, p2) in awayGames for t2 in self.teams if p2 == t2['pot'] and t2['country'] == c]) + # for (g2, p2) in awayGames: + # if p2 == t2['pot']: # model_xp.addConstraint( - # xp.Sum([x_xp[t2['id'], g2] for (g2, p2) in awayGames for t2 in self.teams if p2 == t2['pot'] and t2['country'] == c]) <= 3) - # print(t1['name'],t1['country'],t1['pot'],[t2['name'] for (g2, p2) in awayGames for t2 in self.teams if p2 == t2['pot'] and t2['country'] == c]) - # for (g2, p2) in awayGames: - # if p2 == t2['pot']: - # model_xp.addConstraint( - # x_xp[t1['id'], g1] + x_xp[t2['id'], g2] <= 1) - # # model_xp.addConstraint( - # xp.Sum([x_xp[t['id'], g] for t in self.teams if t['country'] == c]) <= 2) + # x_xp[t1['id'], g1] + x_xp[t2['id'], g2] <= 1) + + # # model_xp.addConstraint( + # xp.Sum([x_xp[t['id'], g] for t in self.teams if t['country'] == c]) <= 2) # for t in self.teams: # for c in ['Finland']: # for t2 in self.teams_by_country[c]: @@ -1006,19 +1179,19 @@ class Draw_Simulator: for p in self.pots: if fixed_groups[g][p]: nFixed += 1 - model_xp.addConstraint(x_xp[fixed_groups[g][p]['id'], g] >= 1) + model_xp.addConstraint(x_xp[fixed_groups[g][p]["id"], g] >= 1) + # print(f"\tFixed {fixed_groups[g][p]['name']}, {fixed_groups[g][p]['country']} in group {g}") - model_xp.setObjective(xp.Sum([x_xp[key] - for key in x_xp.keys()]), sense=xp.minimize) + model_xp.setObjective( + xp.Sum([x_xp[key] for key in x_xp.keys()]), sense=xp.minimize + ) - - - if self.algorithm == 'SAT': + if self.algorithm == "SAT": solver = cp_model.CpSolver() start_time = time.time() status = solver.Solve(model_sat) - comp_time = time.time()-start_time - model_time = time.time()-model_time-comp_time + comp_time = time.time() - start_time + model_time = time.time() - model_time - comp_time # solver.parameters.enumerate_all_solutions = True # solver.parameters.log_search_progress = True @@ -1027,7 +1200,7 @@ class Draw_Simulator: for g in self.groups: for p in self.pots: for t in self.basepots[p]: - if solver.BooleanValue(x_sat[t['id'], g]): + if solver.BooleanValue(x_sat[t["id"], g]): sol_dict[g][p] = t self.html_solution(nSim, sol_dict, fixed_groups) return True, comp_time, model_time, sol_dict @@ -1038,15 +1211,15 @@ class Draw_Simulator: # f.write(model_mip.__repr__()) start_time = time.time() model_mip.solve(PULP_CBC_CMD(msg=0)) - comp_time = time.time()-start_time - model_time = time.time()-model_time-comp_time + comp_time = time.time() - start_time + model_time = time.time() - model_time - comp_time if model_mip.status == 1: if self.html_output: for g in self.groups: for p in self.pots: for t in self.basepots[p]: - if x_mip[t['id'], g].value() > 0: + if x_mip[t["id"], g].value() > 0: sol_dict[g][p] = t self.html_solution(nSim, sol_dict, fixed_groups) return True, comp_time, model_time, sol_dict @@ -1057,50 +1230,46 @@ class Draw_Simulator: # f.write(model_mip.__repr__()) start_time = time.time() model_xp.solve() - comp_time = time.time()-start_time - model_time = time.time()-model_time-comp_time + comp_time = time.time() - start_time + model_time = time.time() - model_time - comp_time + + # print("STATUS",model_xp.getProbStatus(),model_xp.getProbStatusString()) if model_xp.getProbStatus() == 6: if self.html_output: for g in self.groups: for p in self.pots: for t in self.basepots[p]: - if model_xp.getSolution(x_xp[t['id'], g]) > 0: + if model_xp.getSolution(x_xp[t["id"], g]) > 0: sol_dict[g][p] = t self.html_solution(nSim, sol_dict, fixed_groups) - + return True, comp_time, model_time, sol_dict else: return False, comp_time, model_time, {} + def team_travel(self, team, sol): - def team_travel(self,team,sol): - - return 0 - - def team_coefficients(self,team,sol): + def team_coefficients(self, team, sol): return 0 - - def simulate(self, nTimes): tt = time.time() if nTimes < 1: return None tmp_stats = defaultdict(lambda: {}) - - for n in range(nTimes): - print(f"{self.opponent_func.__name__} - Simulation {n} - in {time.time()-tt}") - ttt =time.time() + for n in range(nTimes): + print( + f"{self.opponent_func.__name__} - {self.opt_param} - Simulation {n} - in {time.time()-tt}" + ) + ttt = time.time() - sol_dict = { - g: {b: None for b in self.pots} for g in self.groups - } + sol_dict = {g: {b: None for b in self.pots} for g in self.groups} pots = copy.deepcopy(self.basepots) infeasible = False @@ -1117,28 +1286,40 @@ class Draw_Simulator: pot = pots[p] random.shuffle(pot) - while (pot): + while pot: r = random.choice(pot) for g in self.groups: if sol_dict[g][p]: continue else: + # print(f"Trying to add {r['name']} to group {g}") sol_dict[g][p] = r feasible, comptime, modeltime, _ = self.check_feasibility( - sol_dict, nSim=n) + sol_dict, nSim=n + ) + # print("\tFeasible:", feasible) + total_computations += 1 total_time += comptime total_model_time += modeltime if feasible: feasible = True if self.chess and not self.blue_groups: - if r['id'] in self.blue_teams: - self.blue_groups = [1,3,5] if g % 2 == 1 else [2,4,6] - self.red_groups = [2,4,6] if g % 2 == 1 else [1,3,5] - elif r['id'] in self.red_teams: - self.blue_groups = [2,4,6] if g % 2 == 1 else [1,3,5] - self.red_groups = [1,3,5] if g % 2 == 1 else [2,4,6] + if r["id"] in self.blue_teams: + self.blue_groups = ( + [1, 3, 5] if g % 2 == 1 else [2, 4, 6] + ) + self.red_groups = ( + [2, 4, 6] if g % 2 == 1 else [1, 3, 5] + ) + elif r["id"] in self.red_teams: + self.blue_groups = ( + [2, 4, 6] if g % 2 == 1 else [1, 3, 5] + ) + self.red_groups = ( + [1, 3, 5] if g % 2 == 1 else [2, 4, 6] + ) break else: # print("\tCONFLICT: skipping group {} for team {}".format(g,r)) @@ -1151,168 +1332,206 @@ class Draw_Simulator: pot.remove(r) - - travel = defaultdict(lambda:0) - coefficients = defaultdict(lambda:0) - visited_countries = defaultdict(lambda:set({})) - visited_finland = defaultdict(lambda:0) - travel_finland = defaultdict(lambda:0) + travel = defaultdict(lambda: 0) + coefficients = defaultdict(lambda: 0) + visited_countries = defaultdict(lambda: set({})) + visited_finland = defaultdict(lambda: 0) + travel_finland = defaultdict(lambda: 0) if not infeasible: for g in self.groups: for p in self.pots: - t1 = sol_dict[g][p] + t1 = sol_dict[g][p] for ag in self.awayGames[g, p]: - t2 = sol_dict[ag[0]][ag[1]] - travel[t1['id']] += self.distance_matrix[t1['id'],t2['id']] - if t2['country'] == 'Switzerland': - travel_finland[t1['id']] += 1 - for op in self.opponents[g,p]: + t2 = sol_dict[ag[0]][ag[1]] + travel[t1["id"]] += self.distance_matrix[t1["id"], t2["id"]] + if t2["country"] == "Switzerland": + travel_finland[t1["id"]] += 1 + for op in self.opponents[g, p]: t2 = sol_dict[op[0]][op[1]] - if self.opponent_func.__name__ == 'groups_6_4': - coefficients[t1['id']] += 2*(abs(t1['coeff']-t2['coeff'])) + if self.opponent_func.__name__ == "groups_6_4": + coefficients[t1["id"]] += 2 * ( + abs(t1["coeff"] - t2["coeff"]) + ) else: - coefficients[t1['id']] += abs(t1['coeff']-t2['coeff']) - visited_countries[t1['id']].add(t2['country']) - if t2['country'] == 'Switzerland': - visited_finland[t1['id']] += 1 - + coefficients[t1["id"]] += abs(t1["coeff"] - t2["coeff"]) + visited_countries[t1["id"]].add(t2["country"]) + if t2["country"] == "Switzerland": + visited_finland[t1["id"]] += 1 + else: + print("INFEASIBLE") + exit() blockings, breaks = self.create_schedule(sol_dict, n) # blockings = defaultdict(lambda:0) # breaks = defaultdict(lambda:0) - - - - tmp_stats[n] = { - 'conflicts': conflicts, - 'infeasible': infeasible, - 'comptime': total_time, - 'modeltime': total_model_time, - 'total_computations': total_computations, - 'travel':travel, - 'coefficients':coefficients, - 'visited_countries':{t['id']:len(visited_countries[t['id']]) for t in self.teams}, - 'blockings':blockings, - 'breaks':breaks, - 'visited_finland':visited_finland, - 'travel_finland':travel_finland, - } - - with open(f'json/{self.opponent_func.__name__}_{n}.json', 'w') as f: - json.dump(tmp_stats, f, cls=NumpyEncoder) - - nInfeasible = sum(s['infeasible'] for s in tmp_stats.values()) > 0 - nComputation = sum(s['total_computations'] for s in tmp_stats.values()) - tComputation = sum(s['comptime'] for s in tmp_stats.values()) + tmp_stats[n] = { + "conflicts": conflicts, + "infeasible": infeasible, + "comptime": total_time, + "modeltime": total_model_time, + "total_computations": total_computations, + "travel": travel, + "coefficients": coefficients, + "visited_countries": { + t["id"]: len(visited_countries[t["id"]]) for t in self.teams + }, + "blockings": blockings, + "breaks": breaks, + "visited_finland": visited_finland, + "travel_finland": travel_finland, + } + + with open(f"json/{self.opponent_func.__name__}_{n}.json", "w") as f: + json.dump(tmp_stats, f, cls=NumpyEncoder) + + nInfeasible = sum(s["infeasible"] for s in tmp_stats.values()) > 0 + nComputation = sum(s["total_computations"] for s in tmp_stats.values()) + tComputation = sum(s["comptime"] for s in tmp_stats.values()) conflicts_dict = { - p: round(sum(s['conflicts'][p] for s in tmp_stats.values())/nTimes,2) + p: round(sum(s["conflicts"][p] for s in tmp_stats.values()) / nTimes, 2) for p in self.pots } - conflicts_dict['total'] = round(sum(conflicts_dict[p] for p in self.pots),2) + conflicts_dict["total"] = round(sum(conflicts_dict[p] for p in self.pots), 2) travel_stats = { - t['id']: { - 'mean': round(np.mean([s['travel'][t['id']] for s in tmp_stats.values()]),2), - 'std': round(np.std([s['travel'][t['id']] for s in tmp_stats.values()]),2), - 'var': round(np.var([s['travel'][t['id']] for s in tmp_stats.values()]),2), - } + t["id"]: { + "mean": round( + np.mean([s["travel"][t["id"]] for s in tmp_stats.values()]), 2 + ), + "std": round( + np.std([s["travel"][t["id"]] for s in tmp_stats.values()]), 2 + ), + "var": round( + np.var([s["travel"][t["id"]] for s in tmp_stats.values()]), 2 + ), + } for t in self.teams } - travel_stats['total'] = { - 'mean': round(np.mean([travel_stats[t['id']]['mean'] for t in self.teams]),2), - 'std': round(np.mean([travel_stats[t['id']]['std'] for t in self.teams]),2), - 'var': round(np.mean([travel_stats[t['id']]['var'] for t in self.teams]),2), + travel_stats["total"] = { + "mean": round( + np.mean([travel_stats[t["id"]]["mean"] for t in self.teams]), 2 + ), + "std": round( + np.mean([travel_stats[t["id"]]["std"] for t in self.teams]), 2 + ), + "var": round( + np.mean([travel_stats[t["id"]]["var"] for t in self.teams]), 2 + ), } coefficient_stats = { - t['id']: { - 'mean': round(np.mean([s['coefficients'][t['id']] for s in tmp_stats.values()]),2), - 'std': round(np.std([s['coefficients'][t['id']] for s in tmp_stats.values()]),2), - 'var': round(np.var([s['coefficients'][t['id']] for s in tmp_stats.values()]),2), - } + t["id"]: { + "mean": round( + np.mean([s["coefficients"][t["id"]] for s in tmp_stats.values()]), 2 + ), + "std": round( + np.std([s["coefficients"][t["id"]] for s in tmp_stats.values()]), 2 + ), + "var": round( + np.var([s["coefficients"][t["id"]] for s in tmp_stats.values()]), 2 + ), + } for t in self.teams } - coefficient_stats['total'] = { - 'mean': round(np.mean([coefficient_stats[t['id']]['mean'] for t in self.teams]),2), - 'std': round(np.mean([coefficient_stats[t['id']]['std'] for t in self.teams]),2), - 'var': round(np.mean([coefficient_stats[t['id']]['var'] for t in self.teams]),2), + coefficient_stats["total"] = { + "mean": round( + np.mean([coefficient_stats[t["id"]]["mean"] for t in self.teams]), 2 + ), + "std": round( + np.mean([coefficient_stats[t["id"]]["std"] for t in self.teams]), 2 + ), + "var": round( + np.mean([coefficient_stats[t["id"]]["var"] for t in self.teams]), 2 + ), } visited_countries = { - t['id']: { - 'mean': round(np.mean([s['visited_countries'][t['id']] for s in tmp_stats.values()]),2), - } + t["id"]: { + "mean": round( + np.mean( + [s["visited_countries"][t["id"]] for s in tmp_stats.values()] + ), + 2, + ), + } for t in self.teams } - visited_countries['total'] = { - 'mean': round(np.mean([visited_countries[t['id']]['mean'] for t in self.teams]),2), + visited_countries["total"] = { + "mean": round( + np.mean([visited_countries[t["id"]]["mean"] for t in self.teams]), 2 + ), } - + visited_finland = { - t['id']: { - 'sum': np.sum([1 for s in tmp_stats.values() if s['visited_finland'][t['id']] >= 3]), - } + t["id"]: { + "sum": np.sum( + [ + 1 + for s in tmp_stats.values() + if s["visited_finland"][t["id"]] >= 3 + ] + ), + } for t in self.teams } - visited_finland['total'] = { - 'sum': np.sum([visited_finland[t['id']]['sum'] for t in self.teams]), + visited_finland["total"] = { + "sum": np.sum([visited_finland[t["id"]]["sum"] for t in self.teams]), } - + travel_finland = { - t['id']: { - 'sum': np.sum([1 for s in tmp_stats.values() if s['travel_finland'][t['id']] >= 3]), - } + t["id"]: { + "sum": np.sum( + [1 for s in tmp_stats.values() if s["travel_finland"][t["id"]] >= 3] + ), + } for t in self.teams } - travel_finland['total'] = { - 'sum': np.sum([travel_finland[t['id']]['sum'] for t in self.teams]), + travel_finland["total"] = { + "sum": np.sum([travel_finland[t["id"]]["sum"] for t in self.teams]), } - - + blockings = { - t['id']: { - 'mean': round(np.mean([s['blockings'][t['id']] for s in tmp_stats.values()]),3), - } + t["id"]: { + "mean": round( + np.mean([s["blockings"][t["id"]] for s in tmp_stats.values()]), 3 + ), + } for t in self.teams } - blockings['total'] = { - 'sum': round(np.sum([blockings[t['id']]['mean'] for t in self.teams]),3), + blockings["total"] = { + "sum": round(np.sum([blockings[t["id"]]["mean"] for t in self.teams]), 3), } - + breaks = { - t['id']: { - 'mean': round(np.mean([s['breaks'][t['id']] for s in tmp_stats.values()])*0.5,3), - } + t["id"]: { + "mean": round( + np.mean([s["breaks"][t["id"]] for s in tmp_stats.values()]) * 0.5, 3 + ), + } for t in self.teams } - breaks['total'] = { - 'sum': round(np.sum([breaks[t['id']]['mean'] for t in self.teams]),3), + breaks["total"] = { + "sum": round(np.sum([breaks[t["id"]]["mean"] for t in self.teams]), 3), } - - + stats = { - 'nInfeasible':nInfeasible, - 'nComputation':nComputation, - 'tComputation':tComputation, - 'conflicts_dict':conflicts_dict, - 'conflicts_dict':conflicts_dict, - 'travel_stats':travel_stats, - 'coefficient_stats':coefficient_stats, - 'visited_countries':visited_countries, - 'visited_finland':visited_finland, - 'travel_finland':travel_finland, - 'blockings':blockings, - 'breaks':breaks, + "nInfeasible": nInfeasible, + "nComputation": nComputation, + "tComputation": tComputation, + "conflicts_dict": conflicts_dict, + "conflicts_dict": conflicts_dict, + "travel_stats": travel_stats, + "coefficient_stats": coefficient_stats, + "visited_countries": visited_countries, + "visited_finland": visited_finland, + "travel_finland": travel_finland, + "blockings": blockings, + "breaks": breaks, } - - - - + return stats - - def create_schedule(self, sol_dict, nSim): - + # for g in self.groups: # for p in self.pots: # print(g,p,sol_dict[g][p]['name'],sol_dict[g][p]['country']) @@ -1320,14 +1539,15 @@ class Draw_Simulator: # print("\t",game[0],game[1],sol_dict[game[0]][game[1]]) # for game in self.awayGames[g, p]: # print("\t",game[0],game[1],sol_dict[game[0]][game[1]]) - base_scenario_id = 12098 + base_scenario_id = 13020 base_scenario = Scenario.objects.get(id=base_scenario_id) - - scenario = copy_scenario(base_scenario,f" - {self.opponent_func.__name__} - {nSim}") + + scenario = copy_scenario( + base_scenario, f" - {self.opponent_func.__name__} - {self.opt_param} - {nSim}" + ) # scenario.base_scenario = base_scenario scenario.save() - - + GameRequirement.objects.filter(scenario=scenario).delete() games = [] for g in self.groups: @@ -1335,38 +1555,48 @@ class Draw_Simulator: # print(g,p,sol_dict[g][p]['name'],sol_dict[g][p]['country']) for game in self.homeGames[g, p]: # print("\t",game[0],game[1],sol_dict[game[0]][game[1]]) - games.append(GameRequirement(number=1, scenario=scenario, team1=Team.objects.get(id=sol_dict[g][p]['id']), team2=Team.objects.get(id=sol_dict[game[0]][game[1]]['id']))) + games.append( + GameRequirement( + number=1, + scenario=scenario, + team1=Team.objects.get(id=sol_dict[g][p]["id"]), + team2=Team.objects.get(id=sol_dict[game[0]][game[1]]["id"]), + ) + ) # for game in self.awayGames[g, p]: # print("\t",game[0],game[1],sol_dict[game[0]][game[1]]) # games.append(GameRequirement(number=1, scenario=scenario, team1=Team.objects.get(id=sol_dict[game[0]][game[1]]['id']), team2=Team.objects.get(id=sol_dict[g][p]['id']))) GameRequirement.objects.bulk_create(games) - s2 = scenario.id - user_name = 'md' + user_name = "md" user_is_staff = True - runMode = 'New' + runMode = "New" localsearch_time = 0 - RUN_ENV = 'celery' - SOLVER = 'xpress' + RUN_ENV = "celery" + SOLVER = "xpress" - sol = optimize(task=None, s2=s2, user_name=user_name, user_is_staff=user_is_staff, runMode=runMode, localsearch_time=localsearch_time, RUN_ENV=RUN_ENV, solver=SOLVER) - - - kpis = Availabilities(scenario.id,showSolution=1) - - blockings = defaultdict(lambda:0) - breaks = defaultdict(lambda:0) - for v in kpis['violations']: + sol = optimize( + task=None, + s2=s2, + user_name=user_name, + user_is_staff=user_is_staff, + runMode=runMode, + localsearch_time=localsearch_time, + RUN_ENV=RUN_ENV, + solver=SOLVER, + ) + + kpis = Availabilities(scenario.id, showSolution=1) + + blockings = defaultdict(lambda: 0) + breaks = defaultdict(lambda: 0) + for v in kpis["violations"]: blockings[v[0].id] += 1 - for b in kpis['missingBreaks']: + for b in kpis["missingBreaks"]: breaks[b] += 1 - - - return blockings, breaks - - + return blockings, breaks def html_solution(self, nSim, sol_dict, fixed_groups): @@ -1383,11 +1613,11 @@ class Draw_Simulator: sol += "" for g in self.groups: if g in self.blue_groups: - color = 'blue' + color = "blue" elif g in self.red_groups: - color = 'red' + color = "red" else: - color = 'white' + color = "white" sol += f"{g}" sol += "" sol += "\n" @@ -1397,19 +1627,19 @@ class Draw_Simulator: sol += f"{p}" for g in self.groups: if fixed_groups[g][p]: - color = 'lightgreen' + color = "lightgreen" nFixed += 1 else: - color = 'lightyellow' - if sol_dict[g][p]['id'] in self.blue_teams: - text_color = 'blue' - elif sol_dict[g][p]['id'] in self.red_teams: - text_color = 'red' + color = "lightyellow" + if sol_dict[g][p]["id"] in self.blue_teams: + text_color = "blue" + elif sol_dict[g][p]["id"] in self.red_teams: + text_color = "red" else: - text_color = 'black' - tpot = sol_dict[g][p]['pot'] - tname = sol_dict[g][p]['name'] - tcountry = sol_dict[g][p]['country'] + text_color = "black" + tpot = sol_dict[g][p]["pot"] + tname = sol_dict[g][p]["name"] + tcountry = sol_dict[g][p]["country"] sol += f"({tpot}){tname}({tcountry})" sol += "" sol += "\n" @@ -1417,23 +1647,26 @@ class Draw_Simulator: sol += "


\n" for (g1, p1), other_games in self.opponents.items(): - for (g2, p2) in other_games: - tpot = sol_dict[g1][p1]['pot'] - tname = sol_dict[g1][p1]['name'] - tcountry = sol_dict[g1][p1]['country'] - sol += f'({tpot}){tname}({tcountry})' + for g2, p2 in other_games: + tpot = sol_dict[g1][p1]["pot"] + tname = sol_dict[g1][p1]["name"] + tcountry = sol_dict[g1][p1]["country"] + sol += f"({tpot}){tname}({tcountry})" sol += " vs " - tpot = sol_dict[g2][p2]['pot'] - tname = sol_dict[g2][p2]['name'] - tcountry = sol_dict[g2][p2]['country'] - sol += f'({tpot}){tname}({tcountry})' + tpot = sol_dict[g2][p2]["pot"] + tname = sol_dict[g2][p2]["name"] + tcountry = sol_dict[g2][p2]["country"] + sol += f"({tpot}){tname}({tcountry})" sol += "
" sol += "
" sol += "
" - with open(f'html/{self.algorithm}_{self.opponent_func.__name__}_{nSim}_{nFixed}_sol.html', 'w') as f: - f.write(sol) - - + + if nFixed == 24: + with open( + f"html/{self.algorithm}_{self.opponent_func.__name__}_{self.opt_param}_{nSim}_{nFixed}_{self.suffix}_sol.html", + "w", + ) as f: + f.write(sol) # %% @@ -1443,14 +1676,15 @@ class Draw_Simulator: # nSim = 10 - # %% funcs = [ # Draw_Simulator.groups_6_4, # Draw_Simulator.groups_3_8, - Draw_Simulator.groups_1_24_martin, - Draw_Simulator.groups_1_24_martin_chess, + (Draw_Simulator.groups_1_24, "free"), + (Draw_Simulator.groups_1_24_chess, "free"), + # (Draw_Simulator.groups_1_24, "max_2"), + # (Draw_Simulator.groups_1_24_chess, "max_2"), # Draw_Simulator.groups_2_12_martin, # Draw_Simulator.groups_2_12_stephan, # Draw_Simulator.groups_1_24_stephan, @@ -1458,19 +1692,38 @@ funcs = [ ] -scenario_id = 12098 +scenario_id = 13020 scenario = Scenario.objects.get(id=scenario_id) # Scenario.objects.filter(base_scenario=scenario).delete() +Scenario.objects.filter(season=scenario.season).exclude(id=scenario_id).delete() + +filename = "worst_case" + stats = {} -for func in funcs: - if func == Draw_Simulator.groups_1_24_martin_chess: - simulator = Draw_Simulator(algorithm='XP', opponent_func = func, html_output=True,use_db=True,use_chess=True) +for (func,opt_param) in funcs: + if func == Draw_Simulator.groups_1_24_chess: + simulator = Draw_Simulator( + algorithm="XP", + opponent_func=func, + html_output=True, + use_db=True, + use_chess=True, + suffix=filename, + opt_param=opt_param, + scenario_id=scenario_id, + + ) else: - simulator = Draw_Simulator(algorithm='XP', opponent_func = func, html_output=True,use_db=True) + simulator = Draw_Simulator( + algorithm="XP", opponent_func=func, html_output=True, use_db=True, + suffix=filename, + opt_param=opt_param, + scenario_id=scenario_id, + ) nSim = 100 - stats[func.__name__] = simulator.simulate(nSim) + stats[(func.__name__,opt_param)] = simulator.simulate(nSim) # %% @@ -1498,7 +1751,7 @@ sol += "" for p in simulator.pots: sol += f"{p}" for t in simulator.teams: - sol+= f"{t['name']} ({t['country']})" + sol += f"{t['name']} ({t['country']})" sol += "" sol += "" sol += "Cfl." @@ -1531,74 +1784,71 @@ for t in simulator.teams: sol += "" sol += "\n" sol += "\n" -for func in funcs: +for (func,opt_param) in funcs: sol += "" - sol += f"{func.__name__}" + sol += f"{func.__name__} - {opt_param} " for p in simulator.pots: - sol += f"{stats[func.__name__]['conflicts_dict'][p]}" - sol += f"{stats[func.__name__]['conflicts_dict']['total']}" - ttmean = stats[func.__name__]['travel_stats']['total']['mean'] - ttstd = stats[func.__name__]['travel_stats']['total']['std'] - ctmean = stats[func.__name__]['coefficient_stats']['total']['mean'] - ctstd = stats[func.__name__]['coefficient_stats']['total']['std'] - sol += f"{stats[func.__name__]['travel_stats']['total']['mean']}" - sol += f"{stats[func.__name__]['travel_stats']['total']['std']}" - sol += f"{stats[func.__name__]['coefficient_stats']['total']['mean']}" - sol += f"{stats[func.__name__]['coefficient_stats']['total']['std']}" - sol += f"{stats[func.__name__]['blockings']['total']['sum']}" - sol += f"{stats[func.__name__]['breaks']['total']['sum']}" - sol += f"{stats[func.__name__]['visited_countries']['total']['mean']}" - sol += f"{stats[func.__name__]['visited_finland']['total']['sum']}" - sol += f"{stats[func.__name__]['travel_finland']['total']['sum']}" + sol += f"{stats[(func.__name__,opt_param)]['conflicts_dict'][p]}" + sol += f"{stats[(func.__name__,opt_param)]['conflicts_dict']['total']}" + ttmean = stats[(func.__name__,opt_param)]["travel_stats"]["total"]["mean"] + ttstd = stats[(func.__name__,opt_param)]["travel_stats"]["total"]["std"] + ctmean = stats[(func.__name__,opt_param)]["coefficient_stats"]["total"]["mean"] + ctstd = stats[(func.__name__,opt_param)]["coefficient_stats"]["total"]["std"] + sol += f"{stats[(func.__name__,opt_param)]['travel_stats']['total']['mean']}" + sol += f"{stats[(func.__name__,opt_param)]['travel_stats']['total']['std']}" + sol += f"{stats[(func.__name__,opt_param)]['coefficient_stats']['total']['mean']}" + sol += f"{stats[(func.__name__,opt_param)]['coefficient_stats']['total']['std']}" + sol += f"{stats[(func.__name__,opt_param)]['blockings']['total']['sum']}" + sol += f"{stats[(func.__name__,opt_param)]['breaks']['total']['sum']}" + sol += f"{stats[(func.__name__,opt_param)]['visited_countries']['total']['mean']}" + sol += f"{stats[(func.__name__,opt_param)]['visited_finland']['total']['sum']}" + sol += f"{stats[(func.__name__,opt_param)]['travel_finland']['total']['sum']}" for t in simulator.teams: - tmean = stats[func.__name__]['travel_stats'][t['id']]['mean'] - tstd = stats[func.__name__]['travel_stats'][t['id']]['std'] - cmean = stats[func.__name__]['coefficient_stats'][t['id']]['mean'] - cstd = stats[func.__name__]['coefficient_stats'][t['id']]['std'] - blmean = stats[func.__name__]['blockings'][t['id']]['mean'] - brmean = stats[func.__name__]['breaks'][t['id']]['mean'] - visited = stats[func.__name__]['visited_countries'][t['id']]['mean'] - visited_finland = stats[func.__name__]['visited_finland'][t['id']]['sum'] - travel_finland = stats[func.__name__]['travel_finland'][t['id']]['sum'] - color = Draw_Simulator.heatmap_color_for(abs(tmean-ttmean)/ttmean) + tmean = stats[(func.__name__,opt_param)]["travel_stats"][t["id"]]["mean"] + tstd = stats[(func.__name__,opt_param)]["travel_stats"][t["id"]]["std"] + cmean = stats[(func.__name__,opt_param)]["coefficient_stats"][t["id"]]["mean"] + cstd = stats[(func.__name__,opt_param)]["coefficient_stats"][t["id"]]["std"] + blmean = stats[(func.__name__,opt_param)]["blockings"][t["id"]]["mean"] + brmean = stats[(func.__name__,opt_param)]["breaks"][t["id"]]["mean"] + visited = stats[(func.__name__,opt_param)]["visited_countries"][t["id"]]["mean"] + visited_finland = stats[(func.__name__,opt_param)]["visited_finland"][t["id"]]["sum"] + travel_finland = stats[(func.__name__,opt_param)]["travel_finland"][t["id"]]["sum"] + color = Draw_Simulator.heatmap_color_for(abs(tmean - ttmean) / ttmean) sol += f"{tmean}" - color = Draw_Simulator.heatmap_color_for(abs(tstd-ttstd)/ttstd) + color = Draw_Simulator.heatmap_color_for(abs(tstd - ttstd) / ttstd) sol += f"{tstd}" - color = Draw_Simulator.heatmap_color_for(abs(cmean-ctmean)/ctmean) + color = Draw_Simulator.heatmap_color_for(abs(cmean - ctmean) / ctmean) sol += f"{cmean}" - color = Draw_Simulator.heatmap_color_for(abs(cstd-ctstd)/ctstd) + color = Draw_Simulator.heatmap_color_for(abs(cstd - ctstd) / ctstd) sol += f"{cstd}" sol += f"{blmean}" sol += f"{brmean}" sol += f"{visited}" sol += f"{visited_finland}" sol += f"{travel_finland}" - + sol += "" sol += "\n" sol += "\n" -with open(f'stats.html', 'w') as f: + + +with open(f"stats_{filename}.html", "w") as f: f.write(sol) - - - - - # %% # %% -with open(f'color.html', 'w') as f: - table = f"" - for i in range(1,11): - color = Draw_Simulator.heatmap_color_for(i/10) +with open(f"color_{filename}.html", "w") as f: + table = f"
" + for i in range(1, 11): + color = Draw_Simulator.heatmap_color_for(i / 10) table += f"" - + table += f"
{color}
" f.write(table)