示例#1
0
#!/usr/bin/env python

import sys
import SA_IO as IO
import Simulated_Annealing as ASA
import SA_Print as SAPrint

###                                     ###
###              MAIN CODE              ###
###                                     ###
""" Starting code. Procedure for input deck will be changed
    soon. """

# Input of argument:
if len(sys.argv) < 3:
    SAPrint.HelpInput()
    sys.exit()

else:
    Method = sys.argv[1]
    Task = sys.argv[2]

    if Task == 'Problem':
        ProblemFileName = sys.argv[3]
""" Creating a file for general output """
IO.OutPut(Task, Method)
""" Generating X_Opt array """
X_Opt = []
""" Calling the optimisation routine """

if (Method == 'SA'):
示例#2
0
def ReadInCoolingSchedule(**kwargs):
    """ This function reads the contents of the cooling schedule file"""
    import csv  # Using csv (comma separated values) module
    """ ===========================================================
            Set up Global variables used throughout the code
        ===========================================================  """
    global SA_Function, SA_Minimum, SA_N, SA_NS, SA_NT, SA_MaxEvl, SA_EPS, SA_RT, SA_Temp, \
        SA_LowerBounds, SA_UpperBounds, SA_VM, SA_C, SA_Debugging, SA_X, BenchmarkSolution
    global SA_Xopt, SA_Fopt  # These variables are defined here just for practicality
    """ Local variables: """
    SA_Cooling = []
    SA_Cooling_list = []
    SA_Benchmarks = []
    """Reading Input files """
    if kwargs:
        for key in kwargs:
            if (key == 'File_Name'):  # For Problems
                SA_Function = kwargs[key]
                Function = SA_Function + '.sa'

            elif (key == 'Test_Number'):  # For Benchmark Test-Cases
                TestNumber = kwargs[key]
                dummy, SA_Function = CountingNumberOfTests(
                    Test_Case=TestNumber)
                Function = os.path.abspath('./Tests/' + SA_Function + '.sa')

            else:
                sys.exit('In ReadInCoolingSchedule. Option not found')

    else:
        sys.exit('Option not found')

    Are_There_Dimensions = False
    """ Open input file containing Cooling Schedule: """
    with open(Function, 'r') as file:
        reader = csv.reader(file, delimiter=' ', skipinitialspace=True)

        for row in reader:
            if row == [] or ListOfCommentsStrings(
                    row):  # List of comment strings that can be used
                Nothing_To_Be_Done = True

            elif row[
                    0] == 'Number_Dimensions':  # This MUST be the first variable declared in the input file
                SA_N = int(row[1])
                Are_There_Dimensions = True

            elif Are_There_Dimensions:

                if row[0] == 'Minimum':  # Maximum or Minimum
                    SA_Minimum = to_bool(row[1])

                elif row[0] == 'NS':  # Maximum number of cycles
                    SA_NS = int(row[1])

                elif row[
                        0] == 'NT':  # Maximum number of iterations before the temperature reduction
                    SA_NT = int(row[1])

                elif row[
                        0] == 'MaxEvl':  # Maximum number of evaluations of the objective function
                    SA_MaxEvl = int(row[1])

                elif row[
                        0] == 'EPS':  # Minimum acceptable discrepancy (used throughout the SAA)
                    SA_EPS = float(row[1])

                elif row[0] == 'RT':  # Parameter for temperature reduction
                    SA_RT = float(row[1])

                elif row[0] == 'Temp':  # SAA temperature parameter
                    SA_Temp = float(row[1])

                elif row[
                        0] == 'X_Init':  # Initial guess for the solution-coordinate vector
                    SA_X = ReadingRows_Float(row)

                elif row[
                        0] == 'LowerBounds':  # Lower bounds for the solution-coordinate vector
                    SA_LowerBounds = ReadingRows_Float(row)

                elif row[
                        0] == 'UpperBounds':  # Upper bounds for the solution-coordinate vector
                    SA_UpperBounds = ReadingRows_Float(row)

                elif row[
                        0] == 'VM':  # Stepping matrix (only the diagonal representing each direction
                    SA_VM = ReadingRows_Float(row)

                elif row[
                        0] == 'C':  # Parameter for controlling the size of the stepping matrix
                    SA_C = ReadingRows_Float(row)

                elif row[
                        0] == 'Benchmark_Solution':  # Solution of the Benchmark test-case
                    BenchmarkSolution = ReadingRows_Float(row, Solution='yes')

                elif row[
                        0] == 'Debugging':  # Option to dump all intermediate results into the *.out file (True or False)
                    SA_Debugging = to_bool(row[1])

                else:
                    sys.exit('Option not recognised')

            else:
                print 'Number_Dimensions was not defined in the FIRST line'
                sys.exit()

    file.close()
    Print.Print_SAA_Diagnostic(Initialisation='yes')

    if kwargs:
        for key in kwargs:
            if (key == 'File_Name'
                ):  # For Problems we assign this array as zero.
                BenchmarkSolution = [0. in range(SA_N + 1)]

    return SA_Function, SA_Minimum, SA_N, SA_NS, SA_NT, SA_MaxEvl, SA_EPS, SA_RT, SA_Temp, \
        SA_LowerBounds, SA_UpperBounds, SA_VM, SA_C, SA_Debugging, SA_X, BenchmarkSolution
示例#3
0
def SimulatedAnnealing(Method, Task, **kwargs):

    if Task == 'Problem':
        import SpecialFunctions as SpFunc

    X_Optimum = []
    F_Optimum = []
    Time_temp = []
    TestSolution = []
    TestSolution_Name = []
    TestSolution_Time = []

    if kwargs:
        for key in kwargs:
            if key == 'FileName':
                FileName = kwargs[key]
            elif key == 'ProblemType':
                ProblemType = kwargs[key]

    (Test, N_Tests) = AssignSolvingProblem(Method, Task, FileName)

    jtest = 0

    for itest in xrange(1, N_Tests + 1):
        """ =========================================================================

                Initialising the SIMULATED ANNEALING ALGORITHM  COOLING SCHEDULE

            =========================================================================  """

        if Task == 'Benchmarks':

            if FileName != 'All':

                if itest == Test:
                    SaT.Function_Name, SaT.Minimum, SaT.Ndim, SaT.NS, SaT.NT, SaT.MaxEvl, SaT.EPS, SaT.RT, SaT.Temp, \
                        SaT.LowerBounds, SaT.UpperBounds, SaT.VM, SaT.C, SaT.Debugging, \
                        SaT.SA_X, SaT.BenchmarkSolution = IO.ReadInCoolingSchedule( Test_Number = Test, Task = Task )
                    print '======================', SaT.Function_Name, '======================'
                else:
                    continue

            else:
                SaT.Function_Name, SaT.Minimum, SaT.Ndim, SaT.NS, SaT.NT, SaT.MaxEvl, SaT.EPS, SaT.RT, SaT.Temp, \
                    SaT.LowerBounds, SaT.UpperBounds, SaT.VM, SaT.C, SaT.Debugging, \
                    SaT.SA_X, SaT.BenchmarkSolution = IO.ReadInCoolingSchedule( Test_Number = itest, Task = Task )
                print '======================', SaT.Function_Name, '======================'

        elif Task == 'Problem':
            SaT.Function_Name, SaT.Minimum, SaT.Ndim, SaT.NS, SaT.NT, SaT.MaxEvl, SaT.EPS, SaT.RT, SaT.Temp, \
                SaT.LowerBounds, SaT.UpperBounds, SaT.VM, SaT.C, SaT.Debugging, \
                SaT.SA_X, SaT.BenchmarkSolution = IO.ReadInCoolingSchedule( File_Name = FileName, Task = Task )

        else:
            sys.exit('In SimulatedAnnealing. Option not found')
        """
            ===================================================================
                      Initial Assessement of the Objective Function
            ===================================================================
        """
        """ Calling the function for the first time before the SA main loop """
        if Task == 'Benchmarks':
            Func = BTest.TestFunction(SaT.Function_Name, SaT.Ndim, SaT.SA_X)

        else:  # Problems
            Func, X_Feed = ObF.ObjFunction(SaT.SA_X,
                                           Problem_Type=ProblemType,
                                           Status='InitialCalculations')

        #sys.exit( Func )
        """ The function must be minimum """
        if SaT.Minimum:
            Func = -Func
        """"                  Printing into the *out file                    """
        IO.f_SAOutput.write('\n')
        IO.f_SAOutput.write(
            'Initial evaluation of the function: {a:.4e}'.format(a=Func) +
            '\n')
        if Task == 'Problem' and ProblemType == 'PhaseEquilibria':
            SpFunc.CalcOtherPhase(SaT.SA_X,
                                  SaT.UpperBounds,
                                  SaT.LowerBounds,
                                  Diagnostics=True)
        """
            ===================================================================
                Calling main SA loop:       
            ===================================================================
        """

        if Task == 'Benchmarks':
            X_OPT, F_OPT = ASA_Loops(Method, Task, Func)
        else:  # Problems
            X_OPT, F_OPT = ASA_Loops(Method,
                                     Task,
                                     Func,
                                     Problem_Type=ProblemType,
                                     X_Feed=X_Feed)

        X_Optimum.append(X_OPT)
        F_Optimum.append(F_OPT)

        print X_Optimum, F_Optimum

        #sys.exit('---')
        """
           =====================================================================
               Assessing the solution (comparison against known solution)
           ====================================================================="""
        if Task == 'Benchmarks':
            TestSolution.append(BTest.AssessTests(X_OPT,
                                                  SaT.BenchmarkSolution))
            TestSolution_Name.append(SaT.Function_Name)

            TestTime = time.clock()
            Time_temp.append(TestTime)
            if FileName == 'All':
                if itest > 1:
                    TestSolution_Time.append(TestTime - Time_temp[itest - 2])
                else:
                    TestSolution_Time.append(TestTime)

                    IO.f_SAOutput.write('\n')
            IO.f_SAOutput.write(
                '===========================================================')
            IO.f_SAOutput.write('\n')
            IO.f_SAOutput.write(
                '            Assessment of the test-cases :      ')
            IO.f_SAOutput.write('\n')
            IO.f_SAOutput.write('{a:}:  {b:}'.format(
                a=SaT.Function_Name, b=TestSolution[jtest]) + '\n')
            IO.f_SAOutput.write('\n')
            jtest += 1

        else:  # Problem
            TestTime = time.clock()
            TestSolution_Time.append(
                time.clock() -
                SaT.Time_Init)  # Measuring CPU time for the problem/test

    if (Task == 'Benchmarks') and (FileName == 'All'):
        Print.Print_SAA_Diagnostic(Bench_AllTestCases='yes',
                                   Solution=TestSolution,
                                   Solution_Name=TestSolution_Name,
                                   Solution_Time=TestSolution_Time)

    return X_Optimum, F_Optimum
示例#4
0
def ASA_Loops(Method, Task, Func, **kwargs):
    """ For debugging """
    #pdb.set_trace()

    TestName = SaT.Function_Name
    SVLE_Problem = False
    if kwargs:
        for key in kwargs:
            if (key == 'X_Feed'):
                X_Feed = kwargs[key]
            elif key == 'Thermodynamics':
                PhaseEquilibria = kwargs[key]
                SVLE_Problem = True
            else:
                sys.exit('In ASA_Loops. Option was not defined')

    IO.f_SAOutput.write('\n')
    IO.f_SAOutput.write('Initialising SA Algorithm for: {a:}'.format(
        a=TestName) + '\n')
    """ Initialisation of a few parameters. """
    Try = False
    NAcc = 0
    Nobds = 0
    NFCNEV = 0
    NEps = 4
    MaxNum = 1.e20

    NACP = [0 for i in range(SaT.Ndim)]
    XP = [0. for i in range(SaT.Ndim)]
    FStar = [MaxNum for i in range(NEps)]
    FStar[0] = Func

    FOpt = Func
    XOpt = SaT.SA_X
    X_Try = SaT.SA_X
    XOpt_f = [0. for i in range(SaT.Ndim)]
    """ The 'Fraction' variable assesses if the function to be optimised is
           a thermodynamic function (TRUE) and therefore the elements of the
           solution-coordinate needs to be bounded (0,1) and the summation
           of the N-1 elements must be smaller than 1.
        If FALSE then the above is neglected.                               """
    if Task == 'Benchmarks':
        Fraction = False
    elif Task == 'Problem' and SVLE_Problem:  #Problems
        Fraction = True
    """ =======================================================================
                       Beginning of the main outter loop: 
        ======================================================================= """

    kloop = 0
    while kloop <= SaT.MaxEvl:

        NUp = 0
        NRej = 0
        NDown = 0
        LNobds = 0
        """ Beginning of the m loop: number of iterations """
        mloop = 0
        while mloop < SaT.NT:
            """ Beginning of j loop: number of cycles"""
            jloop = 0
            while jloop < SaT.NS:
                """ Beginning of the h loop: """
                hloop = 0

                while hloop < SaT.Ndim:

                    if Fraction:
                        dim = SaT.Ndim - 1
                    else:
                        dim = SaT.Ndim

                    for i in range(SaT.Ndim):
                        rand = RanGen.RandomNumberGenerator(SaT.Ndim)

                        if (i == hloop):
                            XP[i] = X_Try[i] + SaT.VM[i] * (2. * rand[i] - 1.)
                        else:
                            XP[i] = X_Try[i]

                    #IO.f_SAOutput.write( 'XP(b4):{a:}'.format( a= XP ) + '\n' )

                    #pdb.set_trace()
                    """ ===========================================================
                            Feasibility Test: check is solution is bounded.
                        =========================================================== """
                    #if Fraction:
                    #    XP[ dim ] = X_Try[ dim ]
                    #XP[ SaT.Ndim ] = X_Try[ SaT.Ndim ]

                    if Task == 'Benchmarks':
                        BoxF.Envelope_Constraints( Method, Task, XP, NDim = SaT.Ndim, LBounds = SaT.LowerBounds, \
                                                   UBounds = SaT.UpperBounds, TryC = Try, IsNormalised = Fraction )

                    else:  # Problems
                        BoxF.Envelope_Constraints( Method, Task, XP, NDim = SaT.Ndim, LBounds = SaT.LowerBounds, \
                                                   UBounds = SaT.UpperBounds, TryC = Try, IsNormalised = Fraction, \
                                                   X_Feed = X_Feed )

                    #IO.f_SAOutput.write( 'XP(after):{a:}'.format( a= XP ) + '\n' )
                    #IO.f_SAOutput.write( '\n' )
                    #if kloop > 10:
                    print XP
                    sys.exit('fck')

                    if Try:
                        LNobds += 1
                        Nobds += 1
                    """ ============================================================ """

                    if Task == 'Benchmarks':
                        FuncP = BTest.TestFunction(SaT.Function_Name, SaT.Ndim,
                                                   XP)
                    else:  # Problems
                        FuncP, dummy = ObF.ObjFunction(
                            XP, Thermodynamics=PhaseEquilibria)
                    """ The function must be minimum """
                    if SaT.Minimum:
                        FuncP = -FuncP

                    NFCNEV += 1  # Number of evaluation of the function
                    """
                       ==================================================================
                         If there were more than MAXEVL evaluations of the objective
                            function, the SA algorithm will finish.
                       =================================================================="""

                    if (NFCNEV >= SaT.MaxEvl):
                        FOpt = -FOpt
                        Print.Print_SAA_Diagnostic(MaxEval='yes',
                                                   FOpt=FOpt,
                                                   XOpt=XOpt_f,
                                                   NFCNEV=NFCNEV)
                        sys.exit(
                            'SAA did not converge. Too many evaluations of the function!'
                        )
                    """"
                       ==================================================================
                         The new solution-coordinate is accepted and the objective 
                            function increases.
                       =================================================================="""

                    if (FuncP > Func):
                        for i in range(SaT.Ndim):
                            X_Try[i] = XP[i]
                        Func = FuncP

                        if SaT.Debugging == True:
                            IO.f_SAOutput.write(
                                '{s:20} New vector-solution is accepted ( X: {a:}) with solution {b:.4f}'
                                .format(s=' ', a=X_Try, b=FuncP) + '\n')

                        NAcc += 1
                        NACP[hloop] = NACP[hloop] + 1
                        NUp += 1
                        """ If the new FP is larger than any other point, this will be 
                               chosen as the new optimum                               """

                        if (FuncP > FOpt):
                            for i in range(SaT.Ndim):
                                XOpt[i] = XP[i]
                            FOpt = FuncP
                            for i in range(SaT.Ndim):
                                XOpt_f[i] = XP[i]

                        if Task == 'Benchmarks':
                            print 'NFCNEV(', NFCNEV, '), XOpt: ', XOpt_f, ' with FOpt: ', FOpt, '(Analytical:', -BTest.TestFunction(
                                SaT.Function_Name, SaT.Ndim,
                                SaT.BenchmarkSolution[0:SaT.Ndim]), ')'
                        else:
                            if (NFCNEV % 25) >= 24:
                                print 'NFCNEV(', NFCNEV, '), XOpt: ', XOpt_f, ' with FOpt: ', FOpt

                            if SaT.Debugging == True:
                                IO.f_SAOutput.write(
                                    '{s:20} New XOpt: {a:} with FOpt: {b:}'.
                                    format(s=' ', a=XOpt_f, b=FOpt) + '\n')

                    else:  # if ( FuncP > Func ):
                        """ However if FuncP is smaller than the others, thus the Metropolis criteria 
                               (Gaussian probability density function) - or any other density function
                               that may be added latter - may be used to either accept or reject this
                               coordinate.                                                            """

                        rand = RanGen.RandomNumberGenerator(SaT.Ndim)
                        #Density = math.exp( ( FuncP - Func ) / SaT.Temp )#max( SaT.Temp, SaT.EPS ) )
                        if SaT.Temp < max(1.e-6, SaT.EPS):
                            Density = math.exp(
                                (FuncP - Func) / max(1.e-3 * SaT.EPS, rand[0]))
                        else:
                            Density = math.exp((FuncP - Func) / SaT.Temp)
                        temp = 1.
                        for i in range(SaT.Ndim):
                            temp = temp * rand[i]
                        Density_Gauss = math.sqrt(abs(temp))

                        if (Density_Gauss < Density):
                            for i in range(SaT.Ndim):
                                X_Try[i] = XP[i]
                            Func = FuncP

                            if SaT.Debugging == True:
                                IO.f_SAOutput.write('\n \n ')
                                IO.f_SAOutput.write(
                                    '{s:20} Metropolis Criteria; New vector-solution is generated ( X: {a:}) with solution {b:.4f}'
                                    .format(s=' ', a=X_Try, b=FuncP) + '\n')

                            NAcc += 1
                            NACP[hloop] = NACP[hloop] + 1
                            NDown += 1

                        else:
                            NRej += 1
                    """ End of h loop """
                    #pdb.set_trace()
                    hloop += 1
                """ End of j loop """
                jloop += 1
            """
               ==================================================================
                 As half of the evaluations may be accepted, thus the VM array
                     may need to be adjusted.
               ================================================================== """

            for i in range(SaT.Ndim):
                Ratio = float(NACP[i]) / float(SaT.NS)
                if (Ratio > 0.6):
                    SaT.VM[i] = SaT.VM[i] * (1. + SaT.C[i] *
                                             (Ratio - 0.6) / 0.4)

                elif (Ratio < 0.4):
                    SaT.VM[i] = SaT.VM[i] / (1. + SaT.C[i] *
                                             (0.4 - Ratio) / 0.4)

                if (SaT.VM[i] > (SaT.UpperBounds[i] - SaT.LowerBounds[i])):
                    SaT.VM[i] = SaT.UpperBounds[i] - SaT.LowerBounds[i]

            if SaT.Debugging == True:
                IO.f_SAOutput.write(
                    '{s:20} {a:3d} Points rejected. VM is adjusted to {b:}'.
                    format(s=' ', a=NRej, b=SaT.VM) + '\n')

            NACP = [0 for i in range(SaT.Ndim)]
            """ End of m loop """
            mloop += 1
        """
           =======================================================================
                Diagnostics of the algorithm before the next temperature reduction
           ======================================================================= """

        Print.Print_SAA_Diagnostic(Diagnostics='yes',
                                   FOpt=FOpt,
                                   NUp=NUp,
                                   NDown=NDown,
                                   NRej=NRej,
                                   NAcc=NAcc,
                                   LNobds=LNobds,
                                   NFCNEV=NFCNEV,
                                   XOpt=XOpt,
                                   FStar=FStar)

        # This will make the tests run faster as we know the solution, thus they do
        #     not need to continue search if the solution if close enough
        if Task == 'Benchmarks':
            Quit = BTest.AssessTests(XOpt_f, SaT.BenchmarkSolution)
            if Quit:
                if SaT.Minimum:
                    FOpt = -FOpt
                Print.Print_SAA_Diagnostic(Termination='yes',
                                           FOpt=FOpt,
                                           NRej=NRej,
                                           XOpt=XOpt_f,
                                           NFCNEV=NFCNEV)
                return XOpt_f, FOpt
        #stop
        """
           ==========================================================
                     Checking the stoppage criteria           
           ==========================================================  """

        Quit = True
        FStar[0] = Func

        #print '--------------------------------------'
        #print ' FOpt, FStar, Func', FOpt, FStar, Func
        #print '--------------------------------------'

        if FOpt - FStar[0] <= SaT.EPS:
            Quit = False

        for i in range(NEps):
            if abs(Func - FStar[i]) > SaT.EPS:
                Quit = False

        if Quit:
            if Task == 'Benchmarks':
                Quit = BTest.AssessTests(XOpt_f, SaT.BenchmarkSolution)

            elif Task == 'Problem' and IO.to_bool(
                    SaT.BenchmarkSolution[0]):  # For validation
                Solution = np.arange(float(SaT.Ndim))
                for i in range(SaT.Ndim):
                    Solution[i] = IO.num(SaT.BenchmarkSolution[i + 1])

                FuncValid, dummy = ObF.ObjFunction(
                    Solution, Thermodynamics=PhaseEquilibria)
                FuncOpt, dummy = ObF.ObjFunction(
                    XOpt, Thermodynamics=PhaseEquilibria)
                print 'Gibbs Function (Validation, Optimum):', FuncValid, FuncOpt

                Pass = True
                if abs(FuncValid - FuncOpt) >= SaT.EPS:
                    Pass = Pass and False

                for i in range(SaT.Ndim):
                    if abs(XOpt[i] - Solution[i]) >= SaT.EPS:
                        Pass = Pass and False

                if Pass:
                    print 'Error Associated with: '
                    print ' (a) Function: ', abs(
                        FuncValid - FuncOpt) / FuncValid * 100., '%'
                    print ' (b) Solution Variables:'
                    for i in range(SaT.Ndim):
                        print 'X[', i, ']', abs(
                            XOpt[i] - Solution[i]) / Solution[i] * 100., '%'
                    Quit == True

        #print '===>', SaT.BenchmarkSolution
        #print assert(SaT.BenchmarkSolution)
        #sys.exit('fck11')

        #if assert(SaT.BenchmarkSolution):
        #    sys.exit('fck11')
        #else:
        #    sys.exit('fck--')
        #elif Quit and ( Task == 'Problem' ) and
        """
           ==========================================================
               Termination of the Simulated Annealing algorithm       
           ==========================================================  """

        if Quit:
            #X_Try = XOpt
            if SaT.Minimum:
                FOpt = -FOpt

            Print.Print_SAA_Diagnostic(Termination='yes',
                                       FOpt=FOpt,
                                       NRej=NRej,
                                       XOpt=XOpt_f,
                                       NFCNEV=NFCNEV)
            if Task == 'Problem':
                SpFunc.CalcOtherPhase(XP,
                                      SaT.UpperBounds,
                                      SaT.LowerBounds,
                                      Diagnostics=True)

            return XOpt_f, FOpt

        #print ' XOpt_f, FOpt ', XOpt_f, FOpt
        """
           ==========================================================
              If the stoppage criteria can not be reached, then
                 continue the K-LOOP
           ==========================================================  """

        SaT.Temp = SaT.RT * SaT.Temp
        for i in xrange(NEps - 1, 0, -1):
            FStar[i] = FStar[i - 1]
            #print 'FStar[ i ]',FStar[ i ]

        Func = FOpt
        for i in range(SaT.Ndim):
            X_Try[i] = XOpt[i]
            #print 'X_Try[ i ]',X_Try[ i ]
        """ End of k loop """
        kloop += 1
def SimulatedAnnealing(Method, Task, **kwargs):

    X_Optimum = []
    F_Optimum = []
    TestSolution = []
    TestSolution_Name = []
    TestSolution_Time = []
    Time_temp = []
    """"
    ===================================================================
        If we are undertaken model validation through benchmarks, we
          may opt to run all benchmark test-cases or a specific one
          controlled in the original command line as:
    
              a) python Optimiser.py SAA Benchmarks All
                            or
              b) python Optimiser.py SAA Benchmarks N
    
          respectively, where N is the number of the required test-case  
          as defined in the 'Benchmarks.in' file.   
    =================================================================== """

    N_Tests, dummy = IO.CountingNumberOfTests(
    )  # Checking the total number of test-cases.
    if (Task == 'Benchmarks'):
        if kwargs:
            for key in kwargs:
                if (key == 'FileName'):
                    TestCases = kwargs[key]
                    if TestCases == 'All':
                        Test = 100 * N_Tests
                    else:
                        Test = int(TestCases)

    elif (Task == 'Problem'):
        if kwargs:
            for key in kwargs:
                if (key == 'FileName'):
                    ProblemFileName = kwargs[key]
                    Test = 0
                    N_Tests = 0

    else:
        sys.exit('In SimulatedAnnealing function. Option not found')
    """"
    ===================================================================
        Now, depending on the case, 'Benchmarks' or 'Problem' we 
          proceed the optimisation, if:
    
              a) 'Problem': then N_Tests = 0 and we run SAA just once
                            or
              b) 'Benchmarks': there are 2 options here,
                  b.1 ) 'All': it will read each cooling schedule 
                               file for all test-cases and proceed
                               with the optimisation.
                  b.2 ) 'N': where 1 <= N <= N_Tests. It will read
                             only the cooling schedule of test-case
                             N and proceed with the optimisation.
    =================================================================== """

    jtest = 0

    for itest in xrange(1, N_Tests + 1):

        if (Task == 'Benchmarks'):

            if TestCases != 'All':  # Dealing with test-case N

                if itest == Test:
                    SaT.Function_Name, SaT.Minimum, SaT.Ndim, SaT.NS, SaT.NT, SaT.MaxEvl, SaT.EPS, SaT.RT, SaT.Temp, \
                        SaT.LowerBounds, SaT.UpperBounds, SaT.VM, SaT.C, SaT.Debugging, \
                        SaT.SA_X, SaT.BenchmarkSolution = IO.ReadInCoolingSchedule( Test_Number = Test )
                    print '======================', SaT.Function_Name, '======================'
                else:
                    continue
            else:
                SaT.Function_Name, SaT.Minimum, SaT.Ndim, SaT.NS, SaT.NT, SaT.MaxEvl, SaT.EPS, SaT.RT, SaT.Temp, \
                    SaT.LowerBounds, SaT.UpperBounds, SaT.VM, SaT.C, SaT.Debugging, \
                    SaT.SA_X, SaT.BenchmarkSolution = IO.ReadInCoolingSchedule( Test_Number = itest )
                print '======================', SaT.Function_Name, '======================'

        elif (Task == 'Problem'):
            SaT.Function_Name, SaT.Minimum, SaT.Ndim, SaT.NS, SaT.NT, SaT.MaxEvl, SaT.EPS, SaT.RT, SaT.Temp, \
                SaT.LowerBounds, SaT.UpperBounds, SaT.VM, SaT.C, SaT.Debugging, \
                SaT.SA_X, SaT.BenchmarkSolution = IO.ReadInCoolingSchedule( File_Name = ProblemFileName )

        else:
            sys.exit('In SimulatedAnnealing. Option not found')
        """
            ===================================================================
                      Initial Assessemnt of the Objective Function
            ===================================================================
        """
        """ Calling the function for the first time before the SA main loop """
        if Task == 'Benchmarks':
            Func = BTest.TestFunction(SaT.Function_Name, SaT.Ndim, SaT.SA_X)

        else:  # Problems
            Func = ObF.ObjFunction(SaT.Function_Name, SaT.Ndim, SaT.SA_X)
        """ The function must be minimum """
        if SaT.Minimum:
            Func = -Func
        """"                  Printing into the *out file                    """
        IO.f_SAOutput.write('\n')
        IO.f_SAOutput.write(
            'Initial evaluation of the function: {a:.4e}'.format(a=Func) +
            '\n')
        """
            ===================================================================
                Calling main SA loop:       
            ===================================================================
        """

        X_OPT, F_OPT = ASA_Loops(Task, Func)

        X_Optimum.append(X_OPT)
        F_Optimum.append(F_OPT)
        """
           =====================================================================
               Assessing the solution (comparison against known solution)
           ====================================================================="""
        if Task == 'Benchmarks':
            TestSolution.append(BTest.AssessTests(X_OPT,
                                                  SaT.BenchmarkSolution))
            TestSolution_Name.append(SaT.Function_Name)

            TestTime = time.clock()
            Time_temp.append(TestTime)
            if TestCases == 'All':
                if itest > 1:
                    TestSolution_Time.append(TestTime - Time_temp[itest - 1])
                else:
                    TestSolution_Time.append(TestTime)

            IO.f_SAOutput.write('\n')
            IO.f_SAOutput.write(
                '===========================================================')
            IO.f_SAOutput.write('\n')
            IO.f_SAOutput.write(
                '            Assessment of the test-cases :      ')
            IO.f_SAOutput.write('\n')
            IO.f_SAOutput.write('{a:}:  {b:}'.format(
                a=SaT.Function_Name, b=TestSolution[jtest]) + '\n')
            IO.f_SAOutput.write('\n')
            jtest += 1

        else:  # Problem
            TestTime = time.clock()
            TestSolution_Time.append(
                time.clock() -
                SaT.Time_Init)  # Measuring CPU time for the problem/test

    print 'TestSolutionTime_all:', TestSolution_Time

    if (Task == 'Benchmarks') and (TestCases == 'All'):
        Print.Print_SAA_Diagnostic(Bench_AllTestCases='yes',
                                   Solution=TestSolution,
                                   Solution_Name=TestSolution_Name,
                                   Solution_Time=TestSolution_Time)

    #return X_OPT, F_OPT
    return X_Optimum, F_Optimum
def ASA_Loops(Task, Func):
    """ For debugging """
    #pdb.set_trace()
    TestName = SaT.Function_Name

    IO.f_SAOutput.write('\n')
    IO.f_SAOutput.write('Initialising SA Algorithm for: {a:}'.format(
        a=TestName) + '\n')
    """ Initialisation of a few parameters. """
    Try = False
    NAcc = 0
    Nobds = 0
    NFCNEV = 0
    NEps = 4
    MaxNum = 1.e20

    NACP = [0 for i in range(SaT.Ndim)]
    XP = [0. for i in range(SaT.Ndim)]
    FStar = [MaxNum for i in range(NEps)]
    FStar[0] = Func

    FOpt = Func
    XOpt = SaT.SA_X
    X_Try = SaT.SA_X
    XOpt_f = [0. for i in range(SaT.Ndim)]
    """ The 'Fraction' variable assess if the function to be optimised is
           a thermodynamic function (TRUE) and therefore the elements of the
           solution-coordinate needs to be bounded (0,1) and the summation
           of the N-1 elements must be smaller than 1.
        If FALSE then the above is neglected.                               """
    if Task == 'Benchmarks':
        Fraction = False
    else:
        Fraction = True

    kloop = 0
    """ Beginning of the main outter loop: """
    while kloop <= SaT.MaxEvl:

        NUp = 0
        NRej = 0
        NDown = 0
        LNobds = 0
        """ Beginning of the m loop: """
        mloop = 0
        while mloop < SaT.NT:
            """ Beginning of j loop: """
            jloop = 0
            while jloop < SaT.NS:
                """ Beginning of the h loop: """
                hloop = 0

                while hloop < SaT.Ndim:

                    if Fraction:
                        dim = SaT.Ndim - 1
                    else:
                        dim = SaT.Ndim

                    for i in range(dim):
                        rand = RanGen.RandomNumberGenerator(dim)

                        if (i == hloop):
                            XP[i] = X_Try[i] + SaT.VM[i] * (2. * rand[i] - 1.)
                        else:
                            XP[i] = X_Try[i]
                    """ ===========================================================
                            Feasibility Test (only for Thermod problems) -- check
                              for compositional constraints.
                        =========================================================== """
                    if Fraction:
                        XP[dim - 1] = 1. - SpFunc.ListSum(XP[0:dim])

                    SpFunc.Envelope_Constraints(XP,
                                                NDim=SaT.Ndim,
                                                LBounds=SaT.LowerBounds,
                                                UBounds=SaT.UpperBounds,
                                                TryC=Try,
                                                IsNormalised=Fraction)

                    if Try:
                        LNobds += 1
                        Nobds += 1
                    """ ============================================================ """

                    if Task == 'Benchmarks':
                        FuncP = BTest.TestFunction(SaT.Function_Name, SaT.Ndim,
                                                   XP)
                    else:  # Problems
                        FuncP = ObF.ObjFunction(SaT.Function_Name, SaT.Ndim,
                                                XP)
                    """ The function must be minimum """
                    if SaT.Minimum:
                        FuncP = -FuncP

                    NFCNEV += 1  # Number of evaluation of the function
                    """
                       ==================================================================
                         If there were more than MAXEVL evaluations of the objective
                            function, the SA algorithm will finish.
                       =================================================================="""

                    if (NFCNEV >= SaT.MaxEvl):
                        FOpt = -FOpt
                        Print.Print_SAA_Diagnostic(MaxEval='yes',
                                                   FOpt=FOpt,
                                                   XOpt=XOpt_f,
                                                   NFCNEV=NFCNEV)
                        sys.exit(
                            'SAA did not converge. Too many evaluations of the function!'
                        )
                    """"
                       ==================================================================
                         The new solution-coordinate is accepted and the objective 
                            function increases.
                       =================================================================="""

                    if (FuncP >= Func):
                        for i in range(SaT.Ndim):
                            X_Try[i] = XP[i]
                        Func = FuncP

                        if SaT.Debugging == True:
                            IO.f_SAOutput.write(
                                '{s:20} New vector-solution is accepted ( X: {a:}) with solution {b:.4f}'
                                .format(s=' ', a=X_Try, b=FuncP) + '\n')

                        NAcc += 1
                        NACP[hloop] = NACP[hloop] + 1
                        NUp += 1
                        """ If the new FP is larger than any other point, this will be 
                               chosen as the new optimum                               """

                        if (FuncP > FOpt):
                            for i in range(SaT.Ndim):
                                XOpt[i] = XP[i]
                            FOpt = FuncP
                            for i in range(SaT.Ndim):
                                XOpt_f[i] = XP[i]

                            print 'NFCNEV(', NFCNEV, '), XOpt: ', XOpt_f, ' with FOpt: ', FOpt, '(Analytical:', -BTest.TestFunction(
                                SaT.Function_Name, SaT.Ndim,
                                SaT.BenchmarkSolution[0:SaT.Ndim]), ')'

                            if SaT.Debugging == True:
                                IO.f_SAOutput.write(
                                    '{s:20} New XOpt: {a:} with FOpt: {b:}'.
                                    format(s=' ', a=XOpt_f, b=FOpt) + '\n')

                    else:
                        """ However if FuncP is smaller than the others, thus the Metropolis criteria 
                               (Gaussian probability density function) - or any other density function
                               that may be added latter - may be used to either accept or reject this
                               coordinate.                                                            """

                        rand = RanGen.RandomNumberGenerator(SaT.Ndim)
                        #Density = math.exp( ( FuncP - Func ) / SaT.Temp )#max( SaT.Temp, SaT.EPS ) )
                        if SaT.Temp < max(1.e-6, SaT.EPS):
                            Density = math.exp(
                                (FuncP - Func) / max(1.e-3 * SaT.EPS, rand[0]))
                        else:
                            Density = math.exp((FuncP - Func) / SaT.Temp)
                        temp = 1.
                        for i in range(SaT.Ndim):
                            temp = temp * rand[i]
                        Density_Gauss = math.sqrt(abs(temp))

                        if (Density_Gauss < Density):
                            for i in range(SaT.Ndim):
                                X_Try[i] = XP[i]
                            Func = FuncP

                            if SaT.Debugging == True:
                                IO.f_SAOutput.write('\n \n ')
                                IO.f_SAOutput.write(
                                    '{s:20} Metropolis Criteria; New vector-solution is generated ( X: {a:}) with solution {b:.4f}'
                                    .format(s=' ', a=X_Try, b=FuncP) + '\n')

                            NAcc += 1
                            NACP[hloop] = NACP[hloop] + 1
                            NDown += 1

                        else:
                            NRej += 1
                    """ End of h loop """
                    hloop += 1
                """ End of j loop """
                jloop += 1
            """
               ==================================================================
                 As half of the evaluations may be accepted, thus the VM array
                     may need to be adjusted.
               ================================================================== """

            for i in range(SaT.Ndim):
                Ratio = float(NACP[i]) / float(SaT.NS)
                if (Ratio > 0.6):
                    SaT.VM[i] = SaT.VM[i] * (1. + SaT.C[i] *
                                             (Ratio - 0.6) / 0.4)

                elif (Ratio < 0.4):
                    SaT.VM[i] = SaT.VM[i] / (1. + SaT.C[i] *
                                             (0.4 - Ratio) / 0.4)

                if (SaT.VM[i] > (SaT.UpperBounds[i] - SaT.LowerBounds[i])):
                    SaT.VM[i] = SaT.UpperBounds[i] - SaT.LowerBounds[i]

            if SaT.Debugging == True:
                IO.f_SAOutput.write(
                    '{s:20} {a:3d} Points rejected. VM is adjusted to {b:}'.
                    format(s=' ', a=NRej, b=SaT.VM) + '\n')

            NACP = [0 for i in range(SaT.Ndim)]
            """ End of m loop """
            mloop += 1
        """
           =======================================================================
                Diagnostics of the algorithm before the next temperature reduction
           ======================================================================= """

        Print.Print_SAA_Diagnostic(Diagnostics='yes',
                                   FOpt=FOpt,
                                   NUp=NUp,
                                   NDown=NDown,
                                   NRej=NRej,
                                   NAcc=NAcc,
                                   LNobds=LNobds,
                                   NFCNEV=NFCNEV,
                                   XOpt=XOpt,
                                   FStar=FStar)

        # This will make the tests run faster as we know the solution, thus they do
        #     not need to continue search if the solution if close enough
        if Task == 'Benchmarks':
            Quit = BTest.AssessTests(XOpt_f, SaT.BenchmarkSolution)
            if Quit:
                if SaT.Minimum:
                    FOpt = -FOpt
                Print.Print_SAA_Diagnostic(Termination='yes',
                                           FOpt=FOpt,
                                           NRej=NRej,
                                           XOpt=XOpt_f,
                                           NFCNEV=NFCNEV)
                return XOpt_f, FOpt
        """
           ==========================================================
                     Checking the stoppage criteria
           ==========================================================  """

        Quit = False
        FStar[0] = Func

        if FOpt - FStar[0] <= SaT.EPS:
            Quit = True

        for i in range(NEps):
            if abs(Func - FStar[i]) > SaT.EPS:
                Quit = False

        if Quit and (Task == 'Benchmarks'):
            Quit = BTest.AssessTests(XOpt_f, SaT.BenchmarkSolution)
        """
           ==========================================================
               Termination of the Simulated Annealing algorithm       
           ==========================================================  """

        if Quit:
            #X_Try = XOpt
            if SaT.Minimum:
                FOpt = -FOpt

            Print.Print_SAA_Diagnostic(Termination='yes',
                                       FOpt=FOpt,
                                       NRej=NRej,
                                       XOpt=XOpt_f,
                                       NFCNEV=NFCNEV)

            return XOpt_f, FOpt
        """
           ==========================================================
              If the stoppage criteria can not be reached, then
                 continue the K-LOOP
           ==========================================================  """

        SaT.Temp = SaT.RT * SaT.Temp
        for i in xrange(NEps - 1, 0, -1):
            FStar[i] = FStar[i - 1]

        Func = FOpt
        for i in range(SaT.Ndim):
            X_Try[i] = XOpt[i]
        """ End of k loop """
        kloop += 1