示例#1
0
def apply_localsearch(name, method, fitness_fun, bounds, current_best,
                      current_best_fitness, maxevals, fid):
    global SR_MTS
    global SR_global_MTS

    lower = bounds[0][0]
    upper = bounds[0][1]

    if method == 'grad':
        sol, fit, info = fmin_l_bfgs_b(fitness_fun,
                                       x0=current_best,
                                       approx_grad=1,
                                       bounds=bounds,
                                       maxfun=maxevals,
                                       disp=False)
        funcalls = info['funcalls']
    elif method == 'mts':
        #        import ipdb
        #        ipdb.set_trace()
        if name.lower() == "global":
            SR = SR_global_MTS
        else:
            SR = SR_MTS

        res, SR_MTS = mtsls(fitness_fun, current_best, current_best_fitness,
                            lower, upper, maxevals, SR)
        sol = res.solution
        fit = res.fitness
        funcalls = maxevals
    else:
        raise NotImplementedError(method)

    if fit <= current_best_fitness:
        fid.write(
            get_improvement("{0} {1}".format(method.upper(), name),
                            current_best_fitness, fit))
        return EAresult(solution=np.array(sol),
                        fitness=fit,
                        evaluations=funcalls)
    else:
        return EAresult(solution=current_best,
                        fitness=current_best_fitness,
                        evaluations=funcalls)
def _mtsls_improve_dim(function, sol, best_fitness, i, check, SR):
    newsol = copy(sol)
    newsol[i] -= SR[i]
    newsol = check(newsol)
    fitness_newsol = function(newsol)
    evals = 1

    if fitness_newsol < best_fitness:
        best_fitness = fitness_newsol
        sol = newsol
    elif fitness_newsol > best_fitness:
        newsol = copy(sol)
        newsol[i] += 0.5 * SR[i]
        newsol = check(newsol)
        fitness_newsol = function(newsol)
        evals += 1

        if (fitness_newsol < best_fitness):
            best_fitness = fitness_newsol
            sol = newsol

    return EAresult(solution=sol, fitness=best_fitness, evaluations=evals)
示例#3
0
def improve(fun,
            run_info,
            dimension,
            check_evals,
            name_output=None,
            replace=True,
            popsize=100,
            H=100,
            population=None,
            population_fitness=None,
            initial_solution=None,
            MemF=None,
            MemCR=None,
            times=1,
            ignoreLimits=False):
    """
    It applies the DE elements.

    Params
    ------
    fun function of the problem to optimize.

    run_info is a dictionary with the following information:
         lower: double lower bounds
         upper: double upper bounds
         threshold: minimum optim value
    
    dimension of the problem.
    max_evals maximum_evaluations_numbers.
    name_output name of the output file
    run number of evaluations
    replace replace the file
    debug show the debug info if it is true
    PS population size
    times the number of runs to carry out.
    ignoreLimits ignore the limits in the run.
    """
    assert isinstance(dimension, int), 'dimension should be integer'
    assert (dimension > 0), 'dimension must be positive'

    final, fid = get_experiments_file(name_output, replace, times=times)

    if final is not None:
        return final

    for attr in ['lower', 'upper', 'threshold', 'best']:
        assert attr in run_info.keys(
        ), "'{}' info not provided for benchmark".format(attr)

    # Added in a array the max evaluations
    if not isinstance(check_evals, list):
        check_evals = [check_evals]

    domain = (run_info['lower'], run_info['upper'])
    fun_best = run_info['best']
    maxEval = check_evals[-1]
    check_eval = check_evals.pop()

    if population is None:
        population = random_population(domain, dimension, popsize)
    else:
        popsize = population.shape[0]

    if initial_solution is not None:
        population[0] = initial_solution

    if population_fitness is None:
        population_fitness = np.array([fun(ind) for ind in population])
        currentEval = popsize
    else:
        currentEval = 0

    # Init memory with population
    memory = population.tolist()

    # Init F and CR
    memorySize = popsize * 2

    if MemF is None:
        MemF = np.ones(H) * 0.5

    if MemCR is None:
        MemCR = np.ones(H) * 0.5

    k = 0
    pmin = 2.0 / popsize

    while currentEval < maxEval:
        SCR = []
        SF = []
        F = np.zeros(popsize)
        CR = np.zeros(popsize)
        u = np.zeros((popsize, dimension))
        best_fitness = np.min(population_fitness)
        numEvalFound = currentEval

        for (i, xi) in enumerate(population):
            # Getting F and CR for that solution
            index_H = np.random.randint(0, H)
            meanF = MemF[index_H]
            meanCR = MemCR[index_H]
            Fi = np.random.normal(meanF, 0.1)
            CRi = np.random.normal(meanCR, 0.1)
            p = np.random.rand() * (0.2 - pmin) + pmin

            # Get two random values
            r1 = random_indexes(1, popsize, ignore=[i])
            # Get the second from the memory
            r2 = random_indexes(1, len(memory), ignore=[i, r1])
            xr1 = population[r1]
            xr2 = memory[r2]
            # Get one of the p best values
            maxbest = int(p * popsize)
            bests = np.argsort(population_fitness)[:maxbest]
            pbest = np.random.choice(bests)
            xbest = population[pbest]
            # Mutation
            v = xi + Fi * (xbest - xi) + Fi * (xr1 - xr2)
            # Special clipping
            if not ignoreLimits:
                v = shade_clip(domain, v, xi)
            # Crossover
            idxchange = np.random.rand(dimension) < CRi
            u[i] = np.copy(xi)
            u[i, idxchange] = v[idxchange]
            F[i] = Fi
            CR[i] = CRi

        # Update population and SF, SCR
        weights = []

        for i, fitness in enumerate(population_fitness):
            fitness_u = fun(u[i])

            if math.isnan(fitness_u):
                print(i)
                print(domain)
                print(u[i])
                print(fitness_u)

            assert not math.isnan(fitness_u)

            if fitness_u <= fitness:
                # Add to memory
                if fitness_u < fitness:
                    memory.append(population[i])
                    SF.append(F[i])
                    SCR.append(CR[i])
                    weights.append(fitness - fitness_u)

                if (fitness_u < best_fitness):
                    best_fitness = fitness_u
                    numEvalFound = currentEval

                population[i] = u[i]
                population_fitness[i] = fitness_u

        currentEval += popsize
        # Check the memory
        memory = limit_memory(memory, memorySize)

        # Update MemCR and MemF
        if len(SCR) > 0 and len(SF) > 0:
            Fnew, CRnew = update_FCR(SF, SCR, weights)
            MemF[k] = Fnew
            MemCR[k] = CRnew
            k = (k + 1) % H

    if fid is not None and currentEval >= check_eval:
        bestFitness = np.min(population_fitness)
        #print("bestFitness: {}".format(bestFitness))
        fid.write("[%.0e]: %e,%d\n" %
                  (check_eval, abs(bestFitness - fun_best), numEvalFound))
        fid.flush()

        if check_evals:
            check_eval = check_evals.pop(0)

    if fid is not None:
        fid.close()

    bestIndex = np.argmin(population_fitness)
    #print("SHADE Mean[F,CR]: ({0:.2f}, {1:.2f})".format(MemF.mean(), MemCR.mean()))

    return EAresult(fitness=population_fitness[bestIndex],
                    solution=population[bestIndex],
                    evaluations=numEvalFound), bestIndex
def ihshadels(fitness_fun,
              funinfo,
              dim,
              evals,
              evals_index,
              fid,
              start_time,
              info_de,
              popsize=100,
              debug=False,
              threshold=0.05):
    """
    Implementation of the proposal for CEC2015
    """
    lower = funinfo['lower']
    upper = funinfo['upper']
    evals = evals[:]

    initial_sol = np.ones(dim) * ((lower + upper) / 2.0)
    current_best_fitness = fitness_fun(initial_sol)

    maxevals = evals[evals_index - 1]
    totalevals = 1

    bounds = list(zip(np.ones(dim) * lower, np.ones(dim) * upper))
    bounds_partial = list(zip(np.ones(dim) * lower, np.ones(dim) * upper))

    popsize = min(popsize, 100)
    population = reset_de(popsize, dim, lower, upper, info_de)
    populationFitness = [fitness_fun(ind) for ind in population]
    bestId = np.argmin(populationFitness)

    initial_sol = np.ones(dim) * (lower + upper) / 2.0
    initial_fitness = fitness_fun(initial_sol)

    if initial_fitness < populationFitness[bestId]:
        fid.write("Best initial_sol\n")
        population[bestId] = initial_sol
        populationFitness[bestId] = initial_fitness

    current_best = EAresult(solution=population[bestId, :],
                            fitness=populationFitness[bestId],
                            evaluations=totalevals)

    crossover = DEcrossover.SADECrossover(2)
    best_global_solution = current_best.solution
    best_global_fitness = current_best.fitness
    current_best_solution = best_global_solution

    apply_de = apply_ls = True
    applyDE = applySHADE

    reset_ls(dim, lower, upper)
    methods = ['mts', 'grad']

    pool_global = PoolLast(methods)
    pool = PoolLast(methods)

    num_worse = 0

    evals_gs = min(50 * dim, 25000)
    evals_de = min(50 * dim, 25000)
    evals_ls = min(10 * dim, 5000)
    num_restarts = 0

    while totalevals < maxevals:

        method = ""

        if not pool_global.is_empty():
            previous_fitness = current_best.fitness
            method_global = pool_global.get_new()
            current_best = apply_localsearch("Global", method_global,
                                             fitness_fun, bounds,
                                             current_best_solution,
                                             current_best.fitness, evals_gs,
                                             fid)
            totalevals += current_best.evaluations
            fid.write("Best: %f - Evals: %f\n" %
                      (best_global_fitness, totalevals))
            improvement = get_ratio_improvement(previous_fitness,
                                                current_best.fitness)

            pool_global.improvement(method_global, improvement, 2)
            evals = check_evals(totalevals, evals, current_best.fitness,
                                best_global_fitness, fid)
            current_best_solution = current_best.solution
            current_best_fitness = current_best.fitness

            if current_best_fitness < best_global_fitness:
                best_global_solution = np.copy(current_best_solution)
                best_global_fitness = fitness_fun(best_global_solution)

        for i in range(1):
            current_best = EAresult(solution=current_best_solution,
                                    fitness=current_best_fitness,
                                    evaluations=0)
            set_region_ls()

            method = pool.get_new()
            fid.write("Best: %f - Evals: %f\n" %
                      (best_global_fitness, totalevals))
            if apply_de:
                result, bestInd = applyDE(crossover, fitness_fun, funinfo, dim,
                                          evals_de, population,
                                          populationFitness, bestId,
                                          current_best, fid, info_de)
                improvement = current_best.fitness - result.fitness
                totalevals += result.evaluations
                fid.write("Best: %f - Evals: %f\n" %
                          (best_global_fitness, totalevals))
                evals = check_evals(totalevals, evals, result.fitness,
                                    best_global_fitness, fid)
                current_best = result

            if apply_ls:
                result = apply_localsearch("Local", method, fitness_fun,
                                           bounds_partial,
                                           current_best.solution,
                                           current_best.fitness, evals_ls, fid)
                improvement = get_ratio_improvement(current_best.fitness,
                                                    result.fitness)
                totalevals += result.evaluations
                fid.write("Best: %f - Evals: %f\n" %
                          (best_global_fitness, totalevals))
                evals = check_evals(totalevals, evals, result.fitness,
                                    best_global_fitness, fid)
                current_best = result

                pool.improvement(method, improvement, 10, .25)

            current_best_solution = current_best.solution
            current_best_fitness = current_best.fitness

            if current_best_fitness < best_global_fitness:
                best_global_fitness = current_best_fitness
                best_global_solution = np.copy(current_best_solution)

            # Restart if it is not improved
            if (previous_fitness == 0):
                ratio_improvement = 1
            else:
                ratio_improvement = (previous_fitness -
                                     result.fitness) / previous_fitness

            #fid.write("TotalImprovement[{:d}%] {:.3e} => {:.3e} ({})\tRestart: {}\n".format(
            #int(100*ratio_improvement), previous_fitness, result.fitness,
            #num_worse, num_restarts))

            if ratio_improvement >= threshold:
                num_worse = 0
            else:
                num_worse += 1
                imp_str = ",".join([
                    "{}:{}".format(m, val)
                    for m, val in pool.improvements.items()
                ])
                #fid.write("Pools Improvements: {}".format(imp_str))

                # Random the LS
                reset_ls(dim, lower, upper, method)

            if num_worse >= 3:
                num_worse = 0
                #                import ipdb; ipdb.set_trace()
                #fid.write("Restart:{0:.2e} for {1:.2f}: with {2:d} evaluations\n".format(current_best.fitness, ratio_improvement, totalevals))
                # Increase a 1% of values
                posi = np.random.choice(popsize)
                new_solution = np.random.uniform(
                    -0.01, 0.01, dim) * (upper - lower) + population[posi]
                new_solution = np.clip(new_solution, lower, upper)
                current_best = EAresult(solution=new_solution,
                                        fitness=fitness_fun(new_solution),
                                        evaluations=0)
                current_best_solution = current_best.solution
                current_best_fitness = current_best.fitness

                # Init DE
                population = reset_de(popsize, dim, lower, upper, info_de)
                populationFitness = [fitness_fun(ind) for ind in population]
                totalevals += popsize
                fid.write("Best: %f - Evals: %f\n" %
                          (best_global_fitness, totalevals))
                totalevals += popsize
                fid.write("Best: %f - Evals: %f\n" %
                          (best_global_fitness, totalevals))

                # Random the LS
                pool_global.reset()
                pool.reset()
                reset_ls(dim, lower, upper)
                num_restarts += 1

            #fid.write("{0:.2e}({1:.2e}): with {2:d} evaluations\n".format(current_best_fitness, best_global_fitness, totalevals))
#            fid.write("improvement_group[{}] : {:.2e}\n".format(i, (initial_fitness - result.fitness)))
            fid.flush()

            if totalevals >= maxevals:
                break

    # Time stamp
    elapsed_time = time.clock() - start_time

    fid.write("\n\nSummary: Results\n\n")
    fid.write("Best global fitness: %e\n" % (abs(best_global_fitness)))
    fid.write("Time %f\n" % elapsed_time)
    fid.write("Total evals: %d\n" % totalevals)
    fid.write("BEST: \n%s" % (' '.join(map(str, best_global_solution))))
    fid.flush()
    return result
def mtsls(function, sol, fitness, lower, upper, maxevals, SR):
    """
    Implements the MTS LS

    parameters
    :function: to optimize.
    :sol: solution to improves.
    :lower: lower domain.
    :upper: upper domain.
    :maxevals: maximum evaluations.
    :SR: step size.
    :improved: indicate the ratio of previous improvement.
    """
    dim = len(sol)
    improve.init(dim)
    improved_dim = zeros(dim, dtype=bool)
    check = partial(clip, a_min=lower, a_max=upper)
    current_best = EAresult(solution=sol, fitness=fitness, evaluations=0)
    totalevals = 0

    improvement = zeros(dim)

    if totalevals < maxevals:
        dims = arange(dim)
        dim_sorted = improve.getDimensionsByProb(dims, 0.95, int(0.025 * dim))
        print("Redux size: ", len(dim_sorted))

        for i in dim_sorted:
            result = _mtsls_improve_dim(function, current_best.solution,
                                        current_best.fitness, i, check, SR)
            totalevals += result.evaluations
            improvement[i] = max(current_best.fitness - result.fitness, 0)

            if improvement[i]:
                improved_dim[i] = True
                current_best = result
            else:
                SR[i] /= 2

        dim_sorted = improvement.argsort()[::-1]
        d = 0

    while totalevals < maxevals:
        i = dim_sorted[d]
        result = _mtsls_improve_dim(function, current_best.solution,
                                    current_best.fitness, i, check, SR)
        totalevals += result.evaluations
        improvement[i] = max(current_best.fitness - result.fitness, 0)
        next_d = (d + 1) % dim

        if improvement[i]:
            improved_dim[i] = True
            current_best = result
            improve.updateValue(i, improvement[i])
        else:
            SR[i] /= 2
            d = next_d

    # Check lower value
    initial_SR = 0.2 * (upper - lower)
    SR[SR < 1e-15] = initial_SR

    return current_best, SR