496 lines
15 KiB
Python
Executable File
496 lines
15 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 networkx as nx
|
|
from multiprocessing import Pool, cpu_count
|
|
|
|
|
|
import xpress as xp
|
|
# xp.controls.outputlog = 0
|
|
|
|
|
|
# %%
|
|
|
|
# n = 1000
|
|
|
|
# def simulate_draws(filename,n):
|
|
# print("RUNNING ASYNC",filename)
|
|
# f = open(f"infeasible/{filename}_{0}.html", "w")
|
|
|
|
n = sys.maxsize
|
|
|
|
for i in range(1, n):
|
|
if i % 100 == 0:
|
|
print("RUNNING ASYNC",i)
|
|
# print("RUNNING ASYNC",filename,i)
|
|
# f.close()
|
|
# f = open(f"infeasible/{filename}_{i}.html", "w")
|
|
|
|
# write html to file
|
|
# filename = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
|
|
# with open(f"infeasible/{i}.html", "w") as f:
|
|
|
|
teams = [
|
|
{'id': 'A1', 'country': '0', 'pot': 1, 'name': 'A1'} ,
|
|
{'id': 'A2', 'country': '0', 'pot': 1, 'name': 'A2'} ,
|
|
{'id': 'A3', 'country': '0', 'pot': 1, 'name': 'A3'} ,
|
|
{'id': 'A4', 'country': '0', 'pot': 1, 'name': 'A4'} ,
|
|
{'id': 'A5', 'country': '0', 'pot': 1, 'name': 'A5'} ,
|
|
{'id': 'A6', 'country': '0', 'pot': 1, 'name': 'A6'} ,
|
|
{'id': 'B1', 'country': '0', 'pot': 2, 'name': 'B1'} ,
|
|
{'id': 'B2', 'country': '0', 'pot': 2, 'name': 'B2'} ,
|
|
{'id': 'B3', 'country': '0', 'pot': 2, 'name': 'B3'} ,
|
|
{'id': 'B4', 'country': '0', 'pot': 2, 'name': 'B4'} ,
|
|
{'id': 'B5', 'country': '0', 'pot': 2, 'name': 'B5'} ,
|
|
{'id': 'B6', 'country': '0', 'pot': 2, 'name': 'B6'} ,
|
|
{'id': 'C1', 'country': '0', 'pot': 3, 'name': 'C1'} ,
|
|
{'id': 'C2', 'country': '0', 'pot': 3, 'name': 'C2'} ,
|
|
{'id': 'C3', 'country': '0', 'pot': 3, 'name': 'C3'} ,
|
|
{'id': 'C4', 'country': '0', 'pot': 3, 'name': 'C4'} ,
|
|
{'id': 'C5', 'country': '0', 'pot': 3, 'name': 'C5'} ,
|
|
{'id': 'C6', 'country': '0', 'pot': 3, 'name': 'C6'} ,
|
|
{'id': 'D1', 'country': '0', 'pot': 4, 'name': 'D1'} ,
|
|
{'id': 'D2', 'country': '0', 'pot': 4, 'name': 'D2'} ,
|
|
{'id': 'D3', 'country': '0', 'pot': 4, 'name': 'D3'} ,
|
|
{'id': 'D4', 'country': '0', 'pot': 4, 'name': 'D4'} ,
|
|
{'id': 'D5', 'country': '0', 'pot': 4, 'name': 'D5'} ,
|
|
{'id': 'D6', 'country': '0', 'pot': 4, 'name': 'D6'} ,
|
|
{'id': 'E1', 'country': '0', 'pot': 5, 'name': 'E1'} ,
|
|
{'id': 'E2', 'country': '0', 'pot': 5, 'name': 'E2'} ,
|
|
{'id': 'E3', 'country': '0', 'pot': 5, 'name': 'E3'} ,
|
|
{'id': 'E4', 'country': '0', 'pot': 5, 'name': 'E4'} ,
|
|
{'id': 'E5', 'country': '0', 'pot': 5, 'name': 'E5'} ,
|
|
{'id': 'E6', 'country': '0', 'pot': 5, 'name': 'E6'} ,
|
|
{'id': 'F1', 'country': '0', 'pot': 6, 'name': 'F1'} ,
|
|
{'id': 'F2', 'country': '0', 'pot': 6, 'name': 'F2'} ,
|
|
{'id': 'F3', 'country': '0', 'pot': 6, 'name': 'F3'} ,
|
|
{'id': 'F4', 'country': '0', 'pot': 6, 'name': 'F4'} ,
|
|
{'id': 'F5', 'country': '0', 'pot': 6, 'name': 'F5'} ,
|
|
{'id': 'F6', 'country': '0', 'pot': 6, 'name': 'F6'} ,
|
|
]
|
|
|
|
teams_dict = {t['id']:t for t in teams}
|
|
|
|
|
|
country_groups = {}
|
|
|
|
# country_groups = {
|
|
# '1':['A1','A2','B1','B2','C1','C2','D1'],
|
|
# '2':['A3','A4','A5','B3','B4','B5'],
|
|
# '3':['A6','A7','A8','B6','B7','B8'],
|
|
# '4':['C3','C4','C5','D3','D4','D5'],
|
|
# '5':['C6','C7','C8','D6','D7','D8'],
|
|
# '6':['A9','B9','C9','D9','D2'],
|
|
# # '5':['A9','B9','C9','D5','D6'],
|
|
# # '2':['A4','A5','A6','B4','B5','B6'],
|
|
# # '3':['A7','A8','A9','B7','B8','B9'],
|
|
# # '4':['C1','C2','C3','D1','D2','D3'],
|
|
# # '5':['C4','C5','C6','D4','D5','D6'],
|
|
# }
|
|
|
|
# for c in country_groups:
|
|
# for tc in country_groups[c]:
|
|
# for t in teams:
|
|
# if t['id'] == tc:
|
|
# t['country'] = c
|
|
|
|
|
|
if not country_groups:
|
|
|
|
nCr = 6
|
|
|
|
|
|
n_country = {
|
|
(c,p):0 for c in range(1,nCr+1) for p in range(1,7)
|
|
}
|
|
|
|
for t in teams:
|
|
samples = list(range(1,nCr+1))
|
|
random.shuffle(samples)
|
|
found = False
|
|
while(samples and not found):
|
|
random_country = samples.pop()
|
|
total_random_countries = sum(n_country[random_country,p] for p in range(1,7))
|
|
|
|
if total_random_countries >= 7:
|
|
pass
|
|
elif max([n_country[random_country,p] for p in range(1,7)]) >= 3:
|
|
pass
|
|
elif max([n_country[random_country,p] for p in range(1,7)]) >= 6 - (total_random_countries):
|
|
pass
|
|
else:
|
|
t['country'] = random_country
|
|
n_country[random_country,t['pot']] += 1
|
|
found = True
|
|
|
|
|
|
x_counter = 0
|
|
x_index = 1
|
|
for t in teams:
|
|
if t['country'] not in list(range(1,nCr+1)):
|
|
if x_counter < 3:
|
|
x_counter += 1
|
|
else:
|
|
x_index += 1
|
|
x_counter = 1
|
|
t['country'] = f'X{x_index}'
|
|
|
|
|
|
|
|
|
|
|
|
# %%
|
|
|
|
|
|
|
|
getTeamById = {}
|
|
getNameById = {}
|
|
getCountryById = {}
|
|
for t in teams:
|
|
getTeamById[t['id']] = f"({t['pot']}) {t['name']}"
|
|
getCountryById[t['id']] = t['country']
|
|
getNameById[t['id']] = t['name']
|
|
|
|
|
|
countries = list(set(t['country'] for t in teams))
|
|
teams_from_country = {
|
|
c:[t for t in teams if t['country']==c] for c in countries
|
|
}
|
|
|
|
pot = {i:[] for i in range(1,7)}
|
|
teams_from_pot = {i:[] for i in range(1,7)}
|
|
team_ids_from_pot = {i:[] for i in range(1,7)}
|
|
for t in teams:
|
|
pot[t['pot']].append(t)
|
|
teams_from_pot[t['pot']].append(t)
|
|
team_ids_from_pot[t['pot']].append(t['id'])
|
|
|
|
|
|
teams = list(teams)
|
|
|
|
def check_feasible(fixed_games):
|
|
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:
|
|
|
|
# play every pot
|
|
for p in range(1,7):
|
|
model.addConstraint(xp.Sum(x[t['id'],t2['id']]+x[t2['id'],t['id']] for t2 in pot[p] if (t['id'],t2['id']) in x.keys()) == 1)
|
|
|
|
model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[1]+pot[2] if (t['id'],t2['id']) in x.keys()) == 1)
|
|
model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[1]+pot[2] if (t2['id'],t['id']) in x.keys()) == 1)
|
|
|
|
model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[3]+pot[4] if (t['id'],t2['id']) in x.keys()) == 1)
|
|
model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[3]+pot[4] if (t2['id'],t['id']) in x.keys()) == 1)
|
|
|
|
model.addConstraint(xp.Sum(x[t['id'],t2['id']] for t2 in pot[5]+pot[6] if (t['id'],t2['id']) in x.keys()) == 1)
|
|
model.addConstraint(xp.Sum(x[t2['id'],t['id']] for t2 in pot[5]+pot[6] 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)
|
|
|
|
start_time = time()
|
|
model.solve()
|
|
comp_time = time()-start_time
|
|
|
|
if model.getProbStatus() != 6:
|
|
# print("INFEASIBLE FOUND")
|
|
return False
|
|
else:
|
|
fixed_games = [(i,j) for (i,j) in x.keys() if model.getSolution(x[(i,j)]) == 1]
|
|
return fixed_games
|
|
|
|
|
|
fixed_games = check_feasible([])
|
|
|
|
|
|
|
|
# %%
|
|
# print(fixed_games)
|
|
|
|
|
|
# if not fixed_games:
|
|
# if True:
|
|
|
|
if True:
|
|
print(f"\t{i}: INFEASIBLE FOUND")
|
|
|
|
# html = f"<h1>{i}</h1>"
|
|
html = f"<h1></h1>"
|
|
html += "<table>"
|
|
html += " \
|
|
<style> \
|
|
table, th, td { \
|
|
border: 1px solid black; \
|
|
border-collapse: collapse; \
|
|
text-align: center; \
|
|
min-width:40px; \
|
|
padding:3px; \
|
|
margin: 3px; \
|
|
font-family : Verdana, sans-serif;\
|
|
} \
|
|
h1 {\
|
|
font-family : Verdana, sans-serif;\
|
|
}\
|
|
</style> \
|
|
"
|
|
|
|
color = {
|
|
'0':'#000000',
|
|
'1':'#FF0000',
|
|
'2':'#00FF00',
|
|
'3':'#0000FF',
|
|
'4':'#FFFF00',
|
|
'5':'#FF00FF',
|
|
'6':'#00FFFF',
|
|
'7':'#777777',
|
|
'8':'#FFFFFF',
|
|
'9':'#FFA500',
|
|
'X1':'#CCCCCC',
|
|
'X2':'#BBBBBB',
|
|
'X3':'#AAAAAA',
|
|
'X4':'#999999',
|
|
'X5':'#888888',
|
|
'X6':'#777777',
|
|
'X7':'#666666',
|
|
'X8':'#555555',
|
|
}
|
|
|
|
font = defaultdict(lambda: '#000000')
|
|
font['0'] = '#FFFFFF'
|
|
|
|
|
|
|
|
html += "<tr><td></td>"
|
|
for j in range(1,7):
|
|
html += f"<td>{j}</td>"
|
|
html += "</tr>"
|
|
for k in ['A','B','C','D','E','F']:
|
|
html += f"<tr><td>{k}</td>"
|
|
for j in range(1,7):
|
|
team = teams_dict[f"{k}{j}"]
|
|
html += f"<td style='color:{font[str(team['country'])]};background-color:{color[str(team['country'])]}'>{team['id']}</td>"
|
|
html += "</tr>"
|
|
html += "</table>"
|
|
|
|
html += "<br><br>"
|
|
|
|
html += f"<h1>INFEASIBLE FOUND</h1>"
|
|
with open(f"infeasible/{i}.html", "w") as f:
|
|
f.write(html)
|
|
|
|
|
|
|
|
|
|
# %%
|
|
|
|
|
|
# n = sys.maxsize
|
|
|
|
# pool = Pool()
|
|
# result = {}
|
|
# answer = {}
|
|
|
|
# for cpu in range(1,2):
|
|
# result[cpu] = pool.apply_async(simulate_draws, args=(f'3_thread_{cpu}', n,))
|
|
|
|
# for cpu in range(1,2):
|
|
# answer[cpu] = result[cpu].get()
|
|
|
|
|
|
|
|
|
|
|
|
# # # SOLUTION
|
|
|
|
|
|
# opponents = {t['name']:[] for t in teams}
|
|
# for g in fixed_games:
|
|
# opponents[getNameById[g[0]]].append(getNameById[g[1]])
|
|
# opponents[getNameById[g[1]]].append(getNameById[g[0]])
|
|
|
|
|
|
# for t in teams:
|
|
# opponents[t['name']] = list(set(opponents[t['name']]))
|
|
|
|
# # %%
|
|
|
|
# cells = {
|
|
# (i,j):[] for i in ['A','B','C','D'] for j in range(1,10)
|
|
# }
|
|
|
|
# for team in teams:
|
|
# for opponent in opponents[team['name']]:
|
|
# cells[(opponent[0],int(opponent[1]))].append(team['name'])
|
|
|
|
|
|
|
|
# html = "<table>"
|
|
# html += " \
|
|
# <style> \
|
|
# table, th, td { \
|
|
# border: 1px solid black; \
|
|
# border-collapse: collapse; \
|
|
# text-align: center; \
|
|
# min-width:40px; \
|
|
# padding:3px; \
|
|
# margin: 3px; \
|
|
# font-family : Verdana, sans-serif;\
|
|
# } \
|
|
# h1 {\
|
|
# font-family : Verdana, sans-serif;\
|
|
# }\
|
|
# </style> \
|
|
# "
|
|
|
|
# color = {
|
|
# '1':'#FF0000',
|
|
# '2':'#00FF00',
|
|
# '3':'#0000FF',
|
|
# '4':'#FFFF00',
|
|
# '5':'#FF00FF',
|
|
# '6':'#00FFFF',
|
|
# '7':'#777777',
|
|
# '8':'#FFFFFF',
|
|
# '9':'#FFA500',
|
|
# }
|
|
|
|
|
|
|
|
# html += "<tr><td></td>"
|
|
# for j in range(1,10):
|
|
# html += f"<td style='background-color:{color[str(j)]}'>{j}</td>"
|
|
# html += "</tr>"
|
|
# for i in ['A','B','C','D']:
|
|
# html += f"<tr><td>{i}</td>"
|
|
# for j in range(1,10):
|
|
# html += f"<td>"
|
|
# for e in sorted(cells[(i,j)]):
|
|
# if e in ['A1','A2','B1','B2','C1','C2','D1']:
|
|
# html += f"<span style='background-color:{color[e[1]]}'>{e}</span><br>"
|
|
# html+=f"</td>"
|
|
# html += "</tr>"
|
|
# html += "</table>"
|
|
|
|
|
|
# # for g in fixed_games:
|
|
# # if getNameById[g[0]] in ['A1','A2'] or getNameById[g[1]] in ['A1','A2']:
|
|
# # print(getTeamById[g[0]],getTeamById[g[1]])
|
|
|
|
|
|
# # print("\n\n")
|
|
|
|
# # for g in fixed_games:
|
|
# # if getNameById[g[0]] in ['B1','B2'] or getNameById[g[1]] in ['B1','B2']:
|
|
# # print(getTeamById[g[0]],getTeamById[g[1]])
|
|
|
|
# # print("\n\n")
|
|
|
|
# # for g in fixed_games:
|
|
# # if getNameById[g[0]] in ['C1','C2'] or getNameById[g[1]] in ['C1','C2']:
|
|
# # print(getTeamById[g[0]],getTeamById[g[1]])
|
|
|
|
|
|
# # print("\n\n")
|
|
|
|
# # for g in fixed_games:
|
|
# # if getNameById[g[0]] in ['D1'] or getNameById[g[1]] in ['D1']:
|
|
# # print(getTeamById[g[0]],getTeamById[g[1]])
|
|
|
|
|
|
|
|
# # %%
|
|
# connected_components= {}
|
|
# t_pot ={ t['id'] : t['pot'] for t in teams}
|
|
# pots=sorted(list(set(t['pot'] for t in teams)))
|
|
# for p1 in pots:
|
|
# for p2 in pots:
|
|
# if p1<=p2:
|
|
# # print ("POTS ",p1, p2, ":")
|
|
# theseGames= [ (t1,t2) for (t1,t2) in fixed_games if (t_pot[t1],t_pot[t2]) in [(p1,p2),(p2,p1)] ]
|
|
# G = nx.Graph(theseGames)
|
|
# cntr=0
|
|
# connected_components[p1,p2]=""
|
|
# for c in nx.connected_components(G):
|
|
# cntr+=1
|
|
# # print (" COMP" ,cntr, list (c))
|
|
# connected_components[p1,p2]+=str(len(c))+", "
|
|
# connected_components[p1,p2]=connected_components[p1,p2][:-2]
|
|
# connected_components[p2,p1]=connected_components[p1,p2]
|
|
|
|
|
|
# extraTable = "<table><tr><th> </th>"
|
|
# for p1 in pots:
|
|
# extraTable += "<th style='width:150px'> Pot " + str(p1)+ "</th>"
|
|
# extraTable += "</tr>"
|
|
|
|
# for p1 in pots:
|
|
# extraTable += "<tr><th style='width:150px'> Pot " + str(p1)+ "</th>"
|
|
# for p2 in pots:
|
|
# extraTable += "<td> " +connected_components[p1,p2] + "</td>"
|
|
# extraTable += "</tr>"
|
|
# extraTable += "</table>"
|
|
|
|
|
|
|
|
# # write html to file
|
|
# with open("table.html", "w") as f:
|
|
# f.write(html)
|
|
# f.write("<br><br>")
|
|
# f.write(extraTable)
|
|
|
|
|
|
# # %%
|
|
|
|
# %%
|