389 lines
13 KiB
Python
Executable File
389 lines
13 KiB
Python
Executable File
# %%
|
|
PROJECT_PATH = '/home/md/Work/ligalytics/leagues_stable/'
|
|
import os, sys
|
|
sys.path.insert(0, PROJECT_PATH)
|
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "leagues.settings")
|
|
os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true"
|
|
import random
|
|
import time
|
|
|
|
# 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 csv
|
|
|
|
import xpress as xp
|
|
xp.controls.outputlog = 0
|
|
|
|
|
|
|
|
scenario = Scenario.objects.get(id=32)
|
|
|
|
# %%
|
|
|
|
teamObjects = Team.objects.filter(season=scenario.season,active=True)
|
|
teams = teamObjects.values('id','country','pot')
|
|
|
|
countries = list(set(teamObjects.values_list('country', flat=True)))
|
|
|
|
|
|
potA_teamObjects = list(teamObjects.filter(pot=1).values('id','country'))
|
|
potB_teamObjects = list(teamObjects.filter(pot=2).values('id','country'))
|
|
potC_teamObjects = list(teamObjects.filter(pot=3).values('id','country'))
|
|
potD_teamObjects = list(teamObjects.filter(pot=4).values('id','country'))
|
|
|
|
potA_tmp = list(teamObjects.filter(pot=1).values_list('id', flat=True))
|
|
potB_tmp = list(teamObjects.filter(pot=2).values_list('id', flat=True))
|
|
potC_tmp = list(teamObjects.filter(pot=3).values_list('id', flat=True))
|
|
potD_tmp = list(teamObjects.filter(pot=4).values_list('id', 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)
|
|
|
|
print("teams = ",teams)
|
|
print("countries = ",countries)
|
|
print("teams_from_country = ",teams_from_country)
|
|
print("pot = ",pot)
|
|
print("potA_teamObjects = ",potA_teamObjects)
|
|
print("potB_teamObjects = ",potB_teamObjects)
|
|
print("potC_teamObjects = ",potC_teamObjects)
|
|
print("potD_teamObjects = ",potD_teamObjects)
|
|
print("potA_tmp = ",potA_tmp)
|
|
print("potB_tmp = ",potB_tmp)
|
|
print("potC_tmp = ",potC_tmp)
|
|
print("potD_tmp = ",potD_tmp)
|
|
|
|
exit()
|
|
|
|
|
|
# %%
|
|
|
|
# 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,
|
|
},
|
|
}
|
|
|
|
def check_feasible(fixed_games):
|
|
model = xp.problem(name='Draws', sense=xp.minimize)
|
|
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,val in requirement[t['pot']].items():
|
|
model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[r] if (t['id'],t2['id']) in x.keys()) == val)
|
|
for c in countries:
|
|
if c != t['country']:
|
|
model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in teams_from_country[c]) <= 3)
|
|
|
|
# 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])
|
|
|
|
start_time = time()
|
|
model.solve()
|
|
comp_time = time()-start_time
|
|
|
|
if model.getProbStatus() != 6:
|
|
# print("INFEASIBLE FOUND")
|
|
return False
|
|
else:
|
|
return True
|
|
|
|
import copy
|
|
# %%
|
|
|
|
|
|
|
|
|
|
for i in range(1,1000):
|
|
print("SIMULATION",i)
|
|
|
|
potA = copy.deepcopy(potA_tmp)
|
|
potB = copy.deepcopy(potB_tmp)
|
|
potC = copy.deepcopy(potC_tmp)
|
|
potD = copy.deepcopy(potD_tmp)
|
|
|
|
possible_Aopps = {
|
|
t['id']: [t2['id'] for t2 in potA_teamObjects if t2['country'] != t['country']] for t in teams
|
|
}
|
|
possible_Bopps = {
|
|
t['id']: [t2['id'] for t2 in potB_teamObjects if t2['country'] != t['country']] for t in teams
|
|
}
|
|
possible_Copps = {
|
|
t['id']: [t2['id'] for t2 in potC_teamObjects if t2['country'] != t['country']] for t in teams
|
|
}
|
|
possible_Dopps = {
|
|
t['id']: [t2['id'] for t2 in potD_teamObjects if t2['country'] != t['country']] for t in teams
|
|
}
|
|
|
|
|
|
Aopps = defaultdict(lambda:[])
|
|
Bopps = defaultdict(lambda:[])
|
|
Copps = defaultdict(lambda:[])
|
|
Dopps = defaultdict(lambda:[])
|
|
|
|
fixed_games = []
|
|
|
|
infeasible = False
|
|
|
|
while(potA):
|
|
new_team = potA.pop(random.randint(0,len(potA)-1))
|
|
|
|
while(len(Aopps[new_team]) < 2 and len(possible_Aopps[new_team]) > 0):
|
|
new_opponent = random.choice(possible_Aopps[new_team])
|
|
if len(Aopps[new_opponent]) < 2:
|
|
if check_feasible(fixed_games+[(new_team,new_opponent)]):
|
|
Aopps[new_team].append(new_opponent)
|
|
Aopps[new_opponent].append(new_team)
|
|
fixed_games.append((new_team,new_opponent))
|
|
possible_Aopps[new_team].remove(new_opponent)
|
|
else:
|
|
possible_Aopps[new_team].remove(new_opponent)
|
|
|
|
if len(Aopps[new_team]) < 2:
|
|
infeasible = True
|
|
break
|
|
|
|
while(len(Bopps[new_team]) < 2 and len(possible_Bopps[new_team]) > 0):
|
|
new_opponent = random.choice(possible_Bopps[new_team])
|
|
if len(Aopps[new_opponent]) < 2:
|
|
if check_feasible(fixed_games+[(new_team,new_opponent)]):
|
|
Bopps[new_team].append(new_opponent)
|
|
Aopps[new_opponent].append(new_team)
|
|
fixed_games.append((new_team,new_opponent))
|
|
possible_Bopps[new_team].remove(new_opponent)
|
|
else:
|
|
possible_Bopps[new_team].remove(new_opponent)
|
|
|
|
if len(Bopps[new_team]) < 2:
|
|
infeasible = True
|
|
break
|
|
|
|
while(len(Copps[new_team]) < 2 and len(possible_Copps[new_team]) > 0):
|
|
new_opponent = random.choice(possible_Copps[new_team])
|
|
if len(Aopps[new_opponent]) < 2:
|
|
if check_feasible(fixed_games+[(new_team,new_opponent)]):
|
|
Copps[new_team].append(new_opponent)
|
|
Aopps[new_opponent].append(new_team)
|
|
fixed_games.append((new_team,new_opponent))
|
|
possible_Copps[new_team].remove(new_opponent)
|
|
else:
|
|
possible_Copps[new_team].remove(new_opponent)
|
|
|
|
if len(Copps[new_team]) < 2:
|
|
infeasible = True
|
|
break
|
|
|
|
while(len(Dopps[new_team]) < 2 and len(possible_Dopps[new_team]) > 0):
|
|
new_opponent = random.choice(possible_Dopps[new_team])
|
|
if len(Aopps[new_opponent]) < 2:
|
|
if check_feasible(fixed_games+[(new_team,new_opponent)]):
|
|
Dopps[new_team].append(new_opponent)
|
|
Aopps[new_opponent].append(new_team)
|
|
fixed_games.append((new_team,new_opponent))
|
|
possible_Dopps[new_team].remove(new_opponent)
|
|
else:
|
|
possible_Dopps[new_team].remove(new_opponent)
|
|
|
|
if len(Dopps[new_team]) < 2:
|
|
infeasible = True
|
|
break
|
|
|
|
|
|
while(potB):
|
|
new_team = potB.pop(random.randint(0,len(potB)-1))
|
|
|
|
while(len(Bopps[new_team]) < 2 and len(possible_Bopps[new_team]) > 0):
|
|
new_opponent = random.choice(possible_Bopps[new_team])
|
|
if len(Bopps[new_opponent]) < 2:
|
|
if check_feasible(fixed_games+[(new_team,new_opponent)]):
|
|
Bopps[new_team].append(new_opponent)
|
|
Bopps[new_opponent].append(new_team)
|
|
fixed_games.append((new_team,new_opponent))
|
|
possible_Bopps[new_team].remove(new_opponent)
|
|
else:
|
|
possible_Bopps[new_team].remove(new_opponent)
|
|
|
|
if len(Bopps[new_team]) < 2:
|
|
infeasible = True
|
|
break
|
|
|
|
while(len(Copps[new_team]) < 2 and len(possible_Copps[new_team]) > 0):
|
|
new_opponent = random.choice(possible_Copps[new_team])
|
|
if len(Bopps[new_opponent]) < 2:
|
|
if check_feasible(fixed_games+[(new_team,new_opponent)]):
|
|
Copps[new_team].append(new_opponent)
|
|
Bopps[new_opponent].append(new_team)
|
|
fixed_games.append((new_team,new_opponent))
|
|
possible_Copps[new_team].remove(new_opponent)
|
|
else:
|
|
possible_Copps[new_team].remove(new_opponent)
|
|
|
|
if len(Copps[new_team]) < 2:
|
|
infeasible = True
|
|
break
|
|
|
|
while(len(Dopps[new_team]) < 2 and len(possible_Dopps[new_team]) > 0):
|
|
new_opponent = random.choice(possible_Dopps[new_team])
|
|
if len(Bopps[new_opponent]) < 2:
|
|
if check_feasible(fixed_games+[(new_team,new_opponent)]):
|
|
Dopps[new_team].append(new_opponent)
|
|
Bopps[new_opponent].append(new_team)
|
|
fixed_games.append((new_team,new_opponent))
|
|
possible_Dopps[new_team].remove(new_opponent)
|
|
else:
|
|
possible_Dopps[new_team].remove(new_opponent)
|
|
|
|
if len(Dopps[new_team]) < 2:
|
|
infeasible = True
|
|
break
|
|
|
|
|
|
while(potC):
|
|
new_team = potC.pop(random.randint(0,len(potC)-1))
|
|
|
|
|
|
while(len(Copps[new_team]) < 2 and len(possible_Copps[new_team]) > 0):
|
|
new_opponent = random.choice(possible_Copps[new_team])
|
|
if len(Copps[new_opponent]) < 2:
|
|
if check_feasible(fixed_games+[(new_team,new_opponent)]):
|
|
Copps[new_team].append(new_opponent)
|
|
Copps[new_opponent].append(new_team)
|
|
fixed_games.append((new_team,new_opponent))
|
|
possible_Copps[new_team].remove(new_opponent)
|
|
else:
|
|
possible_Copps[new_team].remove(new_opponent)
|
|
|
|
if len(Copps[new_team]) < 2:
|
|
infeasible = True
|
|
break
|
|
|
|
while(len(Dopps[new_team]) < 2 and len(possible_Dopps[new_team]) > 0):
|
|
new_opponent = random.choice(possible_Dopps[new_team])
|
|
if len(Copps[new_opponent]) < 2:
|
|
if check_feasible(fixed_games+[(new_team,new_opponent)]):
|
|
Dopps[new_team].append(new_opponent)
|
|
Copps[new_opponent].append(new_team)
|
|
fixed_games.append((new_team,new_opponent))
|
|
possible_Dopps[new_team].remove(new_opponent)
|
|
else:
|
|
possible_Dopps[new_team].remove(new_opponent)
|
|
|
|
if len(Dopps[new_team]) < 2:
|
|
infeasible = True
|
|
break
|
|
|
|
|
|
|
|
while(potD):
|
|
new_team = potD.pop(random.randint(0,len(potD)-1))
|
|
|
|
while(len(Dopps[new_team]) < 2 and len(possible_Dopps[new_team]) > 0):
|
|
new_opponent = random.choice(possible_Dopps[new_team])
|
|
if len(Dopps[new_opponent]) < 2:
|
|
if check_feasible(fixed_games+[(new_team,new_opponent)]):
|
|
Dopps[new_team].append(new_opponent)
|
|
Dopps[new_opponent].append(new_team)
|
|
fixed_games.append((new_team,new_opponent))
|
|
possible_Dopps[new_team].remove(new_opponent)
|
|
else:
|
|
possible_Dopps[new_team].remove(new_opponent)
|
|
|
|
if len(Dopps[new_team]) < 2:
|
|
infeasible = True
|
|
break
|
|
|
|
if infeasible:
|
|
print("PROBLEM!!!!!")
|
|
exit()
|
|
else:
|
|
with open('verteilung_draw2.csv', "a") as f:
|
|
for t in teams:
|
|
f.write(f"{i},{t['id']},{';'.join([str(a) for a in Aopps[t['id']]])},{';'.join([str(a) for a in Bopps[t['id']]])},{';'.join([str(a) for a in Copps[t['id']]])},{';'.join([str(a) for a in Dopps[t['id']]])}\n")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# %%
|