минимизировать функцию Розенброка мю, лямбда Е. С. Стратегия конвергенции - PullRequest
0 голосов
/ 24 декабря 2018

Я не могу найти ошибку в своем коде для схождения по минимальному значению для функции Розенброка с mu, lambda ES.Мой код

    def rosenbrock(x):
    return np.sum((1-x[:-1])**2 + 100*(x[1:] - x[:-1]**2)**2, axis=0)

    def ES(N=5, mu=2, lambda_=100, generations=100, epsilon0=0.001):
    eps0 = epsilon0
    mu = mu
    lamb = lambda_
    leng = N
    tau = 1 / np.power(leng,0.5)
    taup = 1 / np.power(leng,0.25)
    gens = generations
    epsilon = 0.0
    epsilonp = 0.0
    pop = []
    run_stats = []
    for pare in range(mu):
        init_gen = init_generation(leng)
        pop.append(init_gen)

   for gen in range(gens):
        kids = generate_children(pop, lamb, tau, taup, eps0)
        pop, fitness = get_fittest(kids, mu, leng)
        run_stats.append(fitness)
    return run_stats


    def get_fittest(kids, mu, leng):
   new_pop = []
    fittest = []
    best_fitness = []
    tot_len = leng *2
    for k in kids:
        tot_len = int(len(k)/2)
        fitness = rosenbrock(k[:tot_len])
        fittest.append(fitness)
    for min_fit in range(mu):
        minpos = fittest.index(min(fittest))
        best_fitness.append(min(fittest))
        par = kids[minpos]
        new_pop.append(par)
        del fittest[minpos]
        del kids[minpos]
    b_fit = best_fitness[0]
    return new_pop, b_fit


    def generate_children(pop, lam, tau, taup, eps0):
    children = []
    pop_mem = int(len(pop))
    for x in range(lam):
        cur_p = np.random.randint(pop_mem)
        child = mutate_child(pop[cur_p], tau, taup, eps0)
        children.append(child)
    return children


    def mutate_child(child, tau, taup, eps0):
    ch_len = int(len(child)/2)
    sig_values = child[ch_len:]
    old_omega= child[:ch_len]
    e_si = np.random.uniform(0, tau, size=(ch_len))
    e_si_prime = np.random.uniform(0, taup, size=(ch_len))
    new_sig = []
    new_omega = []
    for pos in range(ch_len):
        sig_prime = sig_values[pos] * np.exp(e_si[pos]+e_si_prime[pos])
        if sig_prime < eps0 and sig_prime > 0:
            sig_prime = eps0
        if sig_prime > - eps0 and sig_prime < 0:
            sig_prime = - eps0
        new_sig.append(sig_prime)
    for pos in range(ch_len):
        omega_prime = old_omega[pos] +  new_sig[pos] * np.random.uniform(0, 1)
        if omega_prime < -5:
            omega_prime = -5
        if omega_prime > 10:
            omega_prime = 10
       new_omega.append(omega_prime)
    child = np.concatenate((new_omega, new_sig), axis=None)
    return child

Я знаю, что в данный момент код не является "чистым", но прежде чем я это сделаю, я хотел бы понять, почему он не сходится, когда я зацикливаюсь на x поколений.

Кто-нибудь может определить ошибку?

Спасибо,

Роман

1 Ответ

0 голосов
/ 27 декабря 2018

Rosenbrock разработан так, чтобы его было сложно оптимизировать.Я не ожидал, что смогу найти глобальный минимум 5-мерного Розенброка в 100 мутациях.Если вы где-то рядом, вы сделали столько, сколько можете надеяться сделать за это время.

...