Guest User

Untitled

a guest
May 3rd, 2023
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.73 KB | None | 0 0
  1. import numpy as np
  2. import operator
  3. import random
  4. from deap import base, creator, gp, tools, algorithms
  5.  
  6. # Real pyramid dimensions
  7. base_length = 230.4
  8. height = 146.6
  9.  
  10. # Calculating other constants
  11. pyramid_dimensions={
  12.     diagonal:           np.sqrt(2 * base_length**2),
  13.     apothem:            np.sqrt((base_length / 2)**2 + height**2),
  14.     slant_height:       np.sqrt(height**2 + (base_length / 2)**2),
  15.     base_perimeter:     4 * base_length,
  16.     base_area:          base_length**2,
  17.     base_angle:         np.arctan(height / (base_length / 2)),
  18.     side_area:          2 * base_length * slant_height,
  19.     side_angle:         np.arctan((base_length / 2) / height),
  20.     volume:             (1 / 3) * base_area * height,
  21.     corner_edge_length: np.sqrt(height**2 + diagonal**2 / 4),
  22. }
  23.  
  24. # Target value (e - 1)
  25. target = np.e - 1
  26.  
  27. # For cutsom gen_tree
  28. MAX_TREE_DEPTH = 2
  29.  
  30.  
  31. # Create types
  32. creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
  33. creator.create("Individual", gp.PrimitiveTree, fitness=creator.FitnessMin)
  34.  
  35. # Initialize the primitive set for pyramid constants
  36. pset = gp.PrimitiveSetTyped("MAIN", [float] * 12, float)
  37. pset.addPrimitive(operator.add, [float, float], float)
  38. pset.addPrimitive(operator.sub, [float, float], float)
  39. pset.addPrimitive(operator.mul, [float, float], float)
  40. pset.addPrimitive(operator.truediv, [float, float], float)
  41.  
  42. # Primitive set for integers
  43. for i in range(1, 11):
  44.     pset.addTerminal(i, name=f"N{i}", ret_type=float)
  45.  
  46. # Rename arguments for easier understanding
  47. args = {}
  48. for i in range(len(pyramid_dimensions)):
  49.    
  50.  
  51. 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')
  52.  
  53. # Custom tree generation that use pyramid constants and integers
  54. def gen_tree(pset, max_depth, current_depth):
  55.     if random.random() > 0.5:
  56.         prim = random.choice(pset.primitives[pset.ret])
  57.     else:
  58.         prim = random.choice(pset.terminals[pset.ret])
  59.  
  60.     if isinstance(prim, gp.Primitive):
  61.         node = gp.PrimitiveTree([prim])
  62.         for _ in range(prim.arity):
  63.             child_tree = gen_tree(pset, max_depth, current_depth + 1)
  64.             node.extend(child_tree)
  65.     else:
  66.         node = gp.PrimitiveTree([prim])
  67.  
  68.     return node
  69.  
  70.  
  71. # Define the fitness function
  72. def eval_fit(individual, *consts):
  73.     func = gp.compile(individual, pset)
  74.     error = 0
  75.     try:
  76.         result = func(*consts)
  77.         error = abs(result - np.pi) # (np.e - 1)
  78.     except (ZeroDivisionError, OverflowError, ValueError, TypeError):
  79.         error = float('inf')
  80.     return [error]
  81.  
  82. # Create the toolbox
  83. toolbox = base.Toolbox()
  84. toolbox.register("expr", gp.genHalfAndHalf, pset=pset, min_=1, max_=2)
  85. toolbox.register("individual", tools.initIterate, creator.Individual, lambda: gen_tree(pset, MAX_TREE_DEPTH, 0))
  86. # toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.expr)
  87. toolbox.register("population", tools.initRepeat, list, toolbox.individual)
  88. toolbox.register("compile", gp.compile, pset=pset)
  89. 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)
  90. toolbox.register("select", tools.selTournament, tournsize=3)
  91. toolbox.register("mate", gp.cxOnePoint)
  92. toolbox.register("expr_mut", gp.genFull, min_=0, max_=2)
  93. toolbox.register("mutate", gp.mutUniform, expr=toolbox.expr_mut, pset=pset)
  94.  
  95. # Genetic algorithm parameters
  96. POPULATION_SIZE = 1000
  97. N_GENERATIONS = 100
  98. CROSSOVER_PROB = 0.8
  99. MUTATION_PROB = 0.2
  100.  
  101. # Main function
  102. def main():
  103.     random.seed(42)
  104.     pop = toolbox.population(n=POPULATION_SIZE)
  105.     hof = tools.HallOfFame(1)
  106.  
  107.     stats_fit = tools.Statistics(lambda ind: ind.fitness.values)
  108.     stats_size = tools.Statistics(len)
  109.     mstats = tools.MultiStatistics(fitness=stats_fit, size=stats_size)
  110.     mstats.register("avg", np.mean)
  111.     mstats.register("std", np.std)
  112.     mstats.register("min", np.min)
  113.     mstats.register("max", np.max)
  114.  
  115.     pop, log = algorithms.eaSimple(pop, toolbox, cxpb=CROSSOVER_PROB, mutpb=MUTATION_PROB, ngen=N_GENERATIONS, stats=mstats, halloffame=hof, verbose=True)
  116.  
  117.     best_ind = hof[0]
  118.     best_func = gp.compile(expr=best_ind, pset=pset)
  119.     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)
  120.  
  121.     print("Best individual: ", best_ind)
  122.     print("Best result: ", best_result)
  123.     print("Error: ", abs(best_result - target))
  124.  
  125.     return pop, log, hof
  126.  
  127. if __name__ == "__main__":
  128.     main()
Advertisement
Add Comment
Please, Sign In to add comment