Update Feb24

This commit is contained in:
martin 2024-02-28 12:52:40 +01:00
parent 61e68b069b
commit 7620e297de
21 changed files with 1510 additions and 101 deletions

82
celery/script.py Normal file
View File

@ -0,0 +1,82 @@
# %%
import os
import time
from celery import Celery
from celery.result import AsyncResult
from celery.contrib.abortable import AbortableAsyncResult
# Conference.objects.filter(scenario=scenario,name__in=["UEL","UECL"]).update(reopt=True)
CELERY_RESULT_BACKEND="redis://localhost:6379"
CELERY_BROKER_URL="redis://localhost:6379"
celery = Celery('leagues',
backend=CELERY_RESULT_BACKEND,
broker=CELERY_BROKER_URL
)
celery.conf.update(
worker_redirect_stdouts=False,
timezone='Europe/Berlin',
worker_hijack_root_logger=False,
)
celery.autodiscover_tasks()
# Inspect all nodes.
i = celery.control.inspect()
# Show the items that have an ETA or are scheduled for later processing
i.scheduled()
# Show tasks that are currently active.
i.active()
# Show tasks that have been claimed by workers
i.reserved()
# # # SEND TASK
# # task = celery.send_task('test_task', args=[], kwargs={})
# task = AbortableAsyncResult('b5b1bfff-318c-4052-bbec-f758a1e5925e')
# task.revoke(terminate=True)
# while not task.ready():
# print(task.result)
# print(task.info)
# print(task.state)
# print(task.traceback)
# print(task.task_id)
# print(task.status)
# time.sleep(1)
# # REVOKE TASK
# celery.control.revoke('task.id', terminate=True)
# # # GET TASK RESULT
# job = AbortableAsyncResult('b5b1bfff-318c-4052-bbec-f758a1e5925e')
# job.update_state(state='SUCCESS', result='result')
# %%
#
print(job.status,job.info)
# %%
# l = [{2:"d"},{1:"b"}]
# def test(a):
# a = sorted(a, key=lambda x: list(x.keys())[0])
# a[0][2] = "Z"
# a.append({3:"c"})
# print(a)
# return a
# print(l)
# g = test(l)
# print(l)
# print(g)
# %%

41
celery/task.py Normal file
View File

@ -0,0 +1,41 @@
from .tasks.optimize import optimize
from .functions import *
import json
from celery.contrib.abortable import AbortableTask
from leagues.celery import celery, TASK_TIME_LIMIT
from leagues.settings import RUN_ENV, SOLVER
from scheduler.models import *
@celery.task(name='test_task', bind=True, time_limit=TASK_TIME_LIMIT, base=AbortableTask)
def test_task(self):
status_dict = {
c: {} for c in range(10)
}
i = 0
c = 0
terminate = False
self.update_state(state='STARTED', meta={'info':c})
while(c < 10):
i += 1
status_dict[c][i] = "".join(random.choices(["A","B","C","D","E","F","G","H","I","J"], k=100))
status_dict['info'] = "RUNNING"
self.update_state(state='TESTING', meta=json.dumps(status_dict))
if i == 100000:
c += 1
i = 0
print("TESTING",c)
if terminate:
return "TEST ABORTED"
if self.is_aborted():
terminate = True
return "TEST SUCCESSFULL"

View File

@ -332,7 +332,7 @@ class Draw_Simulator:
self.pots = ['D','C','B','A']
if use_db:
scenario_id = 10081
scenario_id = 9529
scenario = Scenario.objects.get(id=scenario_id)
self.basepots = {
@ -1039,8 +1039,9 @@ class Draw_Simulator:
visited_countries[t1['id']].add(t2['country'])
blockings, breaks = self.create_schedule(sol_dict, n)
# blockings, breaks = self.create_schedule(sol_dict, n)
blockings = defaultdict(lambda:0)
breaks = defaultdict(lambda:0)
@ -1158,7 +1159,7 @@ class Draw_Simulator:
# print("\t",game[0],game[1],sol_dict[game[0]][game[1]])
# for game in self.awayGames[g, p]:
# print("\t",game[0],game[1],sol_dict[game[0]][game[1]])
base_scenario_id = 10081
base_scenario_id = 9529
base_scenario = Scenario.objects.get(id=base_scenario_id)
scenario = copy_scenario(base_scenario,f" - {self.opponent_func.__name__} - {nSim}")
@ -1283,7 +1284,7 @@ funcs = [
]
scenario_id = 10081
scenario_id = 9529
scenario = Scenario.objects.get(id=scenario_id)
Scenario.objects.filter(base_scenario=scenario).delete()
@ -1291,7 +1292,7 @@ Scenario.objects.filter(base_scenario=scenario).delete()
stats = {}
for func in funcs:
simulator = Draw_Simulator(algorithm='XP', opponent_func = func, html_output=True,use_db=True)
nSim = 1000
nSim = 5
stats[func.__name__] = simulator.simulate(nSim)

0
research/__init__.py Normal file
View File

3
research/admin.py Normal file
View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

5
research/apps.py Normal file
View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class ResearchConfig(AppConfig):
name = 'research'

View File

289
research/ml/learners.py Normal file
View File

@ -0,0 +1,289 @@
from django.db.models import F
import pandas as pd
import pickle
from sklearn.preprocessing import OneHotEncoder
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.ensemble import GradientBoostingRegressor
from scheduler.models import *
from common.functions import distanceInKmByGPS
class AttendanceLearner:
def __init__(self,season_id):
self.season = Season.objects.filter(id=season_id).first()
self.rf_regressor = None
self.predictions = None
self.ids = []
def save(self):
with open('research/ml/models/{}.mod'.format(self.season.id), 'wb') as f:
pickle.dump(self.rf_regressor, f)
def load(self):
with open('research/ml/models/{}.mod'.format(self.season.id), 'rb') as f:
self.rf_regressor = pickle.load(f)
def __get_pivot_tables(self):
games = Game.objects.filter(season=self.season).exclude(historic_season=None)
# create dataset
df = pd.DataFrame.from_records(games.values())
# remove outliers
out_fields = ['attendance']
for field in out_fields:
q_low = df[field].quantile(0.01)
q_hi = df[field].quantile(0.99)
df = df[(df[field] < q_hi) & (df[field] > q_low)]
# pivots
pivot_table = {}
pivot_table['homeTeam_mean_attendance'] = df.pivot_table('attendance','homeTeam_id',aggfunc='mean')
pivot_table['homeTeam_max_attendance'] = df.pivot_table('attendance','homeTeam_id',aggfunc='max')
return pivot_table
def __prepare_training_data(self):
games = Game.objects.filter(season=self.season).exclude(historic_season=None).annotate(
home=F('homeTeam__shortname'),
away=F('awayTeam__shortname'),
home_lat=F('homeTeam__latitude'),
home_lon=F('homeTeam__longitude'),
home_attr=F('homeTeam__attractivity'),
away_lat=F('awayTeam__latitude'),
away_lon=F('awayTeam__longitude'),
away_attr=F('awayTeam__attractivity'),
home_country=F('homeTeam__country'),
away_country=F('awayTeam__country'),
)
# create dataset
df = pd.DataFrame.from_records(games.values())
# data cleaning
df['time'] = df['time'].replace('','0')
df = df[df['attendance'] != 0]
# remove outliers
out_fields = ['attendance']
for field in out_fields:
q_low = df[field].quantile(0.01)
q_hi = df[field].quantile(0.99)
df = df[(df[field] < q_hi) & (df[field] > q_low)]
# pivots
self.pivot_homeTeam_mean = df.pivot_table('attendance','homeTeam_id',aggfunc='mean')
self.pivot_homeTeam_max = df.pivot_table('attendance','homeTeam_id',aggfunc='max')
# add more features
df['weekday'] = df.apply(lambda r: r['date'].weekday(), axis=1)
df['day'] = df.apply(lambda r: r['date'].day, axis=1)
df['month'] = df.apply(lambda r: r['date'].month, axis=1)
df['year'] = df.apply(lambda r: r['date'].year, axis=1)
df['distance'] = df.apply(lambda r: distanceInKmByGPS(r['home_lon'],r['home_lat'],r['away_lon'],r['away_lat']), axis=1)
df['weekend'] = df.apply(lambda r: int(r['weekday'] in [6,7]), axis=1)
df['winter_season'] = df.apply(lambda r: int(r['month'] in [1,2,3,10,11,12]), axis=1)
df['home_base'] = df.apply(lambda r: self.pivot_homeTeam_mean.loc[r['homeTeam_id'],'attendance'], axis=1)
df['stadium_size'] = df.apply(lambda r: self.pivot_homeTeam_max.loc[r['homeTeam_id'],'attendance'], axis=1)
df['early'] = df.apply(lambda r: r['time'].replace(':','') < "1800", axis=1)
df['before2010'] = df.apply(lambda r: r['historic_season'].split('-')[0] < "2010", axis=1)
# one hot encoding
ohe_fields = ['home_country']
for field in ohe_fields:
ohe = OneHotEncoder()
transformed = ohe.fit_transform(df[[field]])
df[ohe.categories_[0]] = transformed.toarray()
# sort label to last index
cols = list(df.columns)
cols.append(cols.pop(cols.index('attendance')))
df = df[cols]
remove_columns = ['season_id', 'resultEntered', 'reversible', 'reschedule', 'homeGoals', 'awayGoals',
'homeGoals2', 'awayGoals2', 'homeGoals3', 'awayGoals3', 'home', 'away', 'date', 'time',
'id', 'homeTeam_id', 'awayTeam_id', 'historic_season',
'home_country','home_lat','home_lon','away_lat','away_lon','away_country','year']
feature_cols = list(set(df.columns[:-1]) - set(remove_columns))
label = 'attendance'
self.X = df[feature_cols]
self.y = df[label]
def __prepare_prediction_data(self):
games = Game.objects.filter(season=self.season,historic_season=None).annotate(
home=F('homeTeam__shortname'),
away=F('awayTeam__shortname'),
home_lat=F('homeTeam__latitude'),
home_lon=F('homeTeam__longitude'),
home_attr=F('homeTeam__attractivity'),
away_lat=F('awayTeam__latitude'),
away_lon=F('awayTeam__longitude'),
away_attr=F('awayTeam__attractivity'),
home_country=F('homeTeam__country'),
away_country=F('awayTeam__country'),
)
# create dataset
df = pd.DataFrame.from_records(games.values())
self.ids = list(df['id'].values)
# pivots
pivot_tables = self.__get_pivot_tables()
# add more features
df['weekday'] = df.apply(lambda r: r['date'].weekday(), axis=1)
df['day'] = df.apply(lambda r: r['date'].day, axis=1)
df['month'] = df.apply(lambda r: r['date'].month, axis=1)
df['year'] = df.apply(lambda r: r['date'].year, axis=1)
df['distance'] = df.apply(lambda r: distanceInKmByGPS(r['home_lon'],r['home_lat'],r['away_lon'],r['away_lat']), axis=1)
df['weekend'] = df.apply(lambda r: int(r['weekday'] in [6,7]), axis=1)
df['winter_season'] = df.apply(lambda r: int(r['month'] in [1,2,3,10,11,12]), axis=1)
df['home_base'] = df.apply(lambda r: pivot_tables['homeTeam_mean_attendance'].loc[r['homeTeam_id'],'attendance'], axis=1)
df['stadium_size'] = df.apply(lambda r: pivot_tables['homeTeam_max_attendance'].loc[r['homeTeam_id'],'attendance'], axis=1)
df['early'] = df.apply(lambda r: r['time'].replace(':','') < "1800", axis=1)
df['before2010'] = df.apply(lambda r: 0, axis=1)
# one hot encoding
ohe_fields = ['home_country']
for field in ohe_fields:
ohe = OneHotEncoder()
transformed = ohe.fit_transform(df[[field]])
df[ohe.categories_[0]] = transformed.toarray()
# sort label to last index
cols = list(df.columns)
cols.append(cols.pop(cols.index('attendance')))
df = df[cols]
remove_columns = ['season_id', 'resultEntered', 'reversible', 'reschedule', 'homeGoals', 'awayGoals',
'homeGoals2', 'awayGoals2', 'homeGoals3', 'awayGoals3', 'home', 'away', 'date', 'time',
'id', 'homeTeam_id', 'awayTeam_id', 'historic_season',
'home_country','home_lat','home_lon','away_lat','away_lon','away_country','year']
feature_cols = list(set(df.columns[:-1]) - set(remove_columns))
label = 'attendance'
print (feature_cols)
self.X = df[feature_cols]
self.y = df[label]
def train(self):
self.__prepare_training_data()
X_train, X_test, y_train, y_test = train_test_split(
self.X, self.y, test_size=0.3, random_state=1)
# self.rf_regressor = RandomForestRegressor(n_estimators = 200 , random_state = 42)
self.rf_regressor = GradientBoostingRegressor(n_estimators = 200 , random_state = 42)
self.rf_regressor.fit(X_train,y_train)
self.score = self.rf_regressor.score(X_test,y_test)
def predict(self):
self.__prepare_prediction_data()
print(len(self.ids))
print(len(self.rf_regressor.predict(self.X)))
self.predictions = dict(zip(self.ids,self.rf_regressor.predict(self.X)))
print(self.rf_regressor.predict(self.X))
print(self.predictions)
def predict_games(self,games):
teamObjects = Team.objects.filter(season=self.season ).values()
dayObjects = Day.objects.filter(season=self.season ).values()
teams=[]
t_name={}
t_country={}
t_lon = {}
t_lat = {}
t_attractivity ={}
getTeamById={}
for t in teamObjects:
# print (t['name'], t['id'])
teams.append(t['id'])
t_name[t['id']]= t['name']
t_country[t['id']]= t['country']
t_attractivity[t['id']]=t['attractivity']
t_lon[t['id']]=t['longitude']
t_lat[t['id']]=t['latitude']
getTeamById[t['id']]=t['name']
distance ={}
distanceById ={}
attractivity ={}
travelDict= self.season.travelDict()
for t1 in teamObjects:
for t2 in teamObjects:
# print (t1['name'],t2['name'],distance[t1['name'],t2['name']] ," -> ", travelDict[t1['id']][t2['id']]['distance'] )
distance[t1['id'],t2['id']] = travelDict[t1['id']][t2['id']]['distance']
attractivity[t1['id'],t2['id']] = int(100*t1['attractivity']*t2['attractivity']);
wds= {0:'Mon', 1:'Tue', 2:'Wed', 3:'Thu', 4:'Fri', 5:'Sat', 6:'Sun'}
dayObjects = Day.objects.filter(season=self.season).values()
days = [ d['id'] for d in dayObjects ]
d_round = { d['id'] : d['round'] for d in dayObjects }
getDateTimeDay={}
getNiceDay={}
getWeekDay={}
getMonth={}
getRound={}
days = [ d['id'] for d in dayObjects if d['round']>0 ]
for d in dayObjects:
dt = parse(d['day'])
getDateTimeDay[d['id']] = dt
getNiceDay[d['id']] = str(dt.strftime('%a, %b %d, %Y'))
getWeekDay[d['id']] = str(wds[dt.weekday()])
getMonth[d['id']] = dt.month
def getFeatureVector(t1,t2,d):
gm={'homeTeam_id': t1, 'awayTeam_id': t2, 'month': d.month,
'home_attractivity': t_attractivity[t1], 'away_attractivity': t_attractivity[t2],
'weekday': d.weekday, 'home_lat': t_lat[t1] , 'home_lon': t_lon[t1] ,
'away_lat': t_lat[t2], 'away_lon': t_lon[t2], 'weekday': d.weekday in [1,2,3,4],
# 'home_country': t_country[t1], 'away_country': t_country[t2] ,
'distance' : distance[t1,t2]}
return list(gm.values())
games_train = Game.objects.filter(season=self.season).exclude(historic_season=None)
self.X= []
self.y =[]
for game in games_train:
self.X.append(getFeatureVector(game.homeTeam.id, game.awayTeam.id,game.date) )
self.y.append(game.attendance)
X_train, X_test, y_train, y_test = train_test_split(
self.X, self.y, test_size=0.3, random_state=1)
# self.rf_regressor = RandomForestRegressor(n_estimators = 200 , random_state = 42)
self.rf_regressor = GradientBoostingRegressor(n_estimators = 200 , random_state = 42)
self.rf_regressor.fit(X_train,y_train)
self.score = self.rf_regressor.score(X_test,y_test)
print (self.score)
self.X= []
self.y =[]
for (t1,t2,d) in games:
self.X.append(getFeatureVector(t1,t2,getDateTimeDay[d]) )
result = dict(zip(games,self.rf_regressor.predict(self.X)))
for g in games:
result[g] = int (result[g])
return result

4
research/ml/models/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore

3
research/models.py Normal file
View File

@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

View File

@ -0,0 +1,84 @@
from scheduler.models import *
from scheduler.helpers import *
from scheduler.solver.optimizer import optimize_2phases, optimize_simulate, optimize_sequentially
from celery.result import AsyncResult
from leagues.settings import RUN_ENV
from leagues.celery import celery
class UefaSimulator:
def __init__(self,scenario_id):
self.scenario = Scenario.objects.get(id=scenario_id)
self.param = {
"NAME":"undefined",
"SIMC":0,
"OPPONENTS":"",
"RUNMODE":"",
"LOCALSEARCHTIME":0,
"RESET":False,
"CREATE_ONLY":False,
"SIM_ONLY":False,
"UCL24PATTERNS":False,
"KEEP_SCENARIOS":False,
}
self.param.update(self.scenario.parse_sim_script())
def simulate(self):
if self.param['RESET'] == "True":
self.scenario.simulation_scenarios.all().delete()
setup = {
'STATS': {
"STARTED":datetime.datetime.now().strftime("%d.%m.%Y, %H:%M:%S"),
"FINISHED":0,
}
}
else:
setup = json.loads(self.scenario.sim_report)
setup['STATS'] = {
"STARTED":datetime.datetime.now().strftime("%d.%m.%Y, %H:%M:%S"),
"FINISHED":0,
}
setup['STATS'].update(self.param)
self.scenario.sim_report = json.dumps(setup)
self.scenario.save()
# RUN SCENARIOS
if RUN_ENV == 'celery':
print("RUNNING IN CELERY")
task = celery.send_task('optimize_simulate',args=[self.scenario.id, self.param, "Simulator", True, self.param['RUNMODE'], int(self.param['LOCALSEARCHTIME'])])
self.scenario.task_id = task.id
self.scenario.stopComputation = False
self.scenario.save()
else:
optimize_simulate(self.scenario.id, self.param, "Simulator", True, runMode=self.param['RUNMODE'], localsearch_time=int(self.param['LOCALSEARCHTIME']))
def improve(self):
# IMPROVE ALL SCENARIOS SCENARIOS
scenarios = []
if self.scenario.sim_report:
kpis = json.loads(self.scenario.sim_report)
for kpi in kpis:
if kpi.isnumeric() and Scenario.objects.filter(id=kpi).exists():
scenarios.append(kpi)
if RUN_ENV == 'celery':
task = celery.send_task('optimize_sequentially',args=[scenarios, "Simulator", True, self.param['RUNMODE'], int(self.param['LOCALSEARCHTIME'])])
self.scenario.task_id = task.id
self.scenario.stopComputation = False
self.scenario.save()
else:
optimize_sequentially(scenarios, user_name="Simulator", user_is_staff=True, runMode=self.param['RUNMODE'], localsearch_time=int(self.param['LOCALSEARCHTIME']))

3
research/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

18
research/urls.py Normal file
View File

@ -0,0 +1,18 @@
from django.urls import re_path
from research.views import *
from common.decorators import admin_only
app_name = 'research'
# Learners
urlpatterns = [
re_path(r'^master_attendance/$', admin_only(master_attendance), name='master_attendance'),
re_path(r'^histgames/$', admin_only(histgames), name='histgames'),
]
# Simulator
urlpatterns += [
re_path(r'^simulator/$', admin_only(simulator), name='simulator'),
re_path(r'^simulation_report/$', admin_only(simulation_report), name='simulation_report'),
]

356
research/views.py Normal file
View File

@ -0,0 +1,356 @@
from django.http import JsonResponse, HttpResponse
from django.shortcuts import render
import json
import csv
from scheduler.models import *
from scheduler.views_func import ComputationProgressView
from .ml.learners import AttendanceLearner
from .simulator.simulator import UefaSimulator
def histgames(request):
games = Game.objects.filter(season=request.session['season'])
context = {
'games': games
}
return render(request, 'historic_games.html', context)
def master_attendance(request):
if request.method == 'GET':
season = Season.objects.filter(id=request.session['season'])
context = {
'season': season
}
return render(request, 'attendance.html', context)
elif request.method == "POST":
if request.POST['type'] == 'train':
print("TRAINING")
learner = AttendanceLearner(request.session['season'])
learner.train()
learner.save()
return JsonResponse({'score': learner.score})
elif request.POST['type'] == 'predict':
print("PREDICT")
scenario = Scenario.objects.get(id=request.session['scenario'])
def createGamesFromSolution(scenario_id):
scenario = Scenario.objects.get(id=scenario_id)
season = scenario.season
games = []
Game.objects.filter(
season=season, historic_season=None).delete()
for game in scenario.solutionlist():
day = Day.objects.get(id=game[0])
home = Team.objects.get(id=game[1])
away = Team.objects.get(id=game[2])
round = game[3]
time = game[4]
games.append(Game(
season=season,
homeTeam=home,
awayTeam=away,
round=round,
date=parse(day.day),
time=time,
))
Game.objects.bulk_create(games)
createGamesFromSolution(scenario.id)
learner = AttendanceLearner(request.session['season'])
learner.load()
learner.predict()
games = Game.objects.filter(
season=scenario.season, historic_season=None)
for g in games:
g.attendance = learner.predictions[g.id]
g.save()
return JsonResponse({})
def simulator(request):
if request.method == "GET":
scenario = Scenario.objects.get(id=request.session['scenario'])
response = json.loads(ComputationProgressView(request).content)
progress = response['task_status'] if 'task_status' in response else ""
scenarios = []
scenarios_exist = []
all_kpis = []
get_kpi = defaultdict(lambda:{})
get_kpi_text = defaultdict(lambda:{})
if scenario.sim_report:
kpis = json.loads(scenario.sim_report)
scenarios = list(kpis.keys())[1:]
for s in scenarios:
for kpi in [kpit.split("__") for kpit in kpis[s].split("___")]:
if not kpi[0] in all_kpis:
all_kpis.append(kpi[0])
get_kpi_val = { (s,kpi) : 0 for s in scenarios for kpi in all_kpis}
for s in scenarios:
scenarioObj = Scenario.objects.filter(id=s).first()
kpis_dict = {}
if scenarioObj:
scenarios_exist.append(str(scenarioObj.id))
# If exists update with most recent data
if scenarioObj.sol_kpis != "":
for kpi in scenarioObj.kpis():
kpis_dict[kpi[0]] = kpi[1:]
kpis_dict["Datetime"] = [scenarioObj.lastComputation.strftime('%Y:%m:%d-%H:%M:%S'),""]
for kpi in [kpit.split("__") for kpit in kpis[s].split("___")]:
des1=kpi[0]
val1= kpis_dict[des1][0] if des1 in kpis_dict else kpi[1]
get_kpi[s][des1]= val1
val1=(val1.split(" "))[0]
if val1.isnumeric():
get_kpi_val[(s, des1)]= int(float(val1))
if len(kpi)>2:
if des1 in kpis_dict and len(kpis_dict[des1])>1:
get_kpi_text[s][des1]= kpis_dict[des1][1]
else:
get_kpi_text[s][des1]= kpi[2]
# else:
# get_kpi_text[s][des1] = val1
#
all_kpis=[kpi for kpi in all_kpis if len([sc for sc in scenarios if get_kpi[sc][kpi] != "0 of 0" ])>0]
context = {
'scenario': scenario,
'scenarios':scenarios,
'scenarios_exist':scenarios_exist,
'all_kpis':all_kpis,
'get_kpi': get_kpi,
'get_kpi_text': get_kpi_text,
'progress':progress
}
return render(request, "simulator.html", context)
elif request.method == "POST":
if request.POST['method'] == "submit_params":
s = Scenario.objects.get(id=request.session['scenario'])
s.sim_script = request.POST['payload'].replace("\n", ";").replace("\"","").replace("\'","")
s.save()
return HttpResponse("OK")
elif request.POST['method'] == "start_simulation":
s = Scenario.objects.get(id=request.session['scenario'])
sim = UefaSimulator(s.id)
sim.simulate()
return HttpResponse("OK")
elif request.POST['method'] == "start_improvement":
s = Scenario.objects.get(id=request.session['scenario'])
sim = UefaSimulator(s.id)
sim.improve()
return HttpResponse("OK")
def findall(p, s):
i = s.find(p)
while i != -1:
yield i
i = s.find(p, i+1)
def simulation_report(request):
baseScenario = Scenario.objects.get(id=request.session['scenario'])
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="{}_{}_violations.csv"'.format(baseScenario.season.nicename,baseScenario.name)
writer = csv.writer(response,delimiter=",")
# writer.writerow(['', 'Team Name', 'Date', 'Type', 'Time', 'Comment', 'Tag'])
# for b in Blocking.objects.filter(scenario=scenario):
# writer.writerow(["BLOCKING",b.team.name,parse(b.day.day).date(),b.type,b.time,b.comment,b.tag])
prioVal ={'A': 25 , 'B': 5 , 'C': 1, 'Hard' : 1000}
quality_dict = {}
for ref_scenario in baseScenario.simulation_scenarios.all().order_by('name'):
for scenario in ref_scenario.simulation_scenarios.all().order_by('name').reverse():
total_vio = 0
objectiveFunctionWeights = ObjectiveFunctionWeight.objects.filter(scenario=scenario).values()
gew={}
for ow in objectiveFunctionWeights:
gew[ow['name']]= ow['use'] * ow['prio']
if scenario.sol_kpis != "":
kpis_dict = {}
for kpi in scenario.kpis():
kpis_dict[kpi[0]] = kpi[1:]
kpis_dict["Datetime"] = [scenario.lastComputation.strftime('%Y:%m:%d-%H:%M:%S'),""]
uclpatterns = SpecialWish.objects.filter(scenario=scenario,name='UCL24Patterns',active=True).exists()
quality_scen = {"Overall Quality":kpis_dict["Overall Quality"],"Datetime":kpis_dict["Datetime"],"UCLpatterns":[uclpatterns]}
first_row = ["" for i in range(5)]
# PRIO BASED
# for prio in ['Hard','A','B','C']:
# pairing_vios = Pairing.objects.filter(scenario=scenario,prio=prio,active=True).exclude(violation="")
# pairing_viols_count = 0
# for v in pairing_vios:
# pairing_viols_count += len(v.violation.split("__"))
# quality_scen["Pairing"][prio] = [pairing_viols_count,5*prioVal[prio] * pairing_viols_count * gew["Pairings"]]
# total_vio += 5*prioVal[prio] * pairing_viols_count * gew["Pairings"]
# ha_vios = HAWish.objects.filter(scenario=scenario,prio=prio,active=True).exclude(violation="")
# ha_vios_count = 0
# for v in ha_vios:
# many = {}
# few = {}
# for i in range(10):
# many[i] = len(list(findall(f"{i} too many",v.violation)))
# few[i] = len(list(findall(f"{i} too few",v.violation)))
# ha_vios_count += i*(many[i] + few[i])
# quality_scen["HAWish"][prio] = [ha_vios_count,prioVal[prio] * ha_vios_count * gew["Home-/Away"]]
# total_vio += prioVal[prio] * ha_vios_count * gew["Home-/Away"]
# enc_vios = EncWish.objects.filter(scenario=scenario,prio=prio,active=True).exclude(violation="").exclude(violation="Not evaluated yet!")
# enc_vios_count = 0
# for v in enc_vios:
# many = {}
# few = {}
# for i in range(10):
# many[i] = len(list(findall(f"{i} too many",v.violation)))
# few[i] = len(list(findall(f"{i} too few",v.violation)))
# enc_vios_count += i*(many[i] + few[i])
# # for a in s.split(":"):
# # if "too" in a:
# # print("\t",a)
# # ha_vios_count += int(a.split("too")[0].strip())
# # quality_scen["HAWish"][prio] = [ha_vios_count,prioVal[prio] * ha_vios_count * gew["Home-/Away"]]
# quality_scen["EncWish"][prio] = [enc_vios_count,5*prioVal[prio] * enc_vios_count * gew["Encounters"]]
# total_vio += 5*prioVal[prio] * enc_vios_count * gew["Encounters"]
# quality_scen["PAIR+HA+ENC"] = total_vio
dynamic_rows = []
""" PAIRINGS """
pairings = Pairing.objects.filter(scenario=scenario,active=True)
pairing_tags = pairings.values_list('comment',flat=True).distinct()
for tag in pairing_tags:
first_row.append("PAIRINGS")
row = f"{tag}"
dynamic_rows.append(row)
pairing_vios = pairings.filter(comment=tag).exclude(violation="")
pairing_viols_count = 0
pairing_viols_obj = 0
for v in pairing_vios:
pairing_viols_count += len(v.violation.split("__"))
pairing_viols_obj += 5*prioVal[v.prio] * len(v.violation.split("__"))
quality_scen[row] = [pairing_viols_count,pairing_viols_obj * gew["Pairings"]]
total_vio += pairing_viols_obj * gew["Pairings"]
""" HOME AWAY """
tags = Tag.objects.filter(season=scenario.season,scheduler_hawishes__isnull=False).distinct()
for tag in tags:
first_row.append("HOME AWAY")
row = f"{tag.name}"
dynamic_rows.append(row)
ha_vios = tag.scheduler_hawishes.filter(scenario=scenario,active=True).exclude(violation="")
ha_vios_count = 0
ha_vios_obj = 0
for v in ha_vios:
many = {}
few = {}
for i in range(10):
many[i] = len(list(findall(f"{i} too many",v.violation)))
few[i] = len(list(findall(f"{i} too few",v.violation)))
ha_vios_count += i*(many[i] + few[i])
ha_vios_obj += i*(many[i] + few[i]) * prioVal[v.prio]
quality_scen[row] = [ha_vios_count, ha_vios_obj * gew["Home-/Away"]]
total_vio += ha_vios_obj * gew["Home-/Away"]
""" ENCOUNTERS """
tags = Tag.objects.filter(season=scenario.season,scheduler_encwishes__isnull=False).distinct()
for tag in tags:
first_row.append("ENCOUNTERS")
row = f"{tag.name}"
dynamic_rows.append(row)
# enc_vios = EncWish.objects.filter(scenario=scenario,prio=prio,active=True).exclude(violation="").exclude(violation="Not evaluated yet!")
enc_vios = tag.scheduler_encwishes.filter(scenario=scenario,active=True).exclude(violation="").exclude(violation="Not evaluated yet!")
enc_vios_count = 0
enc_vios_obj = 0
for v in enc_vios:
many = {}
few = {}
for i in range(10):
many[i] = len(list(findall(f"{i} too many",v.violation)))
few[i] = len(list(findall(f"{i} too few",v.violation)))
enc_vios_count += i*(many[i] + few[i])
enc_vios_obj += i*(many[i] + few[i]) * prioVal[v.prio] * 5
# for a in s.split(":"):
# if "too" in a:
# print("\t",a)
# ha_vios_count += int(a.split("too")[0].strip())
# quality_scen["HAWish"][prio] = [ha_vios_count,prioVal[prio] * ha_vios_count * gew["Home-/Away"]]
quality_scen[row] = [enc_vios_count,enc_vios_obj * gew["Encounters"]]
total_vio += enc_vios_obj * gew["Encounters"]
quality_scen["PAIR+HA+ENC"] = total_vio
quality_dict[scenario.name] = quality_scen
writer.writerow(first_row[:5]+[""]+first_row[5:]+[""]+first_row[5:])
rows = ["AScenario","Datetime","UCLPatterns","Overall Quality","PAIR+HA+ENC"]
rows += [""]
rows += [f"#({r})" for r in dynamic_rows]
rows += [""]
rows += [f"obj({r})" for r in dynamic_rows]
writer.writerow(rows)
for scenario in quality_dict.keys():
ll = []
ll.append(f"{scenario}")
ll.append(f"{quality_dict[scenario]['Datetime'][0]}")
ll.append(f"{quality_dict[scenario]['UCLpatterns'][0]}")
ll.append(f"{quality_dict[scenario]['Overall Quality'][0]}")
ll.append(f"{quality_dict[scenario]['PAIR+HA+ENC']}")
ll.append("")
for row in dynamic_rows:
ll.append(f"{quality_dict[scenario][row][0]}")
ll.append("")
for row in dynamic_rows:
ll.append(f"{quality_dict[scenario][row][1]}")
writer.writerow(ll)
return response

85
scripts/check_data.py Normal file
View File

@ -0,0 +1,85 @@
# %%
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"
os.environ["XPRESS"] = "/opt/xpressmp/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 *
import pulp
from pulp import lpSum, value, XPRESS, GUROBI, PULP_CBC_CMD
from django.db.models import Q
from django.template.loader import render_to_string
from qualifiers.models import *
from common.models import GlobalTeam, GlobalCountry
from scheduler.models import *
from qualifiers.draws import groupTeams, optimize_inversions4
from scheduler.solver.tasks.optimize import optimize
from scheduler.solver.tasks.optimize_submodels import ueluecl24_basicmodell_v2
from common.security import ESCAPE_WORDS
import random
import time
import json
import csv
import networkx as nx
import matplotlib.pyplot as plt
from datetime import timedelta
from django.contrib.sessions.models import Session
for word in ESCAPE_WORDS:
print("WORD",word)
for hawish in HAWish.objects.all():
if hawish.reason.find(word) >= 0:
print(f"\t{hawish.scenario.season} found |{word}| in |{hawish.reason}|")
for encwish in EncWish.objects.all():
if encwish.reason.find(word) >= 0:
print(f"\t{encwish.scenario.season} found |{word}| in |{encwish.reason}|")
for pairing in Pairing.objects.all():
if pairing.comment.find(word) >= 0:
print(f"\t{pairing.scenario.season} found |{word}| in |{pairing.comment}|")
for team in Team.objects.all():
if team.comments:
if team.comments.find(word) >= 0:
print(f"\t{team.season} found |{word}| in |{team.comments}|")
for blocking in Blocking.objects.all():
if blocking.comment.find(word) >= 0:
print(f"\t{blocking.scenario.season} found |{word}| in |{blocking.comment}|")

78
solver/debug.py Executable file
View File

@ -0,0 +1,78 @@
# %%
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"
os.environ["XPRESS"] = "/opt/xpressmp/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 *
import pulp
from pulp import lpSum, value, XPRESS, GUROBI, PULP_CBC_CMD
from django.db.models import Q
from django.template.loader import render_to_string
from qualifiers.models import *
from common.models import GlobalTeam, GlobalCountry
from scheduler.models import Season, Scenario, Team, DayObj, CountryClash, Country
from qualifiers.draws import groupTeams, optimize_inversions4
from scheduler.solver.tasks.optimize import optimize
from scheduler.solver.tasks.optimize_submodels import ueluecl24_basicmodell_v2
import random
import time
import json
import csv
import networkx as nx
import matplotlib.pyplot as plt
from datetime import timedelta
from django.contrib.sessions.models import Session
scenario = Scenario.objects.get(id=9343)
# scenario = Scenario.objects.get(id=9368)
# scenario = Scenario.objects.get(id=1)
season = scenario.season
s2 = scenario.id
user_name = 'md'
user_is_staff = True
runMode = 'Improve'
localsearch_time = 0
RUN_ENV = 'local'
SOLVER = 'xpress'
sol = optimize(task=None, s2=s2, user_name=user_name, user_is_staff=user_is_staff,
runMode=runMode, localsearch_time=localsearch_time, RUN_ENV=RUN_ENV, solver=SOLVER)

114
uefa/cycle24/research/script.py Executable file
View File

@ -0,0 +1,114 @@
# %%
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"
os.environ["XPRESS"] = "/opt/xpressmp/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 *
import pulp
from pulp import lpSum, value, XPRESS, GUROBI, PULP_CBC_CMD
from django.db.models import Q
from django.template.loader import render_to_string
from scheduler.models import *
import random
import time
import json
import csv
import networkx as nx
import matplotlib.pyplot as plt
from datetime import timedelta
from django.contrib.sessions.models import Session
from pprint import pprint
ucl_basescenario = Scenario.objects.get(id=9543)
# scenario = Scenario.objects.get(id=9368)
# scenario = Scenario.objects.get(id=1)
season = ucl_basescenario.season
days = Day.objects.filter(season=season)
teams = Team.objects.filter(season=season)
getTeamById = {team.id:team for team in teams}
getDayById = {day.id:day for day in days}
user_name = 'md'
user_is_staff = True
runMode = 'New'
localsearch_time = 0
RUN_ENV = 'local'
SOLVER = 'xpress'
solverstats = json.loads(ucl_basescenario.solverstats_json)
solverstats.keys()
# home_in_round = {
# (r,t):0 for t in teams for r in range(1,season.nRounds+1)
# }
# away_in_round = {
# (r,t):0 for t in teams for r in range(1,season.nRounds+1)
# }
# scenarios = season.scenarios.exclude(id=ucl_basescenario.id)
# for scenario in scenarios:
# solverstats = json.loads(scenario.solverstats_json)
# if solverstats.get('info-Improve'):
# print(solverstats['info-Improve'])
# break
# # solution = scenario.sol_solution()
# for game in solverstats['premodell']['partial_solution']:
# home_in_round[(getDayById[game['days'][0]].round,getTeamById[game['home'][0]])] += 1
# away_in_round[(getDayById[game['days'][0]].round,getTeamById[game['away'][0]])] += 1
# # sol = optimize(task=None, s2=ucl_basescenario.id, user_name=user_name, user_is_staff=user_is_staff,
# # runMode=runMode, localsearch_time=localsearch_time, RUN_ENV=RUN_ENV, solver=SOLVER)
# home_in_round = sorted(home_in_round.items(), key=lambda x: x[0][0])
# pprint(home_in_round)
# away_in_round = sorted(away_in_round.items(), key=lambda x: x[0][0])
# pprint(away_in_round)
# %%

View File

@ -0,0 +1,285 @@
import csv
import operator
import os
import random
import sys
import time
import timeit
import datetime
# import networkx as nx
from datetime import datetime
from dateutil.parser import parse
from math import sqrt, pow, sin, cos, atan2, pi
try:
import simplejson as json
except:
import json
from gurobipy import *
# import config
getTeamsOfPot = { p: [ p+str(i) for i in range(1,10) ] for p in ["A","B","C","D"] }
allTeams = getTeamsOfPot['A']+getTeamsOfPot['B']+getTeamsOfPot['C']+getTeamsOfPot['D']
activeTeams= allTeams
pots = getTeamsOfPot.keys()
# print (pots)
gamesAgainst = { (p1,p2) : 2 for p1 in pots for p2 in pots}
# for p in pots:
# gamesAgainst[(p,p)]=2
# for (p1,p2) in [('A','D'), ('D','A'), ('B','C'), ('C','B') ]:
# gamesAgainst[(p1,p2)]=2
nMatchDays=8
# for p1 in pots:
# for p2 in pots:
# print (p1,p2,gamesAgainst[(p1,p2)])
# print()
# print (allTeams)
cntr=0
mbus = Model("Draw")
possAssigns= [ (t1,t2) for t1 in allTeams for t2 in allTeams if t1!=t2]
# print (possAssigns)
plays = mbus.addVars(possAssigns, vtype=GRB.BINARY)
for (t1,t2) in possAssigns:
if t1<t2:
mbus.addConstr( plays[(t1,t2)] ==plays[(t2,t1)] )
for p in pots:
for t in getTeamsOfPot[p]:
for p2 in pots:
mbus.addConstr( quicksum(plays[(t,t2)] for t2 in getTeamsOfPot[p2] if t!=t2 ) == gamesAgainst[(p,p2)])
# for (t1,t2) in [("A1","A2"), ("A2","A3"), ("A3","A1"),
# ("B1","B2"), ("B2","B3"), ("B3","B1"),
# ("C1","C2"), ("C2","C3"), ("C3","C1"),
# # ("D1","D2"), ("D2","D3"), ("D3","D1"),
# ] :
# mbus.addConstr( plays[(t1,t2)] == 1)
# for (p1,p2) in [ ("A","B"), ("B","C"), ("C","D"), ("D","A") ]:
# for (n1,n2) in [ (1,1),(1,2),(3,2),(3,3),(2,3) ,(2,1)]:
# mbus.addConstr( plays[( p1+str(n1) , p2+str(n2))] == 1)
# potpairs = [ (p1,p2) for p1 in pots for p2 in pots if p1!=p2]
# clusters = [[1,2,3], [4,5,6], [7,8,9]]
# for cl in clusters:
# for (p1,p2) in potpairs:
# if len(cl)==2:
# mbus.addConstr( quicksum(plays[( p1+str(n1),p2+str(n2))] for n1 in cl for n2 in cl ) == 4)
# print ( [( p1+str(n1),p2+str(n2)) for n1 in cl for n2 in cl ])
# for (p1,p2) in [ ("A","B"), ("B","C"), ("C","D"), ("D","A") ]:
# for (n1,n2) in [ (1,1),(1,2),(3,2),(3,3),(2,3) ,(2,1)]:
# mbus.addConstr( plays[( p1+str(n1) , p2+str(n2))] == 1)
badExample=False
if badExample:
for p in pots:
for i in [2,3]:
mbus.addConstr( plays[( p+str(i-1),p+str(i))]==1)
# print ( p+str(i-1),p+str(i))
mbus.addConstr( plays[( p+"3",p+"1")]==1)
for p1 in pots:
for i in [1,2,3]:
for p2 in pots:
if p1!=p2:
mbus.addConstr( quicksum(plays[( p1+str(i),p2+str(j))] for j in [4,5,6] ) ==2)
mbus.Params.OutputFlag = 0
debug=False
now = datetime.now()
nSims=10
if len(sys.argv)>1:
nSims=int(sys.argv[1])
solutions =[]
solution_strings =[]
for i in range(nSims):
if i%10==0:
print(i)
cntr+=1
mbus.setObjective(quicksum([ int(100*random.random()) * plays[pa] for pa in possAssigns ]))
# mbus.setObjective(quicksum([ max(0,int(pa[0][1]) - int(pa[1][1] )) * plays[pa] for pa in possAssigns ]))
# print ("DRAWING !!!!")
mbus.optimize()
sol= [ pa for pa in possAssigns if plays[pa].x>0.9]
solutions.append(sol.copy())
if debug:
print ("Solution")
# exit(0)
print ("INPOT")
for p in pots:
print ("")
print ("POT",p)
for (t1,t2) in [(t1,t2) for (t1,t2) in sol if t1<t2 and t1[0]==p and t2[0]==p]:
print ( t1 , "-" , t2)
print ("OUTPOT")
for p in pots:
print ("")
print ("POT",p)
for (t1,t2) in [(t1,t2) for (t1,t2) in sol if t1[0]==p and t2[0]!=p]:
print ( t1 , "-" , t2)
solstring =""
for pa in possAssigns:
solstring+= str(int(plays[pa].x +0.1) )
if nSims < 1000:
solution_strings.append(solstring)
mds =range(1,nMatchDays+1)
pas2= [ (t1,t2,md) for md in mds for (t1,t2) in sol]
# print ("pas2", pas2)
cal = Model("Calendar")
x = cal.addVars(pas2, vtype=GRB.BINARY)
computeCalendarsHA = True
computeCalendarsHA = False
if computeCalendarsHA:
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 ]
# print ("pos_patterns",pos_patterns)
positions = range (len(pos_patterns))
pos = cal.addVars( [(t,p) for t in allTeams for p in positions], vtype=GRB.CONTINUOUS)
for t in allTeams:
cal.addConstr( quicksum( [ pos[t,p] for p in positions ]) ==1)
for md in mds:
cal.addConstr( quicksum(x[(t1,t2,md)] for (t1,t2) in sol if t ==t1 ) == quicksum( [ pos[t,p] for p in positions if pos_patterns[p][md-1]==1 ]) )
for (t1,t2) in sol :
if t1<t2:
cal.addConstr( quicksum(x[(t1,t2,md)] + x[(t2,t1,md)] for md in mds) <=1 )
for t in allTeams:
# every team 4 home games
cal.addConstr( quicksum(x[(t1,t2,md)] for (t1,t2) in sol if t ==t1 for md in mds ) == 4)
# every team one game a day
for md in mds:
cal.addConstr( quicksum(x[(t1,t2,md)] for (t1,t2) in sol if t in [t1,t2] ) == 1)
for p in pots:
for t in getTeamsOfPot[p]:
for p2 in pots:
cal.addConstr( quicksum(x[(t1,t2,md)] for (t1,t2) in sol if t ==t1 and t2 in getTeamsOfPot[p2] for md in mds ) >= int(0.5*gamesAgainst[(p,p2)]) )
else:
for (t1,t2) in sol :
if t1<t2:
cal.addConstr( quicksum(x[(t1,t2,md)] for md in mds) ==1 )
for md in mds:
cal.addConstr( x[(t1,t2,md)] == x[(t2,t1,md)] )
for t in activeTeams:
for md in mds:
cal.addConstr( quicksum(x[(t1,t2,md)] for (t1,t2) in sol if t==t1 ) == 1)
cal.setObjective(quicksum( -x[pa] for pa in x.keys() ))
cal.Params.OutputFlag = 0
# print ("SCHEDULING !!!!")
cal.optimize()
# cal_sol= [pa for pa in x.keys() if x[pa].x>0.9 ]
# print( cal_sol)
# for pa in cal_sol :
# print (pa)
# # print (cal.status)
# print(cal.objVal)
if cal.status!=2 or cal.objVal>-288:
sol= [ (t1,t2) for (t1,t2) in sol if t1<t2]
# sol= [ (t1,t2) for (t1,t2) in sol if t1[0]=="A" and t2[0]=="D" ]
print ("No calendar for ", sol)
print ("Tested " , str(i+1) , " calendars" )
exit(0)
pas2_sol= [ pas for pas in pas2 if x[pas].x>0.9]
# print (pas2_sol)
showSolution= False
showSolution= True
if showSolution and debug:
for md in mds:
print (md,":")
for (t1,t2,md2) in pas2_sol:
# if md2==md and t1<t2 and "C" in [t1[0],t2[0]] :
if md2==md :
print (" " ,t1, " -" ,t2)
for t in activeTeams:
for md in mds:
if not computeCalendarsHA and sum(x[(t1,t2,md)].x for (t1,t2) in sol if t==t1 ) < 1:
print ("ALERT ",t,md)
# print (solutions)
# oldGm = [ gg for gg in solutions[1] if gg not in solutions[0]]
if len(solutions)>1 and showSolution:
newGm = [ gg for gg in solutions[-1] if gg not in solutions[-2]]
# print (oldGm)
# print (newGm)
# print (solution_strings)
print (len(set(solution_strings)) )
f = open("draw_feasibility/log_"+datetime.now().strftime("%Y%m%d_%H%M%S")+"_"+str(nSims)+".txt", "a")
for s in solutions:
for s2 in s:
f.write(s2[0]+s2[1])
f.write("\n")
f.close()
print ("done" , datetime.now()-now )

View File

@ -43,11 +43,12 @@ from django.template.loader import render_to_string
from qualifiers.models import *
from common.models import GlobalTeam, GlobalCountry
from scheduler.models import Season, Scenario, Team, DayObj, CountryClash, Country
from scheduler.models import Season, Scenario, Team, DayObj, CountryClash, Country, Day
from qualifiers.draws import groupTeams, optimize_inversions4
from scheduler.solver.tasks.optimize import optimize
from scheduler.solver.tasks.optimize_submodels import ueluecl24_basicmodell_v2
from scheduler.solver.optimizer import optimize_2phases
import random
import time
@ -60,114 +61,49 @@ from datetime import timedelta
from django.contrib.sessions.models import Session
scenario = Scenario.objects.get(id=9051)
# scenario = Scenario.objects.get(id=9368)
# scenario = Scenario.objects.get(id=1)
season = scenario.season
# scenario = Scenario.objects.get(id=9534)
# scenario = Scenario.objects.get(id=9379)
# scenario = Scenario.objects.get(id=9361)
scenario = Scenario.objects.get(id=9579)
season = scenario.season
s2 = scenario.id
user_name = 'md'
user_is_staff = True
runMode = 'New'
localsearch_time = 0
runMode = 'Improve'
localsearch_time = 30
RUN_ENV = 'local'
SOLVER = 'xpress'
# Conference.objects.filter(scenario=scenario,name__in=["UEL","UECL"]).update(reopt=True)
nRounds = season.nRounds
rounds=range(1,nRounds+1)
dayObjects = Day.objects.filter(season=season).values()
getDays = { r : [] for r in rounds}
for d in dayObjects:
if d['round']>0 :
getDays[d['round']].append(d['id'])
sol = optimize(task=None, s2=s2, user_name=user_name, user_is_staff=user_is_staff,
runMode=runMode, localsearch_time=localsearch_time, RUN_ENV=RUN_ENV, solver=SOLVER)
# sol = optimize_2phases(s2, user_name, user_is_staff, runMode=runMode, localsearch_time=localsearch_time, RUN_ENV=RUN_ENV, SOLVER=SOLVER)
# partial_solution = []
# res_objective, res_games = ueluecl24_basicmodell_v2(SOLVER, s2, partial_solution)
# print(res_games)
# res_games = [(42255, 42321, 1), (42251, 42252, 1), (42244, 42317, 1), (42291, 42288, 1), (42290, 42310, 1), (42289, 42327, 1), (42277, 42282, 1), (42326, 42312, 1), (42325, 42314, 1), (42324, 42280, 1), (42319, 42320, 1), (42316, 42322, 1), (42315, 42273, 1), (42311, 42296, 1), (42313, 42305, 1), (42318, 42299, 1), (42323, 42329, 1), (42328, 42304, 1), (42330, 42336, 2), (42333, 42343, 2), (42250, 42293, 2), (42273, 42290, 2), (42271, 42300, 2), (42253, 42266, 2), (42252, 42311, 2), (42305, 42326, 2), (42304, 42319, 2), (42299, 42289, 2), (42297, 42332, 2), (42296, 42323, 2), (42288, 42277, 2), (42282, 42313, 2), (42280, 42315, 2), (42279, 42348, 2), (42278, 42286, 2), (42346, 42345, 2), (42342, 42254, 2), (42340, 42261, 2), (42339, 42247, 2), (42338, 42331, 2), (42335, 42344, 2), (42329, 42324, 2), (42327, 42328, 2), (42322, 42318, 2), (42321, 42251, 2), (42320, 42316, 2), (42317, 42291, 2), (42314, 42255, 2), (42312, 42244, 2), (42310, 42325, 2), (42307, 42337, 2), (42347, 42349, 2), (42350, 42334, 2), (42267, 42341, 2), (42293, 42307, 3), (42273, 42304, 3), (42266, 42342, 3), (42261, 42267, 3), (42254, 42338, 3), (42247, 42350, 3), (42305, 42312, 3), (42300, 42297, 3), (42299, 42244, 3), (42296, 42315, 3), (42291, 42280, 3), (42290, 42325, 3), (42286, 42333, 3), (42282, 42318, 3), (42277, 42313, 3), (42349, 42339, 3), (42345, 42340, 3), (42344, 42278, 3), (42341, 42346, 3), (42336, 42335, 3), (42348, 42330, 3), (42334, 42253, 3), (42331, 42250, 3), (42329, 42252, 3), (42327, 42317, 3), (42324, 42326, 3), (42322, 42251, 3), (42321, 42314, 3), (42320, 42288, 3), (42316, 42255, 3), (42311, 42319, 3), (42310, 42289, 3), (42328, 42323, 3), (42332, 42271, 3), (42337, 42279, 3), (42343, 42347, 3), (42255, 42311, 4), (42250, 42350, 4), (42271, 42293, 4), (42266, 42333, 4), (42254, 42348, 4), (42253, 42339, 4), (42252, 42305, 4), (42251, 42310, 4), (42244, 42282, 4), (42304, 42290, 4), (42300, 42349, 4), (42289, 42321, 4), (42286, 42340, 4), (42280, 42329, 4), (42277, 42322, 4), (42346, 42336, 4), (42341, 42337, 4), (42342, 42344, 4), (42338, 42297, 4), (42335, 42261, 4), (42334, 42345, 4), (42331, 42330, 4), (42326, 42316, 4), (42325, 42291, 4), (42319, 42273, 4), (42317, 42328, 4), (42315, 42299, 4), (42314, 42327, 4), (42312, 42324, 4), (42313, 42320, 4), (42318, 42296, 4), (42323, 42288, 4), (42332, 42247, 4), (42343, 42279, 4), (42347, 42307, 4), (42267, 42278, 4), (42330, 42254, 5), (42333, 42334, 5), (42293, 42347, 5), (42273, 42312, 5), (42261, 42332, 5), (42247, 42300, 5), (42244, 42315, 5), (42304, 42316, 5), (42299, 42322, 5), (42297, 42250, 5), (42289, 42305, 5), (42288, 42325, 5), (42282, 42327, 5), (42280, 42251, 5), (42279, 42267, 5), (42278, 42335, 5), (42349, 42271, 5), (42345, 42338, 5), (42344, 42253, 5), (42340, 42341, 5), (42339, 42343, 5), (42336, 42342, 5), (42348, 42266, 5), (42326, 42290, 5), (42324, 42255, 5), (42321, 42252, 5), (42320, 42329, 5), (42319, 42310, 5), (42317, 42311, 5), (42307, 42331, 5), (42313, 42314, 5), (42318, 42291, 5), (42323, 42277, 5), (42328, 42296, 5), (42337, 42286, 5), (42350, 42346, 5), (42330, 42342, 6), (42255, 42289, 6), (42250, 42300, 6), (42261, 42346, 6), (42252, 42319, 6), (42251, 42323, 6), (42305, 42244, 6), (42297, 42271, 6), (42296, 42280, 6), (42291, 42324, 6), (42290, 42282, 6), (42288, 42304, 6), (42286, 42293, 6), (42279, 42334, 6), (42278, 42347, 6), (42349, 42332, 6), (42341, 42254, 6), (42340, 42348, 6), (42339, 42338, 6), (42336, 42333, 6), (42335, 42253, 6), (42331, 42266, 6), (42329, 42273, 6), (42327, 42321, 6), (42325, 42320, 6), (42322, 42313, 6), (42316, 42318, 6), (42315, 42328, 6), (42314, 42317, 6), (42312, 42277, 6), (42311, 42326, 6), (42310, 42299, 6), (42307, 42344, 6), (42343, 42247, 6), (42350, 42337, 6), (42267, 42345, 6), (42333, 42339, 7), (42293, 42336, 7), (42271, 42343, 7), (42266, 42297, 7), (42254, 42261, 7), (42253, 42330, 7), (42247, 42279, 7), (42300, 42307, 7), (42346, 42286, 7), (42345, 42331, 7), (42344, 42350, 7), (42342, 42250, 7), (42338, 42349, 7), (42348, 42267, 7), (42334, 42278, 7), (42332, 42341, 7), (42337, 42340, 7), (42347, 42335, 7), (42255, 42325, 7), (42273, 42318, 7), (42305, 42304, 7), (42296, 42288, 7), (42280, 42320, 7), (42277, 42310, 7), (42326, 42319, 7), (42324, 42244, 7), (42322, 42327, 7), (42321, 42290, 7), (42317, 42282, 7), (42315, 42291, 7), (42314, 42252, 7), (42312, 42316, 7), (42311, 42251, 7), (42313, 42329, 7), (42323, 42289, 7), (42328, 42299, 7), (42252, 42328, 8), (42251, 42273, 8), (42244, 42323, 8), (42304, 42313, 8), (42299, 42255, 8), (42291, 42314, 8), (42290, 42311, 8), (42289, 42277, 8), (42288, 42321, 8), (42282, 42280, 8), (42329, 42305, 8), (42327, 42315, 8), (42325, 42322, 8), (42320, 42312, 8), (42319, 42324, 8), (42316, 42317, 8), (42310, 42296, 8), (42318, 42326, 8)]
# ueluecl24_basicmodell_v2(SOLVER,scenario,[],[],maxTime=3600)
# partial_solution = []
# for (t1,t2,r) in res_games:
# partial_solution.append({"home": [t1], "away": [t2], "days": getDays[r], "time": None , "changeable": False })
# %%
# hawishes = HAWish.objects.filter(scenario=scenario)
# # elemHaWishes ={e['id'] : [] for e in hawishes}
# # elemHaWishTeams={}
# # elemHaWishDays ={}
# # elemHaWishFirstDay ={}
# # elemHaWishNum ={}
# cntr =1
# for e in hawishes:
# elemTeams = [[t] for t in e.get_teams()] if e.forEachTeam else [e.get_teams()]
# elemRounds = [[d] for d in e.get_rounds()] if e.forEachDay else [e.get_rounds()]
# if e.homeAway == "HOME":
# if e.minGames > 0:
# for teamset in elemTeams:
# for roundset in elemRounds:
# model += lpSum([x[r,t.id,t2.id] for t in teamset for r in roundset for t2 in teams if (r,t.id,t2.id) in x.keys()]) >= e.minGames - seedViolation[seed.id]
# res_objective, res_games = ueluecl24_basicmodell_v2(SOLVER, s2, partial_solution)
# # elemHaWishes[e['id']]=[]
# # allElemDays=[]
# # thisDaySet=[]
# # lastDaySet = []
# # # print("elemDays",elemDays)
# # 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 r1 <= getRoundByDay[d3] and getRoundByDay[d3]< r1 + (-e['timeframe']) :
# # thisDaySet.append(d3)
# # # print (" ROUND HA WISH ", e['reason'], 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]
# # elemHaWishNum[cntr]=1
# # if e['maxGames'] ==0:
# # elemHaWishNum[cntr]=len(elemHaWishDays[cntr])*len(elemHaWishTeams[cntr])
# # if e['minGames'] > 0:
# # elemHaWishNum[cntr]=e['minGames']
# # 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]
# # e['nWishes'] = sum ( elemHaWishNum[ee] for ee in elemHaWishes[e['id']] )
# # if e['forOneDay']:
# # e['nWishes'] = e['forOneDayNum'] * len(elemTeams)
# # nElemHaWishes= sum(w['nWishes'] for w in hawishes)
# # %%

View File

@ -108,14 +108,14 @@ def getVal(v):
# basescenario = Scenario.objects.get(id=9306)
basescenario = Scenario.objects.get(id=9279)
# scenario = Scenario.objects.get(id=9308)
basescenario = Scenario.objects.get(id=9414)
s2 = basescenario.id
user_name = 'md'
user_is_staff = True
runMode = 'New'
localsearch_time = 60
localsearch_time = 0
RUN_ENV = 'local'
SOLVER = 'xpress'

22
uefa/uefa_api/api.py Normal file
View File

@ -0,0 +1,22 @@
# %%
import requests
prod_url = 'https://uefadigitalapi.developer.azure-api.net'
prod_primary_key = '7dfa861240aa40f8a834990c24f1a66d'
prod_secondary_key = '4451dcc1ad4f41b2aa6af96cc5a1256a'
pre_url = 'https://uefadigitalapipre.developer.azure-api.net'
pre_primary_key = '1decf93425944f8b9e6dc7226a3b8477'
pre_secondary_key = '14771f5c67b74836a59f777cb543cc0f'
r=requests.get("https://api.digital.uefa.com/comp/v2/competitions/1/seasons", headers={"Cache-Control":"no-cache","Ocp-Apim-Subscription-Key":"7dfa861240aa40f8a834990c24f1a66d"})
# %%
r.json()
# %%
r=requests.get("https://api.pre.digital.uefa.com/comp/v2/competitions/1/seasons", headers={"Cache-Control":"no-cache","Ocp-Apim-Subscription-Key":"14771f5c67b74836a59f777cb543cc0f"})
# %%
r.json()
# %%