import numpy as np
from src.simu import *

Config = {'K': 50, 'T': 8,
        'AreaLen': 40,
        'JobNum_Lb': 10, 'JobNum_Ub': 50,
        'dev': 0,
        'UtilityMode':'complex', #'dist', #  #'random'
        #'ProbOccu': 0.5,
        'ErrorCorr': 0,
        'JobCorr': 0.6, 
        'ScheDri_Wage': 20, 'Dis_Coff': 0.9,
        'PriNum': 5, 'Prices': [20, 30, 40, 50, 60],
        'Sigma': [5,5,5,5,5,5,5,5],# [1,1,1,1,1,1,1,1],#
        'L': 2,
        'InSamNo': 7, 'OutSamNo': 200}

def run(seed, Target):  
    np.random.seed(seed)
    data = optimization(Config)

    print('generating training samples...')
    data.InSamples = data.generate_Samples(data.InSamNo)
    print('generating test samples...')
    data.OutSamples = data.generate_Samples(data.OutSamNo, Config['dev'])
    
    print('solving exact reduced model')
    obj_exact_emp, x_exact_emp, firstCos_exact_emp = data.origin_empirical()
    data.BrePoints = data.generate_BrePoints_exact(x_exact_emp)
    #data.BrePoints = data.generate_BrePoints()

    print('generating reduced information vectors...')
    data.z = data.generalized_assignment_problem(data.InSamples)

    # empirical
    print('solving generalized empirical model...')
    obj_emp, x_emp, firstCos_emp = data.generalized_empirical()
    eva_emp, _ = data.out_of_sample(x_emp)

    # robust 
    print('Solving robust model')
    data.z_hat = data.est_z_hat()
    data.kappa_bound = data.est_kappa_bound()
    print('data kappa up bound', data.kappa_bound)


#lenTar = 16
#Target = [1+0.01*i for i in range(lenTar)]

    lenTar = 1
    #Target = [1.03]
    RS_x = np.zeros((lenTar, data.I))
    RS_firstCost = np.zeros(lenTar)
    RS_optKappa = np.zeros(lenTar)
    RS_OutSample = np.zeros(lenTar)
    RS_achieveness = np.zeros(lenTar)
    RS_ratio = np.zeros(lenTar)

    for i in range(lenTar):
        tau =  Target[i] * obj_emp
        x_rs, kappa, firstCos_RS = data.bisection(tau)

        eva_rs, _ = data.out_of_sample(x_rs)
        RS_x[i] = x_rs[:]
        RS_firstCost[i] = firstCos_RS
        RS_optKappa[i] = kappa
        RS_OutSample[i] = round(eva_rs, 2)
        RS_achieveness[i] = 100*(eva_rs/tau - 1)
        RS_ratio[i] = 100*(eva_rs/eva_emp - 1)

    print('-------------------------------------')
    print('print final results...')
    print('EMP x =', x_emp)
    print('EMP first-stage cost = ', firstCos_emp)
    print('Emp Insample  obj', obj_emp)
    print('Emp Outsample obj %.2f'%(eva_emp))
    print('Emp Out/In  ratio %.2f%%'%(100*(eva_emp-obj_emp)/obj_emp))
    print('Emp mismatch %.2f%%'%(100*(eva_emp-obj_emp)/obj_emp))

    print('RS x = ', RS_x)
    print('RS first-stage cost = ', RS_firstCost)
    print('optimal kappa = ', RS_optKappa)
    print('RS Outsample obj = ', RS_OutSample)
    print('RS improvenemnt over Emp = %.4f%%'%RS_ratio)
    print('RS mismatch =  %.4f%%'%RS_achieveness)
    return RS_ratio[0], 100*(eva_emp-obj_emp)/obj_emp,  RS_achieveness[0] 

SeedNum = 50
Target = [1.03]
results = np.zeros((SeedNum, 3))

print(Config)
for i in range(SeedNum):
    results[i,0], results[i,1], results[i,2] = run(i, Target)
    print('Average RS improvenemnt over Emp = %.2f%%'%np.average(results[:(i+1),0]) )
    print('Average RS mismatch = %.2f%%'%np.average(results[:(i+1),2]) )
    print('Average Emp mismatch = %.2f%%'%np.average(results[:(i+1),1]) )