# %% PROJECT_PATH = '/home/md/Work/ligalytics/leagues_stable/' import os, sys sys.path.insert(0, PROJECT_PATH) os.environ.setdefault("DJANGO_SETTINGS_MODULE", "leagues.settings") os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true" from leagues import settings settings.DATABASES['default']['NAME'] = PROJECT_PATH+'/db.sqlite3' # settings.DATABASES['default']['ENGINE'] = 'django.db.backends.postgresql_psycopg2' # settings.DATABASES['default']['HOST'] = '0.0.0.0' # settings.DATABASES['default']['PORT'] = '5432' # settings.DATABASES['default']['USER'] = 'postgres' # settings.DATABASES['default']['PASSWORD'] = 'secret123' # settings.DATABASES['default']['NAME'] = 'mypgsqldb' # settings.DATABASES['default']['ATOMIC_REQUESTS'] = False # settings.DATABASES['default']['AUTOCOMMIT'] = True # settings.DATABASES['default']['CONN_MAX_AGE'] = 0 # settings.DATABASES['default']['CONN_HEALTH_CHECKS'] = False # settings.DATABASES['default']['OPTIONS'] = {} os.environ["XPRESSDIR"] = "/opt/xpressmp_8.4" os.environ["XPRESS"] = "/opt/xpressmp_8.4/bin" os.environ["LD_LIBRARY_PATH"] = os.environ["XPRESSDIR"] + "/lib" os.environ["DYLD_LIBRARY_PATH"] = os.environ["XPRESSDIR"] + "/lib" os.environ["SHLIB_PATH"] = os.environ["XPRESSDIR"] + "/lib" os.environ["LIBPATH"] = os.environ["XPRESSDIR"] + "/lib" os.environ["PYTHONPATH"] = os.environ["XPRESSDIR"] + "/lib" os.environ["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprs.jar" os.environ["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprb.jar" + os.pathsep + os.environ["CLASSPATH"] os.environ["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprm.jar" + os.pathsep + os.environ["CLASSPATH"] os.environ["PATH"] = os.environ["XPRESSDIR"] + "/bin" + os.pathsep + os.environ["PATH"] import django django.setup() from scheduler.models import * from draws.models import * import csv from multiprocessing import Pool, cpu_count import random import time import pulp from pulp import lpSum, value, XPRESS, GUROBI, PULP_CBC_CMD import gurobipy as gp from gurobipy import GRB import xpress as xp # xp.controls.outputlog = 0 scenario = Scenario.objects.get(id=4) # %% teamObjects = Team.objects.filter(season=scenario.season,active=True).order_by('pot') teams = teamObjects.values('id','country','pot','name') getTeamById = {} for t in teamObjects: getTeamById[t.id] = f"({t.pot}) {t.name}" getCountryById = {} for t in teamObjects: getCountryById[t.id] = t.country countries = list(set(teamObjects.values_list('country', flat=True))) teams_from_country = { c:[t for t in teams if t['country']==c] for c in countries } pot = {} for i in teamObjects.values_list('pot',flat=True).distinct(): pot[i] = list(teams.filter(pot=i)) teams = list(teams) # fixed_games = [(3940, 3894), (3933, 3940), (3940, 3937), (3765, 3940), (3940, 3895), (3700, 3940), (3940, 3696), (3925, 3940), (3702, 3935), (3894, 3702), (3702, 3926), (3937, 3702), (3702, 3700), (3758, 3702), (3702, 3699), (3757, 3702), (3932, 3762), (3732, 3932), (3932, 3938), (3761, 3932), (3932, 3730), (3701, 3932), (3932, 3870), (3853, 3932), (3764, 3933), (3935, 3764), (3764, 3936), (3898, 3764), (3764, 3756), (3928, 3764), (3764, 3925), (3904, 3764), (3762, 3732), (3762, 3761), (3930, 3762), (3762, 3701), (3760, 3762), (3762, 3697), (3698, 3762), (3732, 3765), (3926, 3732), (3732, 3928), (3730, 3732), (3732, 3698), (3870, 3732), (3894, 3930), (3938, 3894), (3894, 3758)] def check_feasible_pulp(fixed_games): model = pulp.LpProblem(f"Draws", pulp.LpMinimize) x = {} for t1 in teams: for t2 in teams: if t1['country'] != t2['country']: x[t1['id'], t2['id']] = pulp.LpVariable('x_'+str(t1['id'])+'_'+str(t2['id']),lowBound=0, upBound=1, cat=pulp.LpInteger) # REQUIREMENTS for t in teams: for r in range(1,5): # model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1) # model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1) model += lpSum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1 model += lpSum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1 for c in countries: if c != t['country']: # model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 3) model += lpSum(x[t['id'],t2['id']] for t2 in teams_from_country[c]) <= 2 # FIXATIONS for (t1,t2) in fixed_games: # print("FIXING",t1,t2) # model.addConstraint(x[t1,t2] == 1) model += x[t1,t2] == 1 for (t1,t2) in x.keys(): model += x[t1,t2] + x[t2,t1] <= 1, f'directed_{t1}_{t2}' # model.addConstraint(x[t1,t2] + x[t2,t1] <= 1) model += lpSum(random.uniform(0,1)*x[key] for key in x.keys()) tt =time.time() model.solve(XPRESS(msg=0,timeLimit=120,keepFiles=0)) comp_time = time.time()-tt if model.status in [-1,-2]: return False, comp_time else: return True, comp_time model = gp.Model('Draws') model.Params.OutputFlag = 0 x = {} for t1 in teams: for t2 in teams: if t1['country'] != t2['country']: # x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer) x[t1['id'], t2['id']] = model.addVar(vtype=GRB.BINARY) # REQUIREMENTS for t in teams: for r in range(1,5): model.addConstr(gp.quicksum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1) model.addConstr(gp.quicksum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1) for c in countries: if c != t['country']: model.addConstr(gp.quicksum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2) for clash in Clash.objects.filter(draw__season=scenario.season): for c1 in clash.countries.all(): for c2 in clash.countries.all(): if c1 != c2 and teams_from_country.get(c1.shortname) and teams_from_country.get(c2.shortname): model.addConstr(gp.quicksum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t in teams_from_country[c1.shortname] for t2 in teams_from_country[c2.shortname]) <= 0) print("CLASH",c1,c2) for (t1,t2) in x.keys(): model.addConstr(x[t1,t2] + x[t2,t1] <= 1) def check_feasible_gurobi(fixed_games): # FIXATIONS for key in x.keys(): if key in fixed_games: x[key].lb = 1 else: x[key].lb = 0 model.update() # tt =time.time() # model.solve() model.optimize() # comp_time = time.time()-tt if model.Status == GRB.OPTIMAL: return True, 0 else: # print("INFEASIBLE FOUND") return False, 0 def check_feasible(fixed_games): model = xp.problem(name='Draws', sense=xp.minimize) model.setControl ('outputlog', 1) x = {} for t1 in teams: for t2 in teams: if t1['country'] != t2['country']: x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer) model.addVariable(x) # REQUIREMENTS for t in teams: for r in range(1,5): model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1) model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1) for c in countries: if c != t['country']: model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2) # FIXATIONS for (t1,t2) in fixed_games: # print("FIXING",t1,t2) model.addConstraint(x[t1,t2] == 1) for (t1,t2) in x.keys(): model.addConstraint(x[t1,t2] + x[t2,t1] <= 1) tt =time.time() model.solve() comp_time = time.time()-tt if model.getProbStatus() != 6: # print("INFEASIBLE FOUND") return False, comp_time else: return True, comp_time # model = xp.problem(name='Draws', sense=xp.minimize) # model.setControl ('outputlog', 0) # x = {} # for t1 in teams: # for t2 in teams: # if t1['country'] != t2['country']: # x[t1['id'], t2['id']] = xp.var(ub=1, vartype=xp.integer) # model.addVariable(x) # # REQUIREMENTS # for t in teams: # for r in range(1,5): # model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == 1) # model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[r] if (t2['id'],t['id']) in x.keys()) == 1) # for c in countries: # if c != t['country']: # model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in teams_from_country[c]) <= 2) # for (t1,t2) in x.keys(): # model.addConstraint(x[t1,t2] + x[t2,t1] <= 1) def check_feasible_fix(fixed_games): # FIXATIONS # for key in x.keys(): # if key in fixed_games: # # x[key].lb = 1 # model.chgbounds([x[key]],['L'],[1]) # else: # # x[key].lb = 0 # model.chgbounds([x[key]],['L'],[0]) reset_bounds = [key for key in x.keys() if key not in fixed_games] model.chgbounds([x[key] for key in fixed_games],['L' for _ in range(len(fixed_games))],[1 for _ in range(len(fixed_games))]) model.chgbounds([x[key] for key in reset_bounds],['L' for _ in range(len(reset_bounds))],[0 for _ in range(len(reset_bounds))]) tt =time.time() model.solve() comp_time = time.time()-tt if model.getProbStatus() != 6: # print("INFEASIBLE FOUND") return False, comp_time return False else: return True, comp_time return True import itertools from itertools import permutations , product def simulate_draws(filename,n): print("RUNNING ASYNC",filename) fixed_games=None for i_sim in range(1, n): if i_sim % 100 == 0: print("RUNNING ASYNC",filename,i_sim) # start_time = time.time() # n_computations = 0 # check_time = 0 # total_comp_time = 0 possible_opps = {} for pos in range(8): p = pos//2+1 teams_from_pot = list(teamObjects.filter(pot=p).values('id','country')) possible_opps[pos] = { t['id']: [t2['id'] for t2 in teams_from_pot if t2['country'] != t['country']] for t in teams } sol_opps = { (t['id'],p):None for t in teams for p in range(8) } sol_countries = { (t['id'],c):0 for t in teams for c in countries if c != t['country'] } fixed_games = [] feasible = True for p in range(1,2): currentPot = list(teamObjects.filter(pot=p).values_list('id', flat=True)) while(feasible and currentPot): new_team = currentPot.pop(random.randint(0,len(currentPot)-1)) for current_pos in range(0,8,2): if sol_opps[new_team,current_pos] != None and sol_opps[new_team,current_pos+1] != None: continue possible_opps[current_pos][new_team] = [t for t in possible_opps[current_pos][new_team] if sol_countries[new_team,getCountryById[t]] < 2 and sol_countries[t,getCountryById[new_team]] < 2] possible_opps[current_pos+1][new_team] = [t for t in possible_opps[current_pos+1][new_team] if sol_countries[new_team,getCountryById[t]] < 2 and sol_countries[t,getCountryById[new_team]] < 2] list_1 = [None] list_2 = [None] if sol_opps[new_team,current_pos] == None: list_1 = possible_opps[current_pos][new_team] if sol_opps[new_team,current_pos+1] == None: list_2 = possible_opps[current_pos+1][new_team] # unique_combinations = [] # for i in range(len(list_1)): # for j in range(len(list_2)): # unique_combinations.append((list_1[i], list_2[j])) unique_combinations = list(itertools.product(list_1, list_2)) random.shuffle(unique_combinations) no_solution_found = True while (no_solution_found): new_games = [] # if sol_opps[new_team,current_pos] == None: # new_opponent1 = random.choice(possible_opps[current_pos][new_team]) # new_games.append((new_team,new_opponent1)) # if sol_opps[new_team,current_pos+1] == None: # new_opponent2 = random.choice(possible_opps[current_pos+1][new_team]) # new_games.append((new_opponent2,new_team)) new_opponent1,new_opponent2 = unique_combinations.pop() if new_opponent1: new_games.append((new_team,new_opponent1)) if new_opponent2: new_games.append((new_opponent2,new_team)) # n_computations += 1 # tt = time.time() check, comp_time = check_feasible_gurobi(fixed_games+new_games) # check_time += time.time()-tt # total_comp_time += comp_time if check: no_solution_found = False if sol_opps[new_team,current_pos] == None: sol_opps[new_team,current_pos] = new_opponent1 sol_countries[new_team,getCountryById[new_opponent1]] += 1 sol_opps[new_opponent1,(2*p-1)] = new_team sol_countries[new_opponent1,getCountryById[new_team]] += 1 if new_team in possible_opps[(2*p-1)-1][new_opponent1]: possible_opps[(2*p-1)-1][new_opponent1].remove(new_team) if sol_opps[new_team,current_pos+1] == None: sol_opps[new_team,current_pos+1] = new_opponent2 sol_countries[new_team,getCountryById[new_opponent2]] += 1 sol_opps[new_opponent2,(2*p-1)-(1)] = new_team sol_countries[new_opponent2,getCountryById[new_team]] += 1 if new_team in possible_opps[(2*p-1)][new_opponent2]: possible_opps[(2*p-1)][new_opponent2].remove(new_team) fixed_games += new_games for p in range(2,5): currentPot = list(teamObjects.filter(pot=p).values_list('id', flat=True)) while(feasible and currentPot): new_team = currentPot.pop(random.randint(0,len(currentPot)-1)) unique_combinations = {} for current_pos in range(2*(p-1),8,2): possible_opps[current_pos][new_team] = [t for t in possible_opps[current_pos][new_team] if sol_countries[new_team,getCountryById[t]] < 2 and sol_countries[t,getCountryById[new_team]] < 2 and sol_opps[t,(2*p-1)] == None] possible_opps[current_pos+1][new_team] = [t for t in possible_opps[current_pos+1][new_team] if sol_countries[new_team,getCountryById[t]] < 2 and sol_countries[t,getCountryById[new_team]] < 2 and sol_opps[t,(2*p-1)-1] == None] list_1 = [0] list_2 = [0] if sol_opps[new_team,current_pos] == None: list_1 = possible_opps[current_pos][new_team] if sol_opps[new_team,current_pos+1] == None: list_2 = possible_opps[current_pos+1][new_team] unique_combinations[current_pos] = [] for i in list_1: for j in list_2: if i != j or (i == 0 and j == 0): unique_combinations[current_pos].append((i, j)) combi_list = list(itertools.product(*unique_combinations.values())) random.shuffle(combi_list) # print("STOP") # for current_pos in range(2*(p-1),8,2): # print(current_pos,possible_opps[current_pos][new_team]) # print(current_pos+1,possible_opps[current_pos+1][new_team]) # list_1 = [0] # list_2 = [0] # if sol_opps[new_team,current_pos] == None: # list_1 = possible_opps[current_pos][new_team] # if sol_opps[new_team,current_pos+1] == None: # list_2 = possible_opps[current_pos+1][new_team] # unique_combinations[current_pos] = [] # for i in list_1: # for j in list_2: # if i != j or (i == 0 and j == 0): # unique_combinations[current_pos].append((i, j)) # print(unique_combinations) # exit() no_solution_found = True while (no_solution_found): # print("\tPOP",len(combi_list)) new_games = [] new_opponents = combi_list.pop() for o1,o2 in new_opponents: if o1: new_games.append((new_team,o1)) if o2: new_games.append((o2,new_team)) # n_computations += 1 # tt = time.time() check, comp_time = check_feasible_gurobi(fixed_games+new_games) # check_time += time.time()-tt # total_comp_time += comp_time if check: no_solution_found = False fixed_games += new_games for i,(new_opponent1,new_opponent2) in enumerate(new_opponents): current_pos = 2*(p-1)+2*i if sol_opps[new_team,current_pos] == None: sol_opps[new_team,current_pos] = new_opponent1 sol_countries[new_team,getCountryById[new_opponent1]] += 1 sol_opps[new_opponent1 ,(2*p-1)] = new_team sol_countries[new_opponent1,getCountryById[new_team]] += 1 if new_team in possible_opps[(2*p-1)-1][new_opponent1]: possible_opps[(2*p-1)-1][new_opponent1].remove(new_team) if sol_opps[new_team,current_pos+1] == None: sol_opps[new_team,current_pos+1] = new_opponent2 sol_countries[new_team,getCountryById[new_opponent2]] += 1 sol_opps[new_opponent2,(2*p-1)-(1)] = new_team sol_countries[new_opponent2,getCountryById[new_team]] += 1 if new_team in possible_opps[(2*p-1)][new_opponent2]: possible_opps[(2*p-1)][new_opponent2].remove(new_team) # print("COMPUTATIONS",n_computations) # print("TIME\t",time.time()-start_time) # print("CHECK\t",check_time) # print("COMP\t",total_comp_time) with open(filename+'.csv', "a") as f: for t in teams: f.write(f"{i_sim},{t['id']},{';'.join([str(sol_opps[t['id'],p]) for p in range(8)])}\n") # # WRITE SOL '.html' # sol = '
' # sol += " \ # \ # " # sol += "| " # sol += " | Pot A | " # sol += "Pot B | " # sol += "Pot C | " # sol += "Pot D | " # sol += "||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| \n" # for t in teams: # sol += f" | {getTeamById[t['id']]} | \n" # sol += "|||||||||||||||||||||||||||||||||||
| {getTeamById[t1['id']]} | " # for t2 in teams: # if (t1['id'],t2['id']) in fixed_games: # sol += f"{t2['country']} | " # elif (t2['id'],t1['id']) in fixed_games: # sol += f"@{t2['country']} | " # else: # sol += f"" # sol += " | |||||||||||||||||||||||||||||||||