from gurobipy import *
from scenarioTree.scenarioTree_standard import ScenarioTree
import numpy as np
import random
from functions import *
from solvers import CLSP_S
from solvers import CLSP_FR
from instances import Instance
import pandas as pd
import math

num_items=5
mean=np.zeros((1,num_items))

random.seed(100)

#ESTRAZIONE VETTORE MEDIE E MATRICE VARIANZA COVARIANZA

for i in range(num_items):
    mean[0,i]=random.randint(10,100)

var_coeff=[]
var=[]

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

#MAGAZZINO INIZIALE

I0=[]
for i in range(num_items):
    I0.append(random.randint(0,2*mean[0,i]))

print(I0)
print(mean)
print(cov)
#ESTRAZIONE COSTI MAGAZZINO E PENALITA' DOMANDA NON SODDISFATTA (ALTI/BASSI)

h0=[]
for i in range(num_items):
    h0.append(random.randint(1,4))
h1=[]
for i in range(num_items):
    h1.append(random.randint(7,10))

g0=[]
for i in range(num_items):
    g0.append(random.randint(50,70))
g1=[]
for i in range(num_items):
    g1.append(random.randint(80,100))

#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 DATAFRAME VUOTO
df=pd.DataFrame(columns=["Seed_parameters","Branching_factors","Seed_tree","h_fact","g_fact","TBO","TimeLimit_BC","Gap_BC","Time_BC","Cost_BC","TimeLimit_FR","Gap_FR","Time_FR","Cost_FR","Rel_Diff","Stopping_Crit_BC","Stopping_Crit_FR"])

#CICLO FOR ESTERNO PER ANALIZZARE I 5 ALBERI
for bf in [0,1,2,3,4]:
    if bf==0:
        branching_factors=[5,3,2]
        gap_BC=0.01
        gap_FR=0.0001
        time_limit_BC=600
        time_limit_FR=np.nan
    elif bf==1:
        branching_factors=[6,5,2]
        gap_BC=0.01
        gap_FR=0.0001
        time_limit_BC=900
        time_limit_FR=np.nan
    elif bf==2:
        branching_factors=[5,3,2,2]
        gap_BC=0.01
        gap_FR=0.0001
        time_limit_BC=900
        time_limit_FR=np.nan
    elif bf==3:
        branching_factors=[9,5,2,1]
        gap_BC=0.01
        gap_FR=0.0001
        time_limit_BC=1800
        time_limit_FR=np.nan
    elif bf==4:
        branching_factors=[5,3,3,2,1]
        gap_BC=0.01
        gap_FR=0.0001
        time_limit_BC=1800
        time_limit_FR=np.nan

    
    time_periods=len(branching_factors)+1

    #FOR SUI COSTI DI MAGAZZINO
    for h_fact in [0,1]:
        if h_fact==0:
            h=h0
        else:
            h=h1

        #FOR SULLE PENALITA' PER DOMANDA NON SODDISFATTA
        for g_fact in [0,1]:
            if g_fact==0:
                g=g0
            else:
                g=g1

            #FOR SUI TBO
            for TBO in [2,3,4]:

                #COSTI DI SETUP
                f=[]
                for i in range(num_items):
                    f.append(mean[0,i]*0.5*TBO*TBO*h[i])

                #FOR SUI DIVERSI SEED PROVATI PER L'ALBERO
                for seedT in [50,60,70,80,90,100,3333,4444]:

                    #GENERAZIONE ALBERO DI SCENARI
                    
                    Tree1=ScenarioTree('Tree1',branching_factors,num_items,mean,mean,cov,seedT)
                    N=Tree1.number_of_nodes()
                    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
                    }

                    instance1=Instance(setting)

                        
                    #RISOLUZIONE PROBLEMA COL SOLVER STANDARD

                    solver1=CLSP_S(**setting)

                    [objV,Y,S,t,final_gap]=solver1.solve(instance1, Tree1, I0, gap=gap_BC, time_limit=time_limit_BC, verbose=False)


                    #RISOLUZIONE PROBLEMA COL
                    #SOLVER CON MATEURISTICA FIX AND RELAX

                    solver2=CLSP_FR(**setting)

                    [objV2,Y2,S2,t2]=solver2.solve(instance1,Tree1,I0)

                    #DIFFERENZA RELATIVA MEDIA TRA GLI OBIETTIVI
                    delta=(objV2-objV)/objV

                    #CRITERIO DI ARRESTO SOLVER STANDARD
                    #0=raggiunto gap 1%
                    if (math.isnan(time_limit_BC) or t<time_limit_BC):
                        sc_BC=0
                        MIPGap=np.nan
                    #1=raggiunto limite massimo di tempo
                    #in MIPGap si salva il gap raggiunto (maggiore di 1%)
                    else:
                        sc_BC=1
                        MIPGap=final_gap

                    #CRITERIO DI ARRESTO SOLVER MATEURISTICA
                    #0=raggiunto gap 0.01%
                    if (math.isnan(time_limit_FR) or t2<time_limit_FR):
                        sc_FR=0
                    #1=raggiunto limite massimo di tempo
                    else:
                        sc_FR=1

                    #SALVATAGGIO NUOVA OSSERVAZIONE NEL DATAFRAME
                    new_obs={
                        "Seed_parameters":[100],
                        "Branching_factors":[bf],
                        "Seed_tree":[seedT],
                        "h_fact":[h_fact],
                        "g_fact":[g_fact],
                        "TBO":[TBO],
                        "TimeLimit_BC":[time_limit_BC],
                        "Gap_BC":[gap_BC],
                        "Time_BC":[t],
                        "Cost_BC":[objV],
                        "TimeLimit_FR":[time_limit_FR],
                        "Gap_FR":[gap_FR],
                        "Time_FR":[t2],
                        "Cost_FR":[objV2],
                        "Rel_Diff":[delta],
                        "Stopping_Crit_BC":[sc_BC],
                        "Stopping_Crit_FR":[sc_FR],
                        "MIPGap_BC":[MIPGap]

                    }

                    new=pd.DataFrame(new_obs)
                    df=pd.concat([df,new],ignore_index=True)

                    df.to_csv("DatiConfrontoFR6.csv",index=False)