# %% PROJECT_PATH = '/home/md/Work/ligalytics/leagues_stable/' import os, sys sys.path.insert(0, PROJECT_PATH) os.environ.setdefault("DJANGO_SETTINGS_MODULE", "leagues.settings") os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true" import random # XPRESS ENVIRONMENT os.environ['XPRESSDIR'] = "/opt/xpressmp_8.4" os.environ['XPRESS'] = "/opt/xpressmp_8.4/bin" os.environ['LD_LIBRARY_PATH'] = os.environ['XPRESSDIR']+"/lib:"+os.environ['LD_LIBRARY_PATH'] os.environ['DYLD_LIBRARY_PATH'] = os.environ['XPRESSDIR']+"/lib:" os.environ['SHLIB_PATH'] = os.environ['XPRESSDIR']+"/lib:" os.environ['LIBPATH'] = os.environ['XPRESSDIR']+"/lib:" # os.environ['PYTHONPATH'] =os.environ['XPRESSDIR']+"/lib:"+os.environ['PYTHONPATH'] os.environ['PYTHONPATH'] =os.environ['XPRESSDIR']+"/lib:" os.environ['CLASSPATH'] =os.environ['XPRESSDIR']+"/lib/xprs.jar:" os.environ['CLASSPATH'] =os.environ['XPRESSDIR']+"/lib/xprb.jar:"+os.environ['CLASSPATH'] os.environ['CLASSPATH'] =os.environ['XPRESSDIR']+"/lib/xprm.jar:"+os.environ['CLASSPATH'] os.environ['PATH'] =os.environ['XPRESSDIR']+"/bin:"+os.environ['PATH'] from leagues import settings settings.DATABASES['default']['NAME'] = PROJECT_PATH+'/db.sqlite3' import django django.setup() from scheduler.models import * from pulp import * import xpress as xp xp.controls.outputlog = 1 scenario = Scenario.objects.get(id=32) # %% teams = Team.objects.filter(season=scenario.season,active=True).order_by('position') team_ids = list(teams.values_list('id',flat=True)) getTeamByID = { t.id:t for t in teams } # %% pot = {} teams_in_pot = {} for i in teams.values_list('pot',flat=True).distinct(): pot[i] = teams.filter(pot=i) teams_in_pot[i] = list(teams.filter(pot=i).values_list('id',flat=True)) # %% requirements = GameRequirement.objects.filter(scenario=scenario) gamereqs = [] for req in requirements: gamereqs.append((req.team1.id,req.team2.id)) # directed version # requirement = { # 1:[1,-1,2,-2,3,-3,4,-4], # 2:[1,-1,2,-2,3,-3,4,-4], # 3:[1,-1,2,-2,3,-3,4,-4], # 4:[1,-1,2,-2,3,-3,4,-4], # } # undirected version requirement = { 1:{ 1:2, 2:2, 3:2, 4:2, }, 2:{ 1:2, 2:2, 3:2, 4:2, }, 3:{ 1:2, 2:2, 3:2, 4:2, }, 4:{ 1:2, 2:2, 3:2, 4:2, }, } # %% # model = LpProblem("Draws", LpMinimize) # x = {(t1, t2): LpVariable('x_'+str(t1)+'_'+str(t2), lowBound=0, upBound=1, cat=LpInteger) for t1 in teams for t2 in teams if t1 != t2 and t1.country != t2.country} # # REQUIREMENTS # for t in teams: # for r,val in requirement[t.pot].items(): # # if r > 0: # # model += lpSum(x[t,t2] for t2 in pot[r] if (t,t2) in x.keys()) == 1, f'home_{t.id}_pot_{r}' # # else: # # model += lpSum(x[t2,t] for t2 in pot[-r] if (t,t2) in x.keys()) == 1, f'away_{t.id}_pot_{r}' # model += lpSum(x[t,t2] + x[t2,t] for t2 in pot[r] if (t,t2) in x.keys()) == val, f'undirected_{t.id}_pot_{r}' # for t1,t2 in x.keys(): # model += x[t1,t2]+x[t2,t1] <= 1, f'play_once_{t1.id}_{t2.id}' # model += lpSum(random.uniform(0,1)*x[key] for key in x.keys()) # model.solve() # # %% # gamereqs = [] # for key in x.keys(): # if x[key].value() > 0 : # gamereqs.append((key[0].id,key[1].id)) # %% # START COMPUTING SCHEDULE nRounds = 8 rounds = range(1,nRounds+1) # %% # MODEL WITH PATTERNS # pos_patterns = [ # [1,0,1,1,0,0,1,0 ], # [1,0,1,0,1,0,1,0 ], # [1,0,1,0,1,0,0,1 ], # [1,0,1,0,0,1,1,0 ], # [1,0,1,0,0,1,0,1 ], # [1,0,0,1,1,0,1,0 ], # [1,0,0,1,1,0,0,1 ], # [1,0,0,1,0,1,1,0 ], # [1,0,0,1,0,1,0,1 ], # ] # # add reverse patterns (all those starting with 0,1 ) # pos_patterns+=[ [ 1-p[i] for i in range(8)] for p in pos_patterns ] # patterns = { # i:p for i,p in enumerate(pos_patterns) # } # model = xp.problem(name='Patterns', sense=xp.minimize) # x = {} # assignPattern = {} # for r in rounds: # for game in gamereqs: # x[r, game[0], game[1]] = xp.var(ub=1, vartype=xp.integer) # x[r, game[1], game[0]] = xp.var(ub=1, vartype=xp.integer) # for t in team_ids: # for p in patterns: # assignPattern[t,p] = xp.var(ub=1, vartype=xp.integer) # model.addVariable(x) # model.addVariable(assignPattern) # for (t1,t2) in gamereqs: # model.addConstraint(xp.Sum([x[r,t1,t2]+x[r,t2,t1] for r in rounds]) == 1) # for t in team_ids: # for r in rounds: # model.addConstraint(xp.Sum([x[r,t,t2]+x[r,t2,t] for t2 in team_ids if (r,t,t2) in x.keys()]) == 1) # model.addConstraint(xp.Sum([x[r,t,t2] for t2 in team_ids if (r,t,t2) in x.keys()]) <= xp.Sum([assignPattern[t,p] for p in patterns if patterns[p][r-1] == 1])) # model.addConstraint(xp.Sum([assignPattern[t,p] for p in patterns]) == 1) # for p in pot: # model.addConstraint(xp.Sum([x[r,t,t2] for r in rounds for t2 in team_ids if (r,t,t2) in x.keys() and t2 in teams_in_pot[p]]) == 1) # =====>>> NOT WORKING WELL # %% # MODEL WITH HOME model = xp.problem(name='HomeAssignments', sense=xp.minimize) x = {} home = {} for r in rounds: for game in gamereqs: x[r, game[0], game[1]] = xp.var(ub=1, vartype=xp.integer) x[r, game[1], game[0]] = xp.var(ub=1, vartype=xp.integer) for t in team_ids: home[r,t] = xp.var(ub=1, vartype=xp.integer) model.addVariable(x) model.addVariable(home) # each game has to be played for (t1,t2) in gamereqs: model.addConstraint(xp.Sum([x[r,t1,t2]+x[r,t2,t1] for r in rounds]) == 1) for t in team_ids: for r in rounds: # each team plays once in each round model.addConstraint(xp.Sum([x[r,t,t2]+x[r,t2,t] for t2 in team_ids if (r,t,t2) in x.keys()]) == 1) # couple homes model.addConstraint(home[r,t] == xp.Sum([x[r,t,t2] for t2 in team_ids if (r,t,t2) in x.keys()])) # structural (home) requirements for r in range(1,nRounds-1): model.addConstraint(xp.Sum([home[r2,t] for r2 in range(r,r+3)]) <= 2) model.addConstraint(xp.Sum([1-home[r2,t] for r2 in range(r,r+3)]) <= 2) model.addConstraint(xp.Sum([home[r2,t] for r2 in range(1,3)]) == 1) model.addConstraint(xp.Sum([home[r2,t] for r2 in range(nRounds-1,nRounds+1)]) == 1) # play home against each pot for p in pot: model.addConstraint(xp.Sum([x[r,t,t2] for r in rounds for t2 in team_ids if (r,t,t2) in x.keys() and t2 in teams_in_pot[p]]) == 1) start_time = time() model.solve() comp_time = time()-start_time if model.getProbStatus() != 6: print("INFEASIBLE FOUND") # %% if model.getProbStatus() == 6: home_dict = {} away_dict = {} for key in x.keys(): if model.getSolution(x[key]) > 0: print(key[0],getTeamByID[key[1]],getTeamByID[key[2]]) home_dict[key[0],key[1]] = key[2] away_dict[key[0],key[2]] = key[1] sol = " \ \ " sol += "\n" sol += "\n" sol += "" for r in rounds: sol += f"" sol += "" sol += "\n" sol += "\n" for t in team_ids: tname = getTeamByID[t] sol += f"" for r in rounds: if (r,t) in home_dict.keys(): opponent = getTeamByID[home_dict[(r,t)]] sol += f"" elif (r,t) in away_dict.keys(): opponent = getTeamByID[away_dict[(r,t)]] sol += f"" else: sol += "" sol += "" sol += "\n" sol += "
{r}
{tname}{opponent.pot} - {opponent}{opponent.pot} - {opponent}
\n" sol += "


\n" with open('draw_schedule.html', 'w') as f: f.write(sol) # %% games = [(key[1],key[2],key[0]) for key in x.keys() if model.getSolution(x[key]) > 0] # %%