Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import numpy as np
- import operator
- import random
- from deap import base, creator, gp, tools, algorithms
- # Real pyramid dimensions
- base_length = 230.4
- height = 146.6
- # Calculating other constants
- pyramid_dimensions={
- diagonal: np.sqrt(2 * base_length**2),
- apothem: np.sqrt((base_length / 2)**2 + height**2),
- slant_height: np.sqrt(height**2 + (base_length / 2)**2),
- base_perimeter: 4 * base_length,
- base_area: base_length**2,
- base_angle: np.arctan(height / (base_length / 2)),
- side_area: 2 * base_length * slant_height,
- side_angle: np.arctan((base_length / 2) / height),
- volume: (1 / 3) * base_area * height,
- corner_edge_length: np.sqrt(height**2 + diagonal**2 / 4),
- }
- # Target value (e - 1)
- target = np.e - 1
- # For cutsom gen_tree
- MAX_TREE_DEPTH = 2
- # Create types
- creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
- creator.create("Individual", gp.PrimitiveTree, fitness=creator.FitnessMin)
- # Initialize the primitive set for pyramid constants
- pset = gp.PrimitiveSetTyped("MAIN", [float] * 12, float)
- pset.addPrimitive(operator.add, [float, float], float)
- pset.addPrimitive(operator.sub, [float, float], float)
- pset.addPrimitive(operator.mul, [float, float], float)
- pset.addPrimitive(operator.truediv, [float, float], float)
- # Primitive set for integers
- for i in range(1, 11):
- pset.addTerminal(i, name=f"N{i}", ret_type=float)
- # Rename arguments for easier understanding
- args = {}
- for i in range(len(pyramid_dimensions)):
- pset.renameArguments(ARG0='base_length', ARG1='height', ARG2='diagonal', ARG3='apothem', ARG4='slant_height', ARG5='base_perimeter', ARG6='base_area', ARG7='base_angle', ARG8='side_area', ARG9='side_angle', ARG10='volume', ARG11='corner_edge_length')
- # Custom tree generation that use pyramid constants and integers
- def gen_tree(pset, max_depth, current_depth):
- if random.random() > 0.5:
- prim = random.choice(pset.primitives[pset.ret])
- else:
- prim = random.choice(pset.terminals[pset.ret])
- if isinstance(prim, gp.Primitive):
- node = gp.PrimitiveTree([prim])
- for _ in range(prim.arity):
- child_tree = gen_tree(pset, max_depth, current_depth + 1)
- node.extend(child_tree)
- else:
- node = gp.PrimitiveTree([prim])
- return node
- # Define the fitness function
- def eval_fit(individual, *consts):
- func = gp.compile(individual, pset)
- error = 0
- try:
- result = func(*consts)
- error = abs(result - np.pi) # (np.e - 1)
- except (ZeroDivisionError, OverflowError, ValueError, TypeError):
- error = float('inf')
- return [error]
- # Create the toolbox
- toolbox = base.Toolbox()
- toolbox.register("expr", gp.genHalfAndHalf, pset=pset, min_=1, max_=2)
- toolbox.register("individual", tools.initIterate, creator.Individual, lambda: gen_tree(pset, MAX_TREE_DEPTH, 0))
- # toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.expr)
- toolbox.register("population", tools.initRepeat, list, toolbox.individual)
- toolbox.register("compile", gp.compile, pset=pset)
- toolbox.register("evaluate", eval_fit, base_length, height, diagonal, apothem, slant_height, base_perimeter, base_area, base_angle, side_area, side_angle, volume, corner_edge_length)
- toolbox.register("select", tools.selTournament, tournsize=3)
- toolbox.register("mate", gp.cxOnePoint)
- toolbox.register("expr_mut", gp.genFull, min_=0, max_=2)
- toolbox.register("mutate", gp.mutUniform, expr=toolbox.expr_mut, pset=pset)
- # Genetic algorithm parameters
- POPULATION_SIZE = 1000
- N_GENERATIONS = 100
- CROSSOVER_PROB = 0.8
- MUTATION_PROB = 0.2
- # Main function
- def main():
- random.seed(42)
- pop = toolbox.population(n=POPULATION_SIZE)
- hof = tools.HallOfFame(1)
- stats_fit = tools.Statistics(lambda ind: ind.fitness.values)
- stats_size = tools.Statistics(len)
- mstats = tools.MultiStatistics(fitness=stats_fit, size=stats_size)
- mstats.register("avg", np.mean)
- mstats.register("std", np.std)
- mstats.register("min", np.min)
- mstats.register("max", np.max)
- pop, log = algorithms.eaSimple(pop, toolbox, cxpb=CROSSOVER_PROB, mutpb=MUTATION_PROB, ngen=N_GENERATIONS, stats=mstats, halloffame=hof, verbose=True)
- best_ind = hof[0]
- best_func = gp.compile(expr=best_ind, pset=pset)
- best_result = best_func(base_length, height, diagonal, apothem, slant_height, base_perimeter, base_area, base_angle, side_area, side_angle, volume, corner_edge_length)
- print("Best individual: ", best_ind)
- print("Best result: ", best_result)
- print("Error: ", abs(best_result - target))
- return pop, log, hof
- if __name__ == "__main__":
- main()
Advertisement
Add Comment
Please, Sign In to add comment