from gurobipy import *
import numpy as np
import random
from itertools import product
import time

#Funzione per creare matrice di varianza-covarianza definita positiva a partire da vettore delle varianze var

def create_cov(var):
    """
    INPUT:
    var: vettore delle varianze della distribuzione normale multivariata
    
    OUTPUT:
    cov: matrice di varianza e covarianza della distribuzione normale multivariata
    """
    
    num_items=len(var)
    cov=np.zeros(shape=(num_items,num_items))
    h=0
    while((not np.all(np.linalg.eigvals(cov) > 0)) or (h==0)):
        for i in range(num_items):
            for j in range(i,num_items):
                if (i==j):
                    cov[i,j]=1*pow(var[i]*var[j],0.5)
                else:
                    cov[i,j]=random.uniform(-1,1)*pow(var[i]*var[j],0.5)
                    cov[j,i]=cov[i,j]
        h+=1
    return cov

#Funzione per generare scenari di domanda normali multivariate

def generate_demands(mean,cov,num_repl,horizon,seedD):
    """
    INPUTS:
    mean: vettore media della normale multivariata
    cov: matrice di varianza-covarianza della normale multivariata
    num_repl: numero di scenari da generare
    horizon: lunghezza del singolo scenario
    
    OUTPUT:
    D: matrice (num_repl*horizon*num_items); in posizione (i,j,k) contiene la domanda nello scenario i, all'istante di tempo j per l'oggetto k
    """
    
    num_items=len(mean)
    D=np.zeros((num_repl,horizon,num_items))
    
    np.random.seed(seedD)
    
    for i in range(num_repl):
        D[i,:,:]=np.random.multivariate_normal(mean,cov,horizon)
        
    for i in range(num_repl):
        for j in range(horizon):
            for k in range(num_items):
                if D[i,j,k]<0:
                    D[i,j,k]=0
    return D

