DE_dynamic_switch.py

# -*- coding: utf-8 -*-
import numpy as np
import random
import csv
# 1. Sphere Function
def sphere(x):
    return np.sum(np.square(x))
# 2. Rosenbrock Function
def rosenbrock(x):
    return np.sum(100 * (x[1:] – x[:-1]**2)**2 + (x[:-1] – 1)**2)
# 3. Rastrigin Function
def rastrigin(x):
    return np.sum(x**2 – 10 * np.cos(2 * np.pi * x) + 10)
# 4. Ackley Function
def ackley(x):
    n = len(x)
    return -20 * np.exp(-0.2 * np.sqrt(np.sum(x**2) / n)) – np.exp(np.sum(np.cos(2 * np.pi * x)) / n) + 20 + np.e
# 5. Griewank Function
def griewank(x):
    return np.sum(x**2 / 4000) – np.prod(np.cos(x / np.sqrt(np.arange(1, len(x) + 1)))) + 1
# 6. Schwefel Function
def schwefel(x):
    n = len(x)
    return 418.9829 * n – np.sum(x * np.sin(np.sqrt(np.abs(x))))
# 7. Levy Function
def levy(x):
    w = 1 + (x – 1) / 4
    return (np.sin(np.pi * w[0])**2
            + np.sum((w[:-1] – 1)**2 * (1 + 10 * np.sin(np.pi * w[:-1] + 1)**2))
            + (w[-1] – 1)**2 * (1 + np.sin(2 * np.pi * w[-1])**2))
# 8. Zakharov Function
def zakharov(x):
    i = np.arange(1, len(x) + 1)
    return np.sum(x**2) + (np.sum(0.5 * i * x))**2 + (np.sum(0.5 * i * x))**4
# 9. Dixon-Price Function
def dixon_price(x):
    i = np.arange(2, len(x) + 1)
    return (x[0] – 1)**2 + np.sum(i * (2 * x[1:]**2 – x[:-1])**2)
# 10. Styblinski-Tang Function
def styblinski_tang(x):
    return 0.5 * np.sum(x**4 – 16 * x**2 + 5 * x)
# 11. Three-Hump Camel Function
def three_hump_camel(x):
    return 2 * x[0]**2 – 1.05 * x[0]**4 + x[0]**6 / 6 + x[0] * x[1] + x[1]**2
# 12. Easom Function
def easom(x):
    return -np.cos(x[0]) * np.cos(x[1]) * np.exp(-(x[0] – np.pi)**2 – (x[1] – np.pi)**2)
# 13. Beale Function
def beale(x):
    return ((1.5 – x[0] + x[0] * x[1])**2
            + (2.25 – x[0] + x[0] * x[1]**2)**2
            + (2.625 – x[0] + x[0] * x[1]**3)**2)
# 14. Booth Function
def booth(x):
    return (x[0] + 2*x[1] – 7)**2 + (2*x[0] + x[1] – 5)**2
# 15. Matyas Function
def matyas(x):
    return 0.26 * (x[0]**2 + x[1]**2) – 0.48 * x[0] * x[1]
# 16. Branin Function
def branin(x):
    a = 1.0
    b = 5.1 / (4 * np.pi**2)
    c = 5 / np.pi
    r = 6
    s = 10
    t = 1 / (8 * np.pi)
    return a * (x[1] – b * x[0]**2 + c * x[0] – r)**2 + s * (1 – t) * np.cos(x[0]) + s
# 17. Alpine Function
def alpine(x):
    return np.sum(np.abs(x * np.sin(x) + 0.1 * x))
# 18. Sum of Different Powers Function
def sum_of_different_powers(x):
    return np.sum(np.abs(x)**(np.arange(2, len(x) + 2)))
# 19. Drop-Wave Function
def drop_wave(x):
    return -(1 + np.cos(12 * np.sqrt(x[0]**2 + x[1]**2))) / (0.5 * (x[0]**2 + x[1]**2) + 2)
# 20. Eggholder Function
def eggholder(x):
    return -(x[1] + 47) * np.sin(np.sqrt(np.abs(x[1] + x[0] / 2 + 47))) – x[0] * np.sin(np.sqrt(np.abs(x[0] – (x[1] + 47))))
# 21. Schaffer Function N.1
def schaffer_n1(x):
    return 0.5 + (np.sin(x[0]**2 – x[1]**2)**2 – 0.5) / (1 + 0.001 * (x[0]**2 + x[1]**2))**2
# 22. Schaffer Function N.2
def schaffer_n2(x):
    return 0.5 + (np.sin(x[0]**2 + x[1]**2)**2 – 0.5) / (1 + 0.001 * (x[0]**2 + x[1]**2))**2
# 23. Shubert Function
def shubert(x):
    i = np.arange(1, 6)
    return np.prod(np.sum(i * np.cos((i + 1) * x[:, None] + i), axis=1))
# 24. Bukin Function N.6
def bukin_n6(x):
    return 100 * np.sqrt(np.abs(x[1] – 0.01 * x[0]**2)) + 0.01 * np.abs(x[0] + 10)
# 25. Michalewicz Function
def michalewicz(x, m=10):
    i = np.arange(1, len(x) + 1)
    return -np.sum(np.sin(x) * (np.sin(i * x**2 / np.pi))**(2 * m))
# 26. Xin-She Yang Function
def xin_she_yang(x):
    return np.sum(np.abs(x)) * np.exp(-np.sum(np.sin(x**2)))
# 27. Sum Squares Function
def sum_squares(x):
    i = np.arange(1, len(x) + 1)
    return np.sum(i * x**2)
# 28. Bent Cigar Function
def bent_cigar(x):
    return x[0]**2 + 1e6 * np.sum(x[1:]**2)
# 29. Katsuura Function
def katsuura(x):
    i = np.arange(1, len(x) + 1)
    term1 = 1 + 1 / 32 * np.sum(i * x)
    term2 = np.prod((1 + i * x) / (i + i * x**2))
    return term1 * term2 – 1
# 30. Happy Cat Function
def happy_cat(x, alpha=1/8):
    n = len(x)
    s = np.sum(x**2)
    return ((s – n)**2)**alpha + (0.5 * s + np.sum(x)) / n + 0.5
# Define the benchmark functions
# … (use the previously provided implementations)
# List of benchmark functions
benchmark_functions = [
    („Sphere“, sphere),
    („Rosenbrock“, rosenbrock),
    („Rastrigin“, rastrigin),
    („Ackley“, ackley),
    („Griewank“, griewank),
    („Schwefel“, schwefel),
    („Levy“, levy),
    („Zakharov“, zakharov),
    („Dixon-Price“, dixon_price),
    („Styblinski-Tang“, styblinski_tang),
    („Three-Hump Camel“, three_hump_camel),
    („Easom“, easom),
    („Beale“, beale),
    („Booth“, booth),
    („Matyas“, matyas),
    („Branin“, branin),
    („Alpine“, alpine),
    („Sum of Different Powers“, sum_of_different_powers),
    („Drop-Wave“, drop_wave),
    („Eggholder“, eggholder),
    („Schaffer N.1“, schaffer_n1),
    („Schaffer N.2“, schaffer_n2),
    („Shubert“, shubert),
    („Bukin N.6“, bukin_n6),
    („Michalewicz“, michalewicz),
    („Xin-She Yang“, xin_she_yang),
    („Sum Squares“, sum_squares),
    („Bent Cigar“, bent_cigar),
    („Katsuura“, katsuura),
    („Happy Cat“, happy_cat),
]
def de_dynamic_switch_1_bin (func, bounds, dimensions, population_size, max_iterations, F, CR, alpha=0.1):
    # Initialize population
    pop = np.random.rand(population_size, dimensions)
    min_b, max_b = np.asarray(bounds).T
    diff = np.fabs(min_b – max_b)
    pop_denorm = min_b + pop * diff
    fitness = np.asarray([func(ind) for ind in pop_denorm])
    # Initialize the „time since last update“ counter
    time_since_update = np.zeros(population_size, dtype=int)
    for _ in range(max_iterations):
        for i in range(population_size):
            indices = [index for index in range(population_size) if index != i]
            a_idx, b_idx, base_idx = np.random.choice(indices, 3, replace=False)
            # Calculate switching probabilities
            P_a = np.exp(-alpha * time_since_update[a_idx])
            P_b = np.exp(-alpha * time_since_update[b_idx])
            # Perform dynamic switching with best-so-far individual
            best_idx = np.argmin(fitness)
            if np.random.rand() < P_a:
                a_idx = best_idx
            if np.random.rand() < P_b and a_idx != best_idx:
                b_idx = best_idx
            X_base = pop[base_idx]
            a = pop[a_idx]
            b = pop[b_idx]
            mutant = np.clip(X_base + F * (a – b), 0, 1)
            cross_points = np.random.rand(dimensions) < CR
            if not np.any(cross_points):
                cross_points[np.random.randint(0, dimensions)] = True
            trial = np.where(cross_points, mutant, pop[i])
            trial_denorm = min_b + trial * diff
            f = func(trial_denorm)
            if f < fitness[i]:
                fitness[i] = f
                pop[i] = trial
                time_since_update[i] = 0
            else:
                time_since_update[i] += 1
    best_idx = np.argmin(fitness)
    return min_b + pop[best_idx] * diff, fitness[best_idx]
def run_de_on_benchmark(func, dimensions, num_runs, population_size=30, max_iterations=100, F=0.8, CR=0.9):
    best_results = []
    for run in range(num_runs):
        _, best_fitness = de_dynamic_switch_1_bin (func, [(-500, 500)] * dimensions, dimensions, population_size, max_iterations, F, CR)
        best_results.append(best_fitness)
    return best_results
# Run the algorithm on each benchmark function
num_runs = 30
results = []
for name, func in benchmark_functions:
    best_results = run_de_on_benchmark(func, 10, num_runs)
    mean_result = np.mean(best_results)
    std_dev = np.std(best_results)
    print(f“{name}: Mean result = {mean_result}, Std. dev. = {std_dev}“)
    results.append((name, best_results, mean_result, std_dev))
# Export results to a CSV file
with open(„de_results.csv“, „w“, newline=““) as csvfile:
    writer = csv.writer(csvfile)
    writer.writerow([„Function“, „Best results“, „Mean“, „Std. dev.“])
    for name, best_results, mean_result, std_dev in results:
        writer.writerow([name, „;“.join(map(str, best_results)), mean_result, std_dev])