# %% 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") # XPRESS ENVIRONMENT os.environ['XPRESSDIR'] = "/opt/xpressmp_8.4" os.environ['XPRESS'] = "/opt/xpressmp_8.4/bin" os.environ['LD_LIBRARY_PATH'] = os.environ['XPRESSDIR']+"/lib:"+os.environ['LD_LIBRARY_PATH'] os.environ['DYLD_LIBRARY_PATH'] = os.environ['XPRESSDIR']+"/lib:" os.environ['SHLIB_PATH'] = os.environ['XPRESSDIR']+"/lib:" os.environ['LIBPATH'] = os.environ['XPRESSDIR']+"/lib:" # os.environ['PYTHONPATH'] =os.environ['XPRESSDIR']+"/lib:"+os.environ['PYTHONPATH'] os.environ['PYTHONPATH'] =os.environ['XPRESSDIR']+"/lib:" os.environ['CLASSPATH'] =os.environ['XPRESSDIR']+"/lib/xprs.jar:" os.environ['CLASSPATH'] =os.environ['XPRESSDIR']+"/lib/xprb.jar:"+os.environ['CLASSPATH'] os.environ['CLASSPATH'] =os.environ['XPRESSDIR']+"/lib/xprm.jar:"+os.environ['CLASSPATH'] os.environ['PATH'] =os.environ['XPRESSDIR']+"/bin:"+os.environ['PATH'] from leagues import settings settings.DATABASES['default']['NAME'] = PROJECT_PATH+'/db.sqlite3' import django django.setup() from scheduler.models import * import operator from scheduler.solver.functions import * from common.functions import distanceInKmByGPS import pandas as pd import numpy as np from django.db.models import Count, F, Value from pulp import * def makeIntVar(v): if type(v) != int: v.cat = LpInteger # print ("int var ", v) def setStart(v, vl): if type(v) != int: vl = float(vl) v.start = vl def setLB(v, vl): if type(v) != int: vl = float(vl) v.lowBound = vl # print ("set lb ", v , " = ", vl) def setUB(v, vl): if type(v) != int: vl = float(vl) v.upBound = vl # print ("set ub ", v , " = ", vl) def getVal(v): if type(v) == int: return v else: return v.value() user_is_staff = True runMode = 'New' localsearch_time = 0 solver = '?' s2 = 3 thisScenario = Scenario.objects.get(id=s2) 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} for t1 in teams: for t2 in teams: if t1 != t2: gameCntr[(t1, t2)] += nPhases/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) # %% gmClusters = range(1, nTeams+2) if nPhases > 0 and not thisSeason.useFeatureOpponentMatrix and not specialGameControl: gmClusters = range(1, 2) print("gmClusters", gmClusters) gameClusterTeams = {c: [t for t in teams] for c in gmClusters} gameClusters = [c for c in gameClusterTeams.keys() if len( gameClusterTeams[c]) > 0] biggestGroupSize = max([len(gameClusterTeams[c]) for c in gameClusters]) # %% nPhases = min([gameCntr[(t1, t2)] + gameCntr[(t2, t1)] + undirectedGameCntr[(t1, t2)] for (t1, t2) in realgames]) tripStartHeuristicGroupsize = 1 if thisSeason.tripStartHeuristicGroupsize == "None" else int( thisSeason.tripStartHeuristicGroupsize) defaultGameRepetions = 1 if not mathModelName in ["NHL", "NBA"] else 2 nPhases = max(1, int(nPhases/defaultGameRepetions)) phases = range(nPhases) useBasicGames = nPhases > 0 if not useBasicGames: print('no basic games but biggest group size ', biggestGroupSize, ' in nPhases ', nPhases) nRounds = thisSeason.nRounds rounds = range(1, nRounds+1) # nRoundsPerPhase= 1 # if nPhases>0: nRoundsPerPhase = int(nRounds/nPhases) print('nRounds ', nRounds) print('nPhases ', nPhases) print('nRoundsPerPhase ', nRoundsPerPhase) print('defaultGameRepetions ', defaultGameRepetions) print('tripStartHeuristicGroupsize ', tripStartHeuristicGroupsize) getPhaseOfRound = {r: min(nPhases-1, int((r-1)/nRoundsPerPhase)) for r in rounds} getDaysOfPhase = {p: [] for p in phases} getDays = {r: [] for r in rounds} roundGamesMax = {r: 0 for r in rounds} roundGamesMin = {r: 0 for r in rounds} getDayById = {d['id']: d for d in dayObjects} getDayByDateTime = {} getNiceDayRaw = {d['id']: d['day'] for d in dayObjects} getNiceDay = {d['id']: d['day'] for d in dayObjects} getWeekDay = {d['id']: '' for d in dayObjects} getDateTimeDay = {d['id']: '' for d in dayObjects} getRoundByDay = {d['id']: d['round'] for d in dayObjects if d['round'] > 0} getDayMinGames = {d['id']: d['minGames'] for d in dayObjects if d['round'] > 0} getDayMaxGames = {d['id']: d['maxGames'] for d in dayObjects if d['round'] > 0} getRoundsByDay = {d['id']: [] for d in dayObjects} nDerbies = {d['id']: [d['nDerbies']] for d in dayObjects} roundDays = [] roundDaysMin = {} roundDaysMax = {} wds = {0: 'Mon', 1: 'Tue', 2: 'Wed', 3: 'Thu', 4: 'Fri', 5: 'Sat', 6: 'Sun'} for d in dayObjects: if d['round'] > 0: getRoundsByDay[d['id']].append(d['round']) getDays[d['round']].append(d['id']) roundDays.append((d['round'], d['id'])) roundDaysMin[(d['round'], d['id'])] = d['minGames'] roundDaysMax[(d['round'], d['id'])] = d['maxGames'] roundGamesMax[d['round']] = min( nTeams/2, roundGamesMax[d['round']]+d['maxGames']) roundGamesMin[d['round']] += d['minGames'] ph = getPhaseOfRound[d['round']] getDaysOfPhase[ph].append(d['id']) if d['round2'] > 0: getRoundsByDay[d['id']].append(d['round2']) getDays[d['round2']].append(d['id']) roundDays.append((d['round2'], d['id'])) roundDaysMin[(d['round2'], d['id'])] = d['minGames2'] roundDaysMax[(d['round2'], d['id'])] = d['maxGames2'] roundGamesMax[d['round2']] = min( nTeams/2, roundGamesMax[d['round2']]+d['maxGames2']) roundGamesMin[d['round2']] += d['minGames2'] dt = parse(d['day']) getDateTimeDay[d['id']] = dt getDayByDateTime[dt] = d['id'] getNiceDay[d['id']] = str(dt.strftime('%a, %b %d, %Y')) getWeekDay[d['id']] = str(wds[dt.weekday()]) countries = list(set([t_country[t] for t in teams])) getWeekDaysPerRound = {r: [getWeekDay[d] for d in getDays[r]] for r in rounds} wd = {"Mondays": 0, "Tuesdays": 1, "Wednesdays": 2, "Thursdays": 3, "Fridays": 4, "Saturdays": 5, "Sundays": 6} t_site_bestTimeSlots = {(t, d): [] for t in realteams for d in days} prio_weight = {"A": 0, "B": 50, "C": 100} toTime = False earliestDay = {r: getDays[r][0] for r in rounds} latestDay = {r: getDays[r][0] for r in rounds} for r in rounds: for d in getDays[r]: dt = getDateTimeDay[d] if dt > getDateTimeDay[latestDay[r]]: latestDay[r] = d if dt < getDateTimeDay[earliestDay[r]]: earliestDay[r] = d # %% basicTeams = teams basicGames = [(t1, t2) for (t1, t2) in games if t1 in basicTeams and t2 in basicTeams] nBasicTeams = len(basicTeams) nBasicTeamsPerCluster = int(nBasicTeams/len(gameClusters)+0.9) if nBasicTeamsPerCluster % 2 == 1: nBasicTeamsPerCluster += 1 nRounds1 = nBasicTeamsPerCluster-1 nBasicRounds = nPhases * (nBasicTeamsPerCluster-1) if nBasicTeamsPerCluster == 1 or nBasicRounds == 1: nBasicRounds = nRounds nRounds1 = nRounds basicRounds = range(1, nBasicRounds+1) print("nPhases ", nPhases) print("nGameClusters ", len(gameClusters)) print("nBasicTeamsPerCluster ", nBasicTeamsPerCluster) print("nBasicTeams ", nBasicTeams) print("nBasicRounds ", nBasicRounds) print("nRounds1 ", nRounds1) stretch = nRounds/nBasicRounds # print ("regionalPatternUse " , regionalPatternUse) rounds1 = range(1, nRounds1+1) nGames = nTeams*nRounds1 getBasicRound = {r: int((r-1)/stretch)+1 for r in rounds} getRealRounds = {br: [r for r in rounds if getBasicRound[r] == br] for br in basicRounds} # print ("stretch : " , stretch) getBasicDays = {r: [] for r in basicRounds} for r in rounds: getBasicDays[getBasicRound[r]] += (getDays[r]) getRoundDaysByDay = {d: [rd for rd in roundDays if rd[1] == d] for d in days} getRoundDaysByRound = { r: [rd for rd in roundDays if rd[0] == r] for r in rounds} daysSorted = [] for dt in sorted([getDateTimeDay[d] for d in days]): daysSorted.append(getDayByDateTime[dt]) minRest = {(t, s1, s2): thisSeason.minDaysBetweenGames for t in teams for s1 in [ 'A', 'H'] for s2 in ['A', 'H']} for t in teamObjects: minRest[(t['id'], 'H', 'H')] = max( minRest[(t['id'], 'H', 'H')], t['minRest_HH']) minRest[(t['id'], 'H', 'A')] = max( minRest[(t['id'], 'H', 'A')], t['minRest_HA']) minRest[(t['id'], 'A', 'H')] = max( minRest[(t['id'], 'A', 'H')], t['minRest_AH']) minRest[(t['id'], 'A', 'A')] = max( minRest[(t['id'], 'A', 'A')], t['minRest_AA']) maxMinRest = {t: max([minRest[(t, s1, s2)] for s1 in ['A', 'H'] for s2 in ['A', 'H']]) for t in teams} excessGames = {rd: -roundDaysMax[rd] for rd in roundDays} deficientGames = {rd: roundDaysMin[rd] for rd in roundDays} excessGames = {rd: max(0, excessGames[rd]) for rd in roundDays} deficientGames = {rd: max(0, deficientGames[rd]) for rd in roundDays} # %% allowed_weekdays = {'--': [0, 1, 2, 3, 4, 5, 6], 'Mondays': [0], 'Tuesdays': [1], 'Wednesdays': [2], 'Thursdays': [3], 'Fridays': [4], 'Saturdays': [5], 'Sundays': [6], 'Weekdays': [0, 1, 2, 3, 4], 'Weekends': [5, 6], 'Mon.-Thu.': [0, 1, 2, 3], 'Fri.-Sun.': [4, 5, 6]} hawishes = HAWish.objects.filter( scenario=s2, active=True).order_by('reason').values() hawTeams = {} hawDays = {} hawTimes = {} hawRounds = {} hawRoundsString = {} for c in HAWish.objects.filter(scenario=s2): # print () # print (c.reason ) hawDays[c.id] = [] hawTeams[c.id] = [] hawTimes[c.id] = [str(dd.id) for dd in c.timeslots.all()] if c.selection_mode == 0: for t in c.teams.filter(active=True): hawTeams[c.id].append(t.id) elif c.selection_mode == 1: for t in c.groups.all(): for t2 in t.teams.filter(active=True): hawTeams[c.id].append(t2.id) elif c.selection_mode == 2: cids = [cn.id for cn in c.countries.all()] for t in teams: if t_globalCountry[t] in cids: hawTeams[c.id].append(t) if c.multidate: hawDays[c.id] = [dd.id for dd in c.dates.all()] # print ("multidate") else: if c.day and not c.day2: hawDays[c.id].append(c.day.id) # print('+ ',getDayById[e['day_id']]) if not c.day and c.day2: hawDays[c.id].append(c.day2.id) # print('+ ',getDayById[e['day2_id']]) if not c.day and not c.day2: for d in days: dt = getDateTimeDay[d] if dt.weekday() in allowed_weekdays[c.weekdays]: # print (hawDays[e['id']]) hawDays[c.id].append(d) # print('+ ',getDayById[d]) if c.day and c.day2: day1 = getDateTimeDay[c.day.id] day2 = getDateTimeDay[c.day2.id] for d in days: dt = getDateTimeDay[d] # print (day1, "<=" , dt , "<=", day2 , " " , day1<=dt and dt<=day2 ) if day1 <= dt and dt <= day2 and dt.weekday() in allowed_weekdays[c.weekdays]: # print (day1, "<=" , dt , "<=", day2 , " " , day1<=dt and dt<=day2 ) hawDays[c.id].append(d) # print('+ ',getDayById[d]) print("processing encounters") encwishes = EncWish.objects.filter(scenario=s2, active=True).values() encTeams1 = {} encTeams2 = {} encGroups = {} encGames = {} encTeams1String = {} encTeams2String = {} encDays = {e['id']: [] for e in encwishes} encDaySets = {} encTimes = {} encRounds = {e['id']: [] for e in encwishes} encRoundsString = {e['id']: "" for e in encwishes} for c in EncWish.objects.filter(scenario=s2, active=True): encTimes[c.id] = [str(dd.id) for dd in c.timeslots.all()] encTeams1[c.id] = [] encTeams2[c.id] = [] encGroups[c.id] = [] encTeams1String[c.id] = '' encTeams2String[c.id] = '' for t in c.encounterGroups.all(): encGroups[c.id].append(t) if c.useGroups: for gr in c.teams1_groups.all(): for t in gr.teams.filter(active=True): encTeams1[c.id].append(t.id) encTeams1String[c.id] += gr.name + ', ' for gr in c.teams2_groups.all(): for t in gr.teams.filter(active=True): encTeams2[c.id].append(t.id) encTeams2String[c.id] += t.name + ', ' else: for t in c.teams1.filter(active=True): encTeams1[c.id].append(t.id) encTeams1String[c.id] += t.name + ', ' for t in c.teams2.filter(active=True): encTeams2[c.id].append(t.id) encTeams2String[c.id] += t.name + ', ' encTeams1String[c.id] = encTeams1String[c.id][:-2] encTeams2String[c.id] = encTeams2String[c.id][:-2] if c.useEncounterGroups: tmp_games = [(t1.id, t2.id) for eg in encGroups[c.id] for ec in eg.encounter_set.all( ) for t1 in ec.homeTeams.all() for t2 in ec.awayTeams.all() if t1 != t2] tmp_games += [(t2.id, t1.id) for eg in encGroups[c.id] for ec in eg.encounter_set.all() for t1 in ec.homeTeams.all() for t2 in ec.awayTeams.all() if t1 != t2 and ec.symmetry] encGames[c.id] = [tmp_games] else: elemHomeTeams = [encTeams1[c.id]] if c.forEachTeam1: elemHomeTeams = [[t] for t in encTeams1[c.id]] elemAwayTeams = [encTeams2[c.id]] if c.forEachTeam2: elemAwayTeams = [[t] for t in encTeams2[c.id]] encGames[c.id] = [] # print ("NEW ENC ", elemHomeTeams,elemAwayTeams) for elh in elemHomeTeams: for ela in elemAwayTeams: # print (" --- ENC ", elh,ela) tmp_games = [(t1, t2) for t1 in elh for t2 in ela if t1 != t2] if c.symmetry: tmp_games += [(t1, t2) for t1 in ela for t2 in elh if t1 != t2] encGames[c.id].append(tmp_games) if c.multidate: encDays[c.id] = [dd.id for dd in c.dates.all()] else: if c.day: day1 = getDateTimeDay[c.day.id] if c.day and not c.day2: encDays[c.id].append(c.day.id) if not c.day and c.day2: encDays[c.id].append(c.day2.id) if not c.day and not c.day2: for d in days: dt = getDateTimeDay[d] # dt = parse(getDayById[d]['day']) if dt.weekday() in allowed_weekdays[c.weekdays]: encDays[c.id].append(d) if c.day and c.day2: # day1= parse(c.day.day) # day2= parse(c.day2.day) day1 = getDateTimeDay[c.day.id] day2 = getDateTimeDay[c.day2.id] for d in days: dt = getDateTimeDay[d] # dt = parse(getDayById[d]['day']) if day1 <= dt and dt <= day2 and dt.weekday() in allowed_weekdays[c.weekdays]: encDays[c.id].append(d) encDaySets[c.id] = [] elemDays = [encDays[c.id]] if c.forEachDay or c.forOneDay: elemDays = [[d] for d in encDays[c.id]] lastDaySet = [] for d in elemDays: tmpDays = d if (c.forEachDay or c.forOneDay) and c.timeframe != 0: tmpDays = [] # day1= parse(getDayById[d[0]]['day']) day1 = getDateTimeDay[d[0]] if c.timeframe > 0: day2 = day1 + datetime.timedelta(days=c.timeframe-1) # print (e) # print (day1, day2) for d3 in days: dt = getDateTimeDay[d3] # dt = parse(getDayById[d3]['day']) if day1 <= dt and dt <= day2: tmpDays.append(d3) else: r1 = getDayById[d[0]]['round'] for d3 in days: # dt = parse(getDayById[d3]['day']) dt = getDateTimeDay[d3] if day1 <= dt and getRoundByDay[d3] < r1 + (-c.timeframe): tmpDays.append(d3) # print (" ROUNDWISH ", e, elemEncWishDays[cntr], e['timeframe']) # for d4 in elemEncWishDays[cntr]: # print (" - " ,getDayById[d4]['day']) if len([d for d in tmpDays if d not in lastDaySet]) > 0: encDaySets[c.id].append(tmpDays) lastDaySet = tmpDays # print("-.--- NEW DAYS", tmpDays) for ds in encDaySets[c.id]: for d3 in ds: encRounds[c.id] += getRoundsByDay[d3] encRounds[c.id] = sorted(list(set(encRounds[c.id]))) for r in encRounds[c.id]: encRoundsString[c.id] += str(r)+"_" if encRoundsString[c.id] != "": encRoundsString[c.id] = encRoundsString[c.id][:-1] # print (encRoundsString[c.id] , " # " ,c.affected_rounds , encRoundsString[c.id] != c.affected_rounds) onlyEarlyDays = [] onlyLateDays = [] alwaysConsiderAllGames = not mathModelName in [ "Florida State League", "UEFA NL"] elemEncWishes = {e['id']: [] for e in encwishes} elemEncWishGames = {} elemEncWishDays = {} cntr = 0 for e in encwishes: for eg in encGames[e['id']]: for ed in encDaySets[e['id']]: if len(eg) > 0 and len(ed) > 0: cntr += 1 elemEncWishes[e['id']].append(cntr) elemEncWishGames[cntr] = eg elemEncWishDays[cntr] = ed # print (elemEncWishGames) # print (elemEncWishDays) encRelRoundsMin = {el: [] for enc in encwishes for el in elemEncWishes[enc['id']]} encRelRoundsMax = {el: [] for enc in encwishes for el in elemEncWishes[enc['id']]} for enc in encwishes: # print (e) # print ("ENC !! " , enc['reason'] ) for el in elemEncWishes[enc['id']]: relDaysSet = set(elemEncWishDays[el]) for r in basicRounds: if len(relDaysSet.intersection(set(getBasicDays[r]))) > 0: frac = len(relDaysSet.intersection( set(getBasicDays[r]))) / len(getBasicDays[r]) # print (len(relDaysSet.intersection(set(getBasicDays[r]))) , len (getBasicDays[r]) , frac) if frac > 0: encRelRoundsMin[el].append(r) if frac == 1: encRelRoundsMax[el].append(r) nElemEncWishes = sum([len(elemEncWishes[enc['id']]) for enc in encwishes]) # print (encRelRoundsMin) elemHaWishes = {e['id']: [] for e in hawishes} elemHaWishTeams = {} elemHaWishDays = {} elemHaWishFirstDay = {} cntr = 1 for e in hawishes: elemTeams = [hawTeams[e['id']]] if e['forEachTeam']: elemTeams = [[t] for t in hawTeams[e['id']]] elemDays = [hawDays[e['id']]] if e['forEachDay'] or e['forOneDay']: elemDays = [[d] for d in hawDays[e['id']]] elemHaWishes[e['id']] = [] allElemDays = [] thisDaySet = [] lastDaySet = [] for d in elemDays: # print (e) if (e['forEachDay'] or e['forOneDay']) and e['timeframe'] != 1: thisDaySet = [] # day1= parse(getDayById[d[0]]['day']) day1 = getDateTimeDay[d[0]] if e['timeframe'] > 1: day2 = day1 + datetime.timedelta(days=e['timeframe']-1) for d3 in days: # dt = parse(getDayById[d3]['day']) dt = getDateTimeDay[d3] if day1 <= dt and dt <= day2: thisDaySet.append(d3) else: r1 = getDayById[d[0]]['round'] for d3 in days: dt = getDateTimeDay[d3] # dt = parse(getDayById[d3]['day']) if day1 <= dt and getRoundByDay[d3] < r1 + (-e['timeframe']): thisDaySet.append(d3) print(" ROUND HA WISH ", e, thisDaySet, e['timeframe']) else: thisDaySet = d # only create wish id new day set is superset if len([d for d in thisDaySet if d not in lastDaySet]) > 0: for t in elemTeams: cntr += 1 elemHaWishes[e['id']].append(cntr) elemHaWishTeams[cntr] = t elemHaWishDays[cntr] = thisDaySet.copy() elemHaWishFirstDay[cntr] = d[0] lastDaySet = thisDaySet.copy() allElemDays += thisDaySet hawRounds[e['id']] = [] for d3 in set(allElemDays): hawRounds[e['id']] += getRoundsByDay[d3] hawRounds[e['id']] = sorted(list(set(hawRounds[e['id']]))) hawRoundsString[e['id']] = "" for r in hawRounds[e['id']]: hawRoundsString[e['id']] += str(r)+"_" if hawRoundsString[e['id']] != "": hawRoundsString[e['id']] = hawRoundsString[e['id']][:-1] nElemHaWishes = sum([len(elemHaWishes[enc['id']]) for enc in hawishes]) gameAttractivity = {(t1, t2): attractivity[t1, t2] for (t1, t2) in games if t1 < t2} sorted_gameAttractivity = sorted( gameAttractivity.items(), key=operator.itemgetter(1)) nGames = len(games) topGames = [sorted_gameAttractivity[i] for i in range( int(0.8*0.5*nGames), min(len(sorted_gameAttractivity), int(0.5*nGames)))] goodGames = [sorted_gameAttractivity[i] for i in range( int(0.6*0.5*nGames), min(len(sorted_gameAttractivity), int(0.5*nGames)))] broadcastingwishes = BroadcastingWish.objects.filter(scenario=s2) nonBlocked = {(t, r): len(getBasicDays[r]) for r in basicRounds for t in teams} travelDays = {(t, r): len(getBasicDays[r]) for r in basicRounds for t in teams} hideDays = {(t, r): len(getBasicDays[r]) for r in basicRounds for t in teams} nonBlockedRounds = {(t, r): len(getDays[r]) for r in rounds for t in teams} travelRounds = {(t, r): len(getDays[r]) for r in rounds for t in teams} hideRounds = {(t, r): len(getDays[r]) for r in rounds for t in teams} for bl in blockings: bl_val = 1.0 if bl['time'] == "----" else 0.5 # if bl['time']!="----": # print (bl, bl_val , getDayById[bl['day_id']] ,getDayById[bl['day_id']]['round'] ,getDayById[bl['day_id']]['round'] !=0 ) if getDayById[bl['day_id']]['round'] != 0: if bl['type'] in ["Home", "Hide"]: nonBlocked[( bl['team_id'], getBasicRound[getDayById[bl['day_id']]['round']])] -= bl_val nonBlockedRounds[( bl['team_id'], getDayById[bl['day_id']]['round'])] -= bl_val # print ('FOUND HOME BLOCKING ', bl) if bl['type'] in ["Away", "Hide"]: travelDays[( bl['team_id'], getBasicRound[getDayById[bl['day_id']]['round']])] -= bl_val travelRounds[(bl['team_id'], getDayById[bl['day_id']] ['round'])] -= bl_val # print ('FOUND AWAY BLOCKING ', bl) if bl['type'] in ["Hide"]: hideDays[( bl['team_id'], getBasicRound[getDayById[bl['day_id']]['round']])] -= bl_val hideRounds[(bl['team_id'], getDayById[bl['day_id']] ['round'])] -= bl_val # print ('FOUND AWAY BLOCKING ', bl) noPlayRounds = {t: [r for r in rounds if nonBlockedRounds[( t, r)] + travelRounds[(t, r)] == 0] for t in teams} noHomeRounds = { t: [r for r in rounds if nonBlockedRounds[(t, r)] == 0] for t in teams} # print("nonBlockedRounds" ,nonBlockedRounds) # print("noHomeRounds" ,noHomeRounds) # print("noPlayRounds" ,noPlayRounds) playRounds = {t: sorted( [r for r in rounds if hideRounds[(t, r)] > 0]) for t in teams} # scale blocking of basic round to [0,1] for t in teams: for r in basicRounds: if len(getBasicDays[r]) > 0: nonBlocked[(t, r)] /= len(getBasicDays[r]) travelDays[(t, r)] /= len(getBasicDays[r]) if getTeamById[t] == "AX Armani Exchange Milan": print(r, getRealRounds[r], nonBlocked[(t, r)], nonBlocked[(t, r)]) for t in teams: if mathModelName == "UEFA NL" and noPlayRounds[t] in [[3, 4]]: t_usePhases[t] = False print("No need for phases ", getTeamById[t]) for t2 in opponents[t]: t_usePhases[t2] = False print(" -- also no need for phases ", getTeamById[t2]) if getTeamById[t] == "AX Armani Exchange Milan": t_usePhases[t] = False print("setting t_usePhases of ", getTeamById[t], t_usePhases[t]) runPatternAssignmentFirst = False chosenGames = [] useFullModel1 = False usePatterns = not mathModelName in ["NHL", "LNR"] usePatterns = not mathModelName in ["NHL"] balanceBreaks = mathModelName == "LNR" haSymmetric = not mathModelName in ["NHL", "LNR"] haSymmetric = not mathModelName in [ "NHL", "Ligue 1", "Costa Rica Premier League"] haSymmetric = not mathModelName in ["NHL"] # haSymmetric = not mathModelName in ["NHL" , "LNR"] if thisSeason.symmetry: haSymmetric = True use2BreakPatterns = False if thisSeason.initBreaks >= 2: use2BreakPatterns = True half_symmetry_offset = 0 if thisSeason.symmetry or use2BreakPatterns or not thisSeason.startWithBreakAllowed or not thisSeason.endWithBreakAllowed else 1 prev_mirror_round = {r: 0 if r <= nRounds1 else r - nRounds1+half_symmetry_offset for r in basicRounds} for r in basicRounds: if r > nRounds1 and int((r-1)/nRounds1) == int((prev_mirror_round[r]-1)/nRounds1): prev_mirror_round[r] = int( (r-1)/nRounds1-1)*nRounds1 + half_symmetry_offset+1-prev_mirror_round[r] % nRounds1 getPhaseOfBasicRound = { br: getPhaseOfRound[getRealRounds[br][0]] for br in basicRounds} getBasicRoundsOfPhase = {ph: [ br for br in basicRounds if getPhaseOfBasicRound[br] == ph] for ph in phases} if use2BreakPatterns or nTeams > 200 or not usePatterns or thisSeason.minRoundsBetweenGameOfSameTeams > 0: useFullModel1 = True useFullModel1 = True preplan_phases = phases preplan_phases = [0] if not haSymmetric: preplan_phases = phases fixedGamesRounds = [] starweight = {t: 0.0 for t in teams} for t1 in teams: for t2 in teams: starweight[t1] += distance[getTeamById[t1], getTeamById[t2]] available_days = {(t, d): 1 for t in teams for d in days} for bl in blockings: if bl['type'] in ["Home", "Hide"] and bl['time'] == '----': available_days[bl['team_id'], bl['day_id']] = 0 t_blocked_at = {(t, r): sum([available_days[t, d] for d in getDays[r]]) == 0 for t in teams for r in rounds} # %% model2 = LpProblem( "League_Scheduling_Model_--_Schedule_Games_"+str(thisScenario.id), LpMinimize) nextDay = {d: -1 for d in days} previousDay = {d: -1 for d in days} # cntr=0 lastDay = parse("01.01.1990") for thisDay in sorted(getDayByDateTime.keys()): if thisDay-lastDay == datetime.timedelta(days=1): # cntr+=1 d1 = getDayByDateTime[lastDay] d2 = getDayByDateTime[thisDay] nextDay[d1] = d2 previousDay[d2] = d1 # print ("next day of " , getNiceDay[d1] , ' ' , getNiceDay[d2]) lastDay = thisDay # print (cntr) # cntr=0 # for d in days+higherLeagueDayIds : # for d2 in days+higherLeagueDayIds: # if getDateTimeDay[d2]-getDateTimeDay[d]==datetime.timedelta(days=1): # cntr+=1 # nextDay[d]=d2 # previousDay[d2]=d # print ("next day of " , getNiceDay[d] , ' ' , getNiceDay[d2]) # print (cntr) cntr = 0 cntr2 = 0 # print ("games",games) # print (roundDays) seedTV = [] dontPlay = [] dontPlayGames = [] for bl in blockings: if bl['type'] == "Hide": dontPlay += [(bl['team_id'], bl['day_id'])] dontPlay += [(t, d) for d in days for t in teams if getDayMaxGames[d] == 0] x = {(t1, t2, rd): 0 for t1 in teams for t2 in teams for rd in roundDays} for (t1, t2) in games: for rd in roundDays: x[(t1, t2, rd)] = 1 for (t1, t2, rd) in x.keys(): if blocked_arena[(t1, rd[1], "----")] and runMode == 'Improve' and not thisSeason.allowBlockingViosInImprove: # cntr +=1 # print ("FORBIDDING") x[(t1, t2, rd)] = 0 for (t, d) in dontPlay: for t3 in teams: if not t3 in [t1, t2]: for rd in getRoundDaysByDay[d]: x[(t, t3, rd)] = 0 x[(t3, t, rd)] = 0 for (t1, t2, d) in dontPlayGames: for rd in getRoundDaysByDay[d]: x[(t1, t2, rd)] = 0 attendance = {(t1, t2, d): 0 for (t1, t2) in games for d in days} # x= {(t1,t2,rd) : 0 for t1 in teams for t2 in teams for rd in roundDays} x_round = {(t1, t2, r): 0 for t1 in teams for t2 in teams for r in rounds} for (t1, t2) in games: for rd in roundDays: if x[(t1, t2, rd)] == 1: if not evalRun: x[(t1, t2, rd)] = LpVariable('x_'+str(t1)+'_'+str(t2)+'_' + str(rd[0])+'_'+str(rd[1]), lowBound=0, upBound=1, cat=LpContinuous) cntr += 1 else: cntr += len(roundDays) for r in rounds: x_round[(t1, t2, r)] = LpVariable('x_round_'+str(t1)+'_' + str(t2)+'_'+str(r), lowBound=0, upBound=1, cat=LpContinuous) model2 += x_round[(t1, t2, r)] == sum([x[(t1, t2, rd)] for rd in getRoundDaysByRound[r]]), f'game_{t1}_{t2}_sum_of_days_equals_round_{r}' t_prev_mirror_round = {(t, r): 0 for t in teams for r in rounds} for t1 in teams: phaseLength = int(len(playRounds[t1])/nPhases+0.5) # print ("phaseLength", phaseLength) for i in range(len(playRounds[t1])): # print (i, phaseLength) if i >= phaseLength: # print ("setting " , playRounds[t1], playRounds[t1][i-phaseLength]) # print ("setting " , playRounds[t1][i], "->",playRounds[t1][i-phaseLength]) t_prev_mirror_round[(t1, playRounds[t1][i]) ] = playRounds[t1][i-phaseLength] # t_prev_mirror_round[(t,playRounds[t1][i])]=5 if not evalRun: for (t1, t2) in games: for r in rounds: if r > nRounds1 and thisSeason.symmetry: prev_round = prev_mirror_round[r] if thisSeason.groupBased and len(noPlayRounds[t1]) > 0 and noPlayRounds[t1] == noPlayRounds[t2]: prev_round = t_prev_mirror_round[t1, r] if prev_round > 0: model2 += x_round[(t1, t2, r) ] == x_round[(t2, t1, prev_round)], f"symmetric_{r}_{prev_round}" homeInRound = {(t1, r): LpVariable('homeInRound_'+str(t1)+'_'+str(r), lowBound=0, upBound=1, cat=LpContinuous) for t1 in teams for r in rounds} awayInRound = {(t1, r): LpVariable('awayInRound_'+str(t1)+'_'+str(r), lowBound=0, upBound=1, cat=LpContinuous) for t1 in teams for r in rounds} gameInBasicRound = {(t1, t2, r): LpVariable('gameInBasicRound_'+str(t1)+'_'+str(t2)+'_'+str(r), lowBound=0, upBound=defaultGameRepetions, cat=LpContinuous) for (t1, t2) in games for r in basicRounds} homeInBasicRound = {(t1, r): LpVariable('homeInBasicRound_'+str(t1)+'_'+str( r), lowBound=0, cat=LpContinuous) for t1 in teams for r in basicRounds} awayInBasicRound = {(t1, r): LpVariable('awayInBasicRound_'+str(t1)+'_'+str( r), lowBound=0, cat=LpContinuous) for t1 in teams for r in basicRounds} break3InRound = {(t1, r): LpVariable('break3InRound_'+str(t1)+'_'+str(r), lowBound=0, cat=LpContinuous) for t1 in teams for r in rounds} # breakInRound= {(t1,r) : LpVariable('breakInRound_'+str(t1)+'_'+str(r), lowBound = 0, upBound = 1, cat = LpContinuous) for t1 in teams for r in rounds} # breaksTotal = LpVariable('breaksTotal', lowBound = 0, cat = LpContinuous) pairingVio = {(pair['id'], d): LpVariable('pairingVio_'+str(pair['id'])+'_' + str(d), lowBound=0, cat=LpContinuous) for pair in pairings for d in days} derbyMissing = {d: LpVariable( 'derbyMissing_'+str(d), lowBound=0, cat=LpContinuous) for d in days} breakVio = {(br['id'], t): LpVariable('breakVio_' + str(br['id'])+'_' + str(t), lowBound=0, cat=LpContinuous) for br in breaks for t in teams} blockingVio = {bl['id']: LpVariable( 'blockingVio_' + str(bl['id']), lowBound=0, cat=LpContinuous) for bl in blockings} # blockingVioTotal = LpVariable('blockingVioTotal', lowBound = 0, cat = LpContinuous) hawVio = {haw['id']: LpVariable( 'hawVio' + str(haw['id']), lowBound=0, cat=LpContinuous) for haw in hawishes} HawVioTooLess = {el: LpVariable('havviotooless_' + str(el), lowBound=0, cat=LpContinuous) for haw in hawishes for el in elemHaWishes[haw['id']]} HawVioTooMuch = {el: LpVariable('havviotoomuch_' + str(el), lowBound=0, cat=LpContinuous) for haw in hawishes for el in elemHaWishes[haw['id']]} # HawVioTotal = LpVariable('HawVioTotal', lowBound = 0, cat = LpContinuous) encVio = {enc['id']: LpVariable( 'encVio' + str(enc['id']), lowBound=0, cat=LpContinuous) for enc in encwishes} encVioTooLess = {el: LpVariable('encViotooless' + str(enc['id'])+"_"+str( el), lowBound=0, cat=LpContinuous) for enc in encwishes for el in elemEncWishes[enc['id']]} encVioTooMuch = {el: LpVariable('encViotoomuch' + str(enc['id'])+"_"+str( el), lowBound=0, cat=LpContinuous) for enc in encwishes for el in elemEncWishes[enc['id']]} # encVioTotal = LpVariable('encVioTotal', lowBound = 0, cat = LpContinuous) # broadVio = { d : LpVariable('broadVio'+ str(d) , lowBound = 0, cat = LpContinuous) for d in days} broadVioTm = {(b.id, r): LpVariable('broadVioTm_' + str(b.id) + "_" + str(r), lowBound=0, cat=LpContinuous) for b in broadcastingwishes for r in rounds} gamesTooClose2 = {(t, r): LpVariable('gamesTooClose2_' + str(t) + '_' + str(r), lowBound=0, cat=LpContinuous) for t in teams for r in rounds} missingGamesVio = {(t1, t2): LpVariable('missingGamesVio_' + str(t1) + '_'+str(t2), lowBound=0, cat=LpContinuous) for (t1, t2) in games} home = {} away = {} home_time = {} away_time = {} away_in_cluster = {} away_in_cluster_day = {} getRoundDaysByBasicRound = {br: [rd for r in getRealRounds[br] for rd in getRoundDaysByRound[r]] for br in basicRounds} getMaxGameOnRoundDaysByBasicRound = {br: sum( roundDaysMax[rd] for r in getRealRounds[br] for rd in getRoundDaysByRound[r]) for br in basicRounds} for t in realteams: for d in days: away[t, d] = lpSum([x[(t2, t, rd)] for t2 in opponents[t] for rd in getRoundDaysByDay[d]]) or LpVariable( 'away'+str(t)+'_'+str(d), lowBound=0, upBound=0, cat=LpContinuous) home[t, d] = lpSum([x[(t, t2, rd)] for t2 in opponents[t] for rd in getRoundDaysByDay[d]]) or LpVariable( 'home'+str(t)+'_'+str(d), lowBound=0, upBound=0, cat=LpContinuous) for t in realteams: for r in rounds: if thisSeason.gamesPerRound == "one day": model2 += homeInRound[(t, r)] == lpSum([x[(t, t2, rd)] for t2 in opponents[t] for rd in getRoundDaysByRound[r]]), f'team_{t}_home_in_round_{r}' model2 += awayInRound[(t, r)] == lpSum([x[(t2, t, rd)] for t2 in opponents[t] for rd in getRoundDaysByRound[r]]), f'team_{t}_away_in_round_{r}' model2 += homeInRound[(t, r)] + awayInRound[(t, r)] <= 1 # if r >= 3: # model2 += break3InRound[(t, r)] + 2 >= homeInRound[(t, r-2)] + \ # homeInRound[(t, r-1)]+homeInRound[(t, r)], f'team_{t}_home_break_in_round_{r}' # model2 += break3InRound[(t, r)] + 2 >= awayInRound[(t, r-2)] + \ # awayInRound[(t, r-1)]+awayInRound[(t, r)], f'team_{t}_away_break_in_round_{r}' breakVioBalance = {t: LpVariable( 'breakVioBalance_'+str(t), lowBound=0, cat=LpContinuous) for t in realteams} numBreaks = {t: lpSum([breakVio[(bl['id'], t)] for bl in breaks]) for t in realteams} succBreaks = [bl for bl in breaks if bl['round1']+1 == bl['round2']] # for t in realteams: # for bl in breaks: # bl_id = bl['id'] # model2 += breakVio[(bl['id'], t)] + 1 >= homeInRound[t, # bl['round1']] + homeInRound[t, bl['round2']], f'breakvio_home_{bl_id}_for_{t}' # model2 += breakVio[(bl['id'], t)] + 1 >= awayInRound[t, # bl['round1']] + awayInRound[t, bl['round2']], f'breakvio_away_{bl_id}_for_{t}' getDays[0] = [] use_currentSolution = False currentGameCntr = {(t1, t2): 0 for t1 in teams for t2 in teams} # if use_currentSolution and len(currentSolution) !=len(fixedGames): teamGameCntr = {(t, r): 0 for t in teams for r in rounds} # print ("days " , days) for d in days: minG = sum([roundDaysMin[rd] - deficientGames[rd] for rd in getRoundDaysByDay[d]]) maxG = sum([roundDaysMax[rd] + excessGames[rd] for rd in getRoundDaysByDay[d]]) model2 += lpSum([home[(t, d)] for t in realteams]) <= maxG, f'max_games_on_day_{d}' # if len(getRoundDaysByDay[d]) > 1: # for rd in getRoundDaysByDay[d]: # model2 += lpSum([x[(t1, t2, rd)] for (t1, t2) in games] # ) <= roundDaysMax[rd] + excessGames[rd] print("rounds ", rounds, nRounds) for r in rounds: # one game a round for everyone for t1 in realteams: if thisSeason.gamesPerRound == "one day": cnstr = lpSum([x[(t1, t2, rd)] + x[(t2, t1, rd)] for t2 in opponents[t1] for rd in getRoundDaysByRound[r]]) if len(cnstr) > 0: model2 += cnstr <= 1, f'one_game_in_round_{r}_for_{t1}' # exit(0) print("realteams ", realteams) print("taking care of right numbers of games ... ") cntr = 0 if not specialGameControl: for (t1, t2) in realgames: if undirectedGameCntr[(t1, t2)] == 0: model2 += lpSum([x[(t1, t2, rd)] for rd in roundDays] ) == gameCntr[(t1, t2)] - missingGamesVio[(t1, t2)], f'let_{t1}_{t2}_play_gameCntr_times' missingGamesVio[(t1, t2)].upBound = max( 0, gameCntr[(t1, t2)]+undirectedGameCntr[(t1, t2)] - currentGameCntr[(t1, t2)]) # %% # breakVioTotal = lpSum([prioVal[bl['prio']]*breakVio[(bl['id'], t)] for bl in breaks for t in realteams]) + \ # 2*lpSum([prioVal[bl['prio']]*breakVio[(bl['id'], t)] # for bl in breaks for t in importantteams]) # break3VioTotal = lpSum([2*break3InRound[t, r] for t in teams for r in rounds]) missingGamesVioTotal = lpSum( [2000000 * missingGamesVio[(t1, t2)] for (t1, t2) in realgames]) standardObjectives = 0 \ + missingGamesVioTotal\ # + gew['Breaks']*breakVioTotal \ # + gew['Breaks']*2*break3VioTotal \ model2 += standardObjectives for v in model2.variables(): v.cat = LpInteger with open ("model2.txt", "w") as f: f.write(model2.__repr__()) model2.solve(XPRESS(msg=1)) # print(model2.sol_status) # for var in model2.variables(): # if var.value() and var.value() > 0: # print(var,var.value()) # %% sum([1 for k in x_round.keys() if type(x_round[k]) != int and x_round[k].value() > 0]) games_dict = defaultdict(lambda:[]) for key in x_round.keys(): if type(x_round[key]) != int and x_round[key].value() > 0: games_dict[key[2]].append((key[0],key[1])) # %% exit() if not evalRun: for (t1, t2) in realgames: # every pair plays each other in each phase once for p in phases: # phase violation in last phase possible if it contained more rounds than necessary if p < len(phases)-1 or True: if t_usePhases[t1] or t_usePhases[t2]: if thisSeason.groupBased and len(noPlayRounds[t1]) > 0 and noPlayRounds[t1] == noPlayRounds[t2]: relDays = [] phaseLength = int(len(playRounds[t1])/nPhases+0.5) for rr in playRounds[t1][p*phaseLength:(p+1)*phaseLength]: relDays += getDays[rr] print("adding days of round ", rr, " to phase ", p) else: relDays = getDaysOfPhase[p] model2 += lpSum([x[(t1, t2, rd)] + x[(t2, t1, rd)] for d in relDays for rd in getRoundDaysByDay[d]]) <= 1 # print (len(relDays),"reldays") # print (getTeamById[t1],getTeamById[t2], sum([x[(t1,t2,rd)] + x[(t2,t1,rd)] for d in relDays for rd in getRoundDaysByDay[d] ] )) if not evalRun: for t in realteams: if t_usePhases[t] and thisSeason.distributeHomeGamesEvenlyOverPhases: for p in phases: rds = [r for r in rounds if getPhaseOfRound[r] == p] nblocked = [r for r in noHomeRounds[t] if r in rds] print(p, len(rds), len(nblocked), rds, nblocked, getTeamById[t]) for p in phases: phaseLength = int(len(playRounds[t])/nPhases+0.5) model2 += lpSum([home[(t, d)] for d in getDaysOfPhase[p]]) <= int(phaseLength/2+1) if thisSeason.minRoundsBetweenGameOfSameTeams > 0: for r in rounds: if r + thisSeason.minRoundsBetweenGameOfSameTeams <= nRounds: rds = [] for r2 in range(r, r+thisSeason.minRoundsBetweenGameOfSameTeams+1): rds += getRoundDaysByRound[r2] rds2 = [] for r2 in range(r, r+int(0.5*thisSeason.minRoundsBetweenGameOfSameTeams)): rds2 += getRoundDaysByRound[r2] # print ("ONLY ONE IN " , rds) # print ("ONLY ONE IN " , rds2) for t1 in realteams: for t2 in realteams: if t1 < t2 and (gameCntr[(t1, t2)]*gameCntr[(t2, t1)] > 0 or x_round[(t1, t2, r)] != 0): # model2 += sum([ (x[(t1,t2, rd)]+x[(t2,t1,rd)]) for rd in rds ]) <= 1 + gamesTooClose2[t1,r] model2 += sum([(x[(t1, t2, rd)]+x[(t2, t1, rd)]) for rd in rds]) <= 1 if not evalRun: # max length home stands /trips for r in range(1, nRounds-thisSeason.maxTourLength+1): # print (" at least one home and away in rounds ") # for r3 in range(r,r+thisSeason.maxTourLength+1): # print (r3 ) for t in teams: if t not in noBreakLimitTeams: # model2 += lpSum([homeInRound[t,r2] for r2 in range(r,r+thisSeason.maxTourLength+1)]) >=1 model2 += lpSum([awayInRound[t, r2] for r2 in range(r, r + thisSeason.maxTourLength+1)]) <= thisSeason.maxTourLength model2 += lpSum([homeInRound[t, r2] for r2 in range(r, r + thisSeason.maxTourLength+1)]) <= thisSeason.maxTourLength print("check 1") # blockings for bl in blockings: if getDayById[bl['day_id']]['round'] != 0: if thisSeason.useFeatureKickOffTime and bl['time'] != '----': if bl['type'] in ["Home", "Hide"]: model2 += blockingVio[bl['id'] ] == home_time[bl['team_id'], bl['day_id'], bl['time']] # print ('FOUND HOME BLOCKING ', bl) else: model2 += blockingVio[bl['id'] ] == away_time[bl['team_id'], bl['day_id'], bl['time']] # print ('FOUND AWAY BLOCKING ', bl) else: if bl['type'] in ["Home", "Hide"]: model2 += blockingVio[bl['id'] ] == home[bl['team_id'], bl['day_id']] # print ('FOUND HOME BLOCKING ', bl) else: model2 += blockingVio[bl['id'] ] == away[bl['team_id'], bl['day_id']] # print ('FOUND AWAY BLOCKING ', bl) print("check 2") hawOneVio = {} hawForOneNotViolated = {} def getStringFromSet(ss): s2 = "" for s in ss: s2 += str(s)+"_" return s2[:-1] # hawishes for haw in hawishes: print(haw['reason']) for el in elemHaWishes[haw['id']]: if thisSeason.useFeatureKickOffTime and len(hawTimes[haw['id']]) > 0: if haw['homeAway'] == 'Home': relGames = lpSum([home_time[t, d, tm] for d in elemHaWishDays[el] for t in elemHaWishTeams[el] for tm in hawTimes[haw['id']]]) # print (haw['id'] ," haw : ", relGames, hawTimes[haw['id']]) elif haw['homeAway'] == 'Away': relGames = lpSum([away_time[t, d, tm] for d in elemHaWishDays[el] for t in elemHaWishTeams[el] for tm in hawTimes[haw['id']]]) else: # print(haw,el) relGames = lpSum([home_time[t, d, tm] + away_time[t, d, tm] for d in elemHaWishDays[el] for t in elemHaWishTeams[el] for tm in hawTimes[haw['id']]]) \ - lpSum([x_time[(t1, t2, rd, tm)] for d in elemHaWishDays[el] for rd in getRoundDaysByDay[d] for tm in hawTimes[haw['id']] for t1 in elemHaWishTeams[el] for t2 in elemHaWishTeams[el] if (t1, t2, rd, tm) in x_time.keys()]) else: if haw['homeAway'] == 'Home': relGames = lpSum([home[t, d] for d in elemHaWishDays[el] for t in elemHaWishTeams[el]]) elif haw['homeAway'] == 'Away': relGames = lpSum([away[t, d] for d in elemHaWishDays[el] for t in elemHaWishTeams[el]]) else: relGames = lpSum([home[t, d] + away[t, d] for d in elemHaWishDays[el] for t in elemHaWishTeams[el]]) - lpSum([x[t1, t2, rd] for d in elemHaWishDays[el] for rd in getRoundDaysByDay[d] for t1 in elemHaWishTeams[el] for t2 in elemHaWishTeams[el] if (t1, t2, rd) in x.keys()]) if haw['minGames'] > 0: model2 += relGames >= haw['minGames'] - HawVioTooLess[el] # print ("adding min ha constraint") if haw['maxGames'] >= 0: model2 += relGames <= haw['maxGames'] + HawVioTooMuch[el] # print ("adding max ha constraint") usedConstraintNames = [""] if haw['forOneDay']: # print (haw['forOneDay'], hawDays[haw['id']]) # print ([el for el in elemHaWishes[haw['id']] ]) # for el in elemHaWishes[haw['id']] : # print("- " , elemHaWishDays[el] , elemHaWishTeams[el] ) # print ([ (el, elemHaWishFirstDay[el]) for el in elemHaWishes[haw['id']] ]) relTeamString = {el: getStringFromSet( elemHaWishTeams[el]) for el in elemHaWishes[haw['id']]} relTeams = set([relTeamString[el] for el in elemHaWishes[haw['id']]]) # print (relTeams) for rt in relTeams: rtname = rt if len(rt) > 50: scname = "" while scname in usedConstraintNames: ttt = bytes(rt + ''.join(random.choice(string.ascii_lowercase) for i in range(10)), 'utf-8') scname = hashlib.sha224(ttt).hexdigest() rtname = scname[:10] usedConstraintNames.append(rtname) # print ("use rtname to encode wishes ", rtname) hawOneVio[(haw['id'], rt)] = LpVariable( 'hawOneVio_'+str(haw['id'])+"_"+rtname, cat=LpContinuous) for fd in hawDays[haw['id']]: relWishes = [el for el in elemHaWishes[haw['id']] if elemHaWishFirstDay[el] == fd] # relWishes = [el for el in elemHaWishes[haw['id']] ] # print (" -" , relWishes , [elemHaWishDays[el] for el in relWishes]) hawForOneNotViolated[(haw['id'], rt, fd)] = 0 if len(relWishes) > 0: hawForOneNotViolated[(haw['id'], rt, fd)] = LpVariable( 'hawForOneViolated_'+str(haw['id'])+"_"+rtname+"_"+str(fd), cat=LpBinary) model2 += lpSum(HawVioTooMuch[el]+HawVioTooLess[el] for el in relWishes if relTeamString[el] == rt) <= 1000 * (1-hawForOneNotViolated[(haw['id'], rt, fd)]) model2 += lpSum(hawForOneNotViolated[(haw['id'], rt, fd)] for fd in hawDays[haw['id']]) >= haw['forOneDayNum']-hawOneVio[(haw['id'], rt)] model2 += lpSum(hawOneVio[(haw['id'], rt)] for rt in relTeams) == hawVio[haw['id']] else: # print (haw['forOneDay'], hawDays[haw['id']]) model2 += hawVio[haw['id']] == lpSum(HawVioTooMuch[el]+HawVioTooLess[el] for el in elemHaWishes[haw['id']]) if haw['prio'] == "Hard" and "HardHAWishesNotBreakable" in special_wishes_active: model2 += hawVio[haw['id']] == 0 print("WISH HARD", haw['reason']) # HawVioTotal=lpSum([prioVal[haw['prio']] * (HawVioTooLess[el]+HawVioTooMuch[el]) for haw in hawishes for el in elemHaWishes[haw['id']]]) # print (hawDays) # print (elemHaWishFirstDay) encOneVio = {} encForOneNotViolated = {} print("check 3") # encwishes for enc in encwishes: print(enc) for el in elemEncWishes[enc['id']]: # print (enc) # model2+= encVio[enc['id']] == 1 - x[enc['team1_id'], enc['team2_id'], enc['day_id']] if thisSeason.useFeatureKickOffTime and len(encTimes[enc['id']]) > 0: if enc['minGames'] > 0: model2 += encVioTooLess[el] >= enc['minGames'] - sum([x_time[(t1, t2, rd, tm)] for d in elemEncWishDays[el] for rd in getRoundDaysByDay[d] for ( t1, t2) in elemEncWishGames[el] for tm in encTimes[enc['id']] if (t1, t2) in games]) if enc['maxGames'] >= 0: # if enc['maxGames']==0: print(enc['reason'], ' ', elemEncWishDays[el], ' ', enc['time'], ' ', encTeams1[enc['id']], ' ', encTeams2[enc['id']]) # print (sum([x_time[(t1,t2,rd, enc['time'])] for d in elemEncWishDays[el] for rd in getRoundDaysByDay[d] for (t1,t2) in elemEncWishGames[el] if (t1,t2) in games ])) model2 += encVioTooMuch[el] >= -enc['maxGames'] + sum([x_time[(t1, t2, rd, tm)] for d in elemEncWishDays[el] for rd in getRoundDaysByDay[d] for ( t1, t2) in elemEncWishGames[el] for tm in encTimes[enc['id']] if (t1, t2) in games]) else: if enc['minGames'] > 0: model2 += encVioTooLess[el] >= enc['minGames'] - sum([x[t1, t2, rd] for d in elemEncWishDays[el] for rd in getRoundDaysByDay[d] for (t1, t2) in elemEncWishGames[el] if (t1, t2) in games]) if enc['maxGames'] >= 0: # if enc['maxGames']==0: # print (enc['reason'], ' ', encDays[enc['id']], ' ', encTeams1[enc['id']] , ' ',encTeams2[enc['id']] ) model2 += encVioTooMuch[el] >= -enc['maxGames'] + sum([x[t1, t2, rd] for d in elemEncWishDays[el] for rd in getRoundDaysByDay[d] for (t1, t2) in elemEncWishGames[el] if (t1, t2) in games]) if enc['forOneDay']: for ed in encDaySets[enc['id']]: if len(ed) > 0: relWishes = [el for el in elemEncWishes[enc['id']] if elemEncWishDays[el] == ed] print("###", ed, relWishes) encForOneNotViolated[(enc['id'], ed[0])] = LpVariable( 'encForOneNotViolated_'+str(enc['id'])+"_"+str(ed[0]), cat=LpBinary) model2 += sum(encVioTooMuch[el]+encVioTooLess[el] for el in relWishes) <= 1000 * ( 1-encForOneNotViolated[(enc['id'], ed[0])]) model2 += sum(encForOneNotViolated[(enc['id'], ed[0])] for ed in encDaySets[enc['id']] if len( ed) > 0) >= enc['forOneDayNum']-encVio[enc['id']] else: model2 += encVio[enc['id']] == sum(encVioTooMuch[el]+encVioTooLess[el] for el in elemEncWishes[enc['id']]) if enc['prio'] == "Hard" and "HardEncWishesNotBreakable" in special_wishes_active: model2 += encVio[enc['id']] == 0 print("WISH HARD", enc['reason']) print("check 4") # return "" weekdayHomePref = {} dayHomePref = {} for t in teams: tm = getTeamByName[getTeamById[t]] weekdayHomePref[(t, 'Mon')] = tm['home_pref_mo'] weekdayHomePref[(t, 'Tue')] = tm['home_pref_tu'] weekdayHomePref[(t, 'Wed')] = tm['home_pref_we'] weekdayHomePref[(t, 'Thu')] = tm['home_pref_th'] weekdayHomePref[(t, 'Fri')] = tm['home_pref_fr'] weekdayHomePref[(t, 'Sat')] = tm['home_pref_sa'] weekdayHomePref[(t, 'Sun')] = tm['home_pref_su'] for d in days: dayHomePref[(t, d)] = weekdayHomePref[(t, getWeekDay[d])] maxTravelDistance = max([distanceById[t1, t2] for t1 in realteams for t2 in realteams]) maxTravelDistance = max(1, maxTravelDistance) singleTripWeight = 50 breakImbalanceTotal = lpSum([breakVioBalance[t] for t in realteams]) # HawVioTotal=lpSum([prioVal[haw['prio']] * (HawVioTooLess[el]+HawVioTooMuch[el]) for haw in hawishes for el in elemHaWishes[haw['id']]]) HawVioTotal = lpSum([prioVal[haw['prio']] * hawVio[haw['id']] for haw in hawishes]) encVioTotal = lpSum([prioVal[enc['prio']] * encVio[enc['id']] for enc in encwishes]) seedVioTotal = lpSum([100*prioVal[enc['prio']] * encVio[enc['id']] for enc in encwishes if enc['reason'] == "Seed Game"]) # broadVioTotal=lpSum([ 10 * broadVio[d] for d in days]) + lpSum([ 10 * broadVioTm[b.id] for b in broadcastingwishes]) broadVioTotal = lpSum([10 * broadVioTm[(b.id, r)] for b in broadcastingwishes for r in rounds]) breakVioTotal = lpSum([prioVal[bl['prio']]*breakVio[(bl['id'], t)] for bl in breaks for t in realteams]) + \ 2*lpSum([prioVal[bl['prio']]*breakVio[(bl['id'], t)] for bl in breaks for t in importantteams]) break3VioTotal = lpSum([2*break3InRound[t, r] for t in teams for r in rounds]) tooManyTop4InRowTotal = lpSum([10*tooManyTop4InRow[(t, r)] for t in teams for r in rounds]) pairingVioTotal = lpSum([5 * prioVal[pair['prio']] * pairingVio[(pair['id'], d)] for pair in pairings for d in days]) # blockingVioTotal=lpSum([ 100 * blockingVio[bl['id']] for bl in blockings if bl['type']=="Home"]) # print (blockings) # for bl in blockings: # if bl['type'] in ["Home"]: # print (blocked_arena[(bl["team_id"],bl["day_id"],"----")], getTeamById[bl["team_id"]], getNiceDay[bl["day_id"]] , bl ) fulfBlocks = set([(bl["team_id"], getRoundByDay[bl["day_id"]]) for bl in blockings if bl['type'] in [ "Home"] and blocked_arena[(bl["team_id"], bl["day_id"], "----")]]) blockingVioTotal2 = lpSum([-30 * homeInRound[tr] for tr in fulfBlocks if thisSeason.allowBlockingViosInImprove and runMode == 'Improve']) blockingVioTotal = lpSum([100 * blockingVio[bl['id']] for bl in blockings if bl['type'] in ["Home", "Hide"]]) + blockingVioTotal2 travelVioTotal = lpSum([100 * blockingVio[bl['id']] for bl in blockings if bl['type'] == "Away"]) derbiesMissingTotal = lpSum([30 * derbyMissing[d] for d in days]) unpreferredTotal = lpSum( [home[t, d] for t in teams for d in days if dayHomePref[(t, d)] == 0]) # competitionVioTotal=lpSum([ 100 * competitionVio[(c,d,t)] for (c,d,t) in competitions]) missingGamesVioTotal = lpSum( [2000000 * missingGamesVio[(t1, t2)] for (t1, t2) in realgames]) # TODO - UNDO CHANGES: missingGamesVioTotal=lpSum([ 2000 * missingGamesVio[(t1,t2)] for (t1,t2) in games]) oldScenGamesTotal = lpSum([wg * x[t1, t2, rd] for (t1, t2, r, wg) in otherScenGames for rd in getRoundDaysByRound[r]]) totalAttendance = lpSum([attendance[(t1, t2, d)] * x[t1, t2, (r, d)] for (t1, t2) in games for (r, d) in roundDays]) specialObjectives = 0 specialWishItems = {sw: [] for sw in special_wishes_active} specialWishVio = {} optCameraMovement = "Standard" # tvkitproblem = {} move2 = {} newtrip2 = {} standardObjectives = 1+gew['Home-/Away']*HawVioTotal\ + gew['Home-/Away']*3*unpreferredTotal \ + gew['Pairings']*pairingVioTotal \ + gew['Blockings']*blockingVioTotal \ + gew['Traveling']*travelVioTotal \ + gew['Breaks']*breakVioTotal \ + gew['Breaks']*2*break3VioTotal \ + gew['Breaks']*1*breakImbalanceTotal \ + 5*gew['Encounters']*encVioTotal \ + 5*gew['Encounters']*seedVioTotal \ + gew['Broadcasting']*broadVioTotal \ + gew['Derbies']*derbiesMissingTotal \ + 1.0*tooManyTop4InRowTotal\ + missingGamesVioTotal\ + oldScenGamesTotal\ - 0.01*totalAttendance model2 += standardObjectives # %% script = thisSeason.optimizationScript if script == '': if useBasicGames: script += "HEURISTIC\n" script += "GAME;1-"+str(nRounds)+";0.1;200\n" if thisSeason.groupBased: for c in allConferences: if not c.regional and c.teams.count() <= 12: script += "GROUP;1-"+str(nRounds)+";0.05;30;"+c.name+"\n" for cr in range(nPhases): minIntRound = min((cr) * nRoundsPerPhase+1, nRounds) maxIntRound = min((cr+1)*nRoundsPerPhase, nRounds) script = script.replace('\r', '') print("script") print(script) optSteps = [st.split(';') for st in script.split("\n")] print(optSteps) # %% print("Model built now solving .... ") nRuns = 1 maxSolveTime = 300 if thisSeason.groupBased: maxSolveTime = 40 mipgap = 0.01 # print ("######## Testing") # model2.solve(GUROBI(MIPGap=0.0, TimeLimit=120,msg=1)) use_LP_heuristic = False print(runMode == 'New', useBasicGames, runPatternAssignmentFirst) nRuns = nPhases # maxSolveTime = 120 mipgap = 0.0 # mipgap=0.95 # nRuns =1 onlyReopt = True onlyReopt = False onlyFewTrips = False singleTripWeight = 10 if onlyReopt: nRuns = 0 maxIntRound = nRounds missing_imp = [] cntr = 0 for st in optSteps: print(" - ", st) cntr += 1 if runMode == 'New' and st[0] == "HARDCONSTRAINTS": for bl in blockings: blockingVio[bl['id']].upBound = 0 print("blocking tightened : ", getTeamById[bl['team_id']], bl['day_id']) for enc in encwishes: if enc['reason'] == "Seed Game": encVio[enc['id']].upBound = 0 if runMode == 'New' and len(st) >= 1 and st[0] in ["PATTERNS", "HOMEAWAY", "BASICGAME", "GAME", "GAMES", "GROUP", "TRIPS", "LP-HEURISTIC"]: newRounds = [] print() optTarget = st[0] if len(st) > 1: for rf in st[1].split(","): rr = rf.split("-") if len(rr) == 1: newRounds.append(min(nRounds, int(rr[0]))) else: for ii in range(int(rr[0]), min(nRounds, int(rr[1])+1)): newRounds.append(ii) newRoundsString = st[1] else: newRounds = rounds newRoundsString = "1-"+str(nRounds) optsteptime = maxSolveTime optstepgap = mipgap if len(st) >= 3 and st[2] != "": optstepgap = float(st[2]) if len(st) >= 4 and st[3] != "": optsteptime = float(st[3]) print(newRounds) if st[0] == "HOMEAWAY": for t in teams: for r in newRounds: homeInRound[(t, r)].cat = LpInteger if st[0] == "BASICGAME": for (t1, t2) in games: for r in newRounds: gameInBasicRound[(t1, t2, r)].cat = LpInteger if st[0] in ["GAME", "GAMES"]: for (t, t2) in games: for r in newRounds: for rd in getRoundDaysByRound[r]: makeIntVar(x[(t, t2, rd)]) print('########################') print('# SOLVING MODEL '+optTarget+' FOR ROUNDS ' + newRoundsString + ' USING GAP ' + str(optstepgap) + ' and MAXTIME ' + str(optsteptime) + ' #') print('########################') # if solver == "CBC": # model2.solve(PULP_CBC_CMD(fracGap=optstepgap, # maxSeconds=optsteptime, threads=8, msg=1)) # elif solver == "Gurobi": # model2.solve(GUROBI(MIPGap=optstepgap, # TimeLimit=optsteptime, msg=1, Method=2, NodeMethod=2)) # else: # # for debugging: # # with open ("model2.txt", "w") as f: # # f.write(model2.__repr__()) # model2.solve(XPRESS(msg=1, targetGap=optstepgap, maxSeconds=optsteptime, options=[ # "THREADS=12,DETERMINISTIC=0,CUTSTRATEGY=0"], keepFiles=True)) # if model2.status < 0: # print("Status: ", model2.status) # if not lowerBoundFound: # lowerBoundFound = value(model2.objective) # cntr_rnd = 0 # if st[0] == "HOMEAWAY": # print(teams) # print(newRounds) # for t in teams: # for r in newRounds: # if homeInRound[(t, r)].value() > 0.9: # print('fixing home ' + str(r) + ' : ' + # getTeamById[t] + " " + str(homeInRound[(t, r)].value())) # homeInRound[(t, r)].lowBound = 1 # else: # homeInRound[(t, r)].upBound = 0 # if st[0] == "BASICGAME": # for r in newRounds: # for (t1, t2) in games: # if getTeamById[t1] != "-" and getTeamById[t2] != "-" and (t1, t2, r) in gameInBasicRound.keys() and type(gameInBasicRound[(t1, t2, r)]) != int: # if getVal(gameInBasicRound[(t1, t2, r)]) > 0.9: # gameInBasicRound[(t1, t2, r)].lowBound = 1 # else: # gameInBasicRound[(t1, t2, r)].upBound = 0 # if st[0] in ["GAME", "GAMES"]: # feedback = "Optimize games...." # missing_imp = [] # for (t1, t2) in realgames: # if missingGamesVio[(t1, t2)].value() > 0.9: # feedback += 'Game missing : '+getTeamById[t1] + ' - ' + getTeamById[t2] + ' ' + str( # missingGamesVio[(t1, t2)].value()) + '
\n' # missing_imp += [(1, nRounds, [t1, t2], 50)] # print(missing_imp) # print(feedback) # print("number of assigned games : ", sum( # [getVal(x[ttrd]) for ttrd in x.keys()])) # for (t1, t2) in games: # for r in newRounds: # for rd in getRoundDaysByRound[r]: # if getVal(x[(t1, t2, rd)]) > 0.9: # setLB(x[(t1, t2, rd)], 1) # print("fixing ", t1, t2, rd, # x[(t1, t2, rd)].lowBound) # else: # setUB(x[(t1, t2, rd)], 0) # for r in basicRounds: # for t1 in realteams: # homeInBasicRound[(t1, r)].lowBound = 0 # homeInBasicRound[(t1, r)].upBound = 10 # awayInBasicRound[(t1, r)].lowBound = 0 # awayInBasicRound[(t1, r)].upBound = 10 # for t2 in opponents[t1]: # if (t1, t2) in games: # gameInBasicRound[(t1, t2, r)].cat = LpContinuous # gameInBasicRound[(t1, t2, r)].lowBound = 0 # for t in realteams: # for r in newRounds: # homeInRound[(t, r)].cat = LpContinuous # for t2 in opponents[t]: # for rd in getRoundDaysByRound[r]: # if (t, t2) in games and getVal(x[(t, t2, rd)]) > 0.9: # setLB(x[(t, t2, rd)], x[(t, t2, rd)].value()) # currentSolution = [(t1, t2, r, d) for (t1, t2) in realgames for ( # r, d) in roundDays if getVal(x[(t1, t2, (r, d))]) > 0.9] # for r in rounds: # for t in teams: # homeInRound[(t, r)].lowBound = 0 # homeInRound[(t, r)].upBound = 1 # for (t1, t2) in games: # for r in rounds: # for rd in getRoundDaysByRound[r]: # makeIntVar(x[(t1, t2, rd)]) # print('Solved Again') # print('NOW REOPT') # # %% # %%