from solvers import *
from scenarioTree import *
from instances import *
from functions import *
import random
import time
import numpy as np

#NUMERO PRODOTTI DEL MODELLO
num_items=5

random.seed(100)

#ESTRAZIONE VETTORE MEDIE E MATRICE VARIANZA COVARIANZA
    
mean=np.ndarray(shape=(1,num_items),dtype=int)
    
for i in range(num_items):
    mean[0,i]=random.randint(10,100)

var_coeff=[]
var=[]
sd=[]

for i in range(num_items):
    var_coeff.append(random.uniform(0.1,0.5))
    sd.append(mean[0,i]*var_coeff[i])
    var.append(pow(sd[i],2))
    
cov=create_cov(var)

#ESTRAZIONE PARAMETRI DEL MODELLO
    
#MAGAZZINO INIZIALE
initial_inventory=[]
for i in range(num_items):
    initial_inventory.append(random.randint(0,2*mean[0,i]))

#COSTI DI MAGAZZINO

h=[]
for i in range(num_items):
    h.append(random.randint(1,10))

#PENALITA' PER DOMANDA NON SODDISFATTA

g=[]
for i in range(num_items):
    g.append(random.randint(50,100))
    
#COSTI DI SETUP

f=[]
for i in range(num_items):
    f.append(mean[0,i]*0.5*4*h[i])
    
#PROCESSING TIMES

proc_time=[]
for i in range(num_items):
    proc_time.append(random.uniform(1,5))
    
#DISPONIBILITA' MASSIMA DELLA RISORSA

cap_factor=2
R=np.inner(proc_time,mean[0,])*cap_factor

#TEMPI DI SETUP

setup_factor=0.5
setup_times=[]

for i in range(num_items):
    setup_times.append(R*setup_factor/num_items)

#CREAZIONE DI UN ALBERO DI SCENARI STANDARD
branching_factors=[4,2,1]
TreeStandard=ScenarioTree('ScenarioTreeStandard',branching_factors,num_items,mean,mean,cov,700)

#CREAZIONE DI UN ALBERO DI SCENARI DI TIPO SOBOL
TreeSobol=ScenarioTree_Sobol('ScenarioTreeSobol',branching_factors,num_items,mean,mean,cov,900)

#NUMERO NODI E LIVELLI DELL'ALBERO (UGUALE PER ENTRAMBI)
N=TreeStandard.number_of_nodes()
time_periods=len(branching_factors)+1

#CREAZIONE DI UN'ISTANZA DEL PROBLEMA STOCASTICO
stoc_setting={
    'h':h,
    'g':g,
    'f':f,
    'proc_time':proc_time,
    'R':R,
    'setup_times':setup_times,
    'num_items':num_items,
    'time_periods':time_periods,
    'N':N
}

stoc_instance=Instance(stoc_setting)

#DEFINIZIONE DEL SOLVER STANDARD
solver_standard=CLSP_S(**stoc_setting)

#RISOLUZIONE DEL MODELLO CSLP STOCASTICO CON IL SOLVER STANDARD (ALBERO DI SCENARI STANDARD)
[objV,Y,S,t,gap]=solver_standard.solve(stoc_instance,TreeStandard,initial_inventory)

print('MODELLO CLSP STOCASTICO, SOLVER STANDARD; ALBERO STANDARD')
print('Valore funzione obiettivo: {}'.format(objV))
print('Produzione al primo stadio Y: {}'.format(Y))
print('Variabili di setup al primo stadio: {}'.format(S))
print('Tempo per la soluzione: {} s'.format(t))

#RISOLUZIONE DEL MODELLO CSLP STOCASTICO CON IL SOLVER STANDARD (ALBERO DI SCENARI DI SOBOL)
[objV,Y,S,t,gap]=solver_standard.solve(stoc_instance,TreeSobol,initial_inventory)

print('MODELLO CLSP STOCASTICO, SOLVER STANDARD; ALBERO SOBOL')
print('Valore funzione obiettivo: {}'.format(objV))
print('Produzione al primo stadio Y: {}'.format(Y))
print('Variabili di setup al primo stadio: {}'.format(S))
print('Tempo per la soluzione: {} s'.format(t))

#DEFINIZIONE DEL SOLVER FIX & RELAX
solver_fix_relax=CLSP_FR(**stoc_setting)

#RISOLUZIONE DEL MODELLO CSLP STOCASTICO CON IL SOLVER FIX & RELAX (ALBERO DI SCENARI STANDARD)
[objV,Y,S,t]=solver_fix_relax.solve(stoc_instance,TreeStandard,initial_inventory)

print('MODELLO CLSP STOCASTICO, SOLVER FIX & RELAX; ALBERO STANDARD')
print('Valore funzione obiettivo: {}'.format(objV))
print('Produzione al primo stadio Y: {}'.format(Y))
print('Variabili di setup al primo stadio: {}'.format(S))
print('Tempo per la soluzione: {} s'.format(t))

#RISOLUZIONE DEL MODELLO CSLP STOCASTICO CON IL SOLVER FIX & RELAX (ALBERO DI SCENARI DI SOBOL)
[objV,Y,S,t]=solver_fix_relax.solve(stoc_instance,TreeSobol,initial_inventory)

print('MODELLO CLSP STOCASTICO, SOLVER FIX & RELAX; ALBERO SOBOL')
print('Valore funzione obiettivo: {}'.format(objV))
print('Produzione al primo stadio Y: {}'.format(Y))
print('Variabili di setup al primo stadio: {}'.format(S))
print('Tempo per la soluzione: {} s'.format(t))

#CREAZIONE DI UN'ISTANZA DEL PROBLEMA DETERMINISTICO

#SCELTA DEL LIVELLO DI SICUREZZA DELLE SCELTE
alpha=0.7

det_setting={
    'h':h,
    'f':f,
    'proc_time':proc_time,
    'R':R,
    'setup_times':setup_times,
    'num_items':num_items,
    'time_periods':time_periods,
    'N':N,
    'mean':mean[0,],
    'sd':sd,
    'alpha':alpha
}

det_instance=Instance_Det(det_setting)

#DEFINIZIONE DEL SOLVER DETERMINISTICO
solver_det=CLSP_Det(**det_setting)

#RISOLUZIONE DEL MODELLO CSLP DETERMINISTICO CON SCORTE DI SICUREZZA
[objV,Y,S,t,gap]=solver_det.solve(det_instance,initial_inventory)

print('MODELLO CLSP DETERMINISTICO CON SCORTE DI SICUREZZA')
print('Valore funzione obiettivo: {}'.format(objV))
print('Produzione al primo stadio Y: {}'.format(Y))
print('Variabili di setup al primo stadio: {}'.format(S))
print('Tempo per la soluzione: {} s'.format(t))


