Advertisement
vatman

Untitled

May 16th, 2024
683
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.23 KB | None | 0 0
  1. import numpy as np
  2. import itertools
  3. import random
  4. import matplotlib.pyplot as plt
  5. import networkx as nx
  6. from networkx.drawing.layout import fruchterman_reingold_layout
  7.  
  8. np.random.seed(4)
  9.  
  10. VERTEX = 10.0
  11. EGDE = 0.0
  12. WEGDE = 0.0
  13. POPUL_LENGTH = 50
  14. GRAPH_LENGTH = 4
  15.  
  16.  
  17. def data(n):
  18.  
  19.     prufer_sequence = np.random.randint(0, n, n - 2)
  20.  
  21.     G1 = nx.from_prufer_sequence(prufer_sequence)
  22.  
  23.     pos = fruchterman_reingold_layout(G1, dim=2)
  24.  
  25.     edge_points = [pos[node] for node in G1.nodes]
  26.  
  27.     vectors = []
  28.     for point in edge_points:
  29.         for _ in range(10):
  30.             vectors.append(point + np.random.normal(size=2) * 0.05)
  31.     return vectors
  32.  
  33.  
  34. def visualize_graph(vectors, selected_vectors, G):
  35.     for point in vectors:
  36.         plt.scatter(point[0], point[1], color="b")
  37.     for node in selected_vectors:
  38.         plt.scatter(node[0], node[1], color="r")
  39.     pos = {
  40.         node: (selected_vectors[node][0], selected_vectors[node][1])
  41.         for node in G.nodes()
  42.     }
  43.     nx.draw(G, pos, with_labels=False, node_size=0, edge_color="k")
  44.     plt.show()
  45.  
  46.  
  47. def get_zero_population_graph(data, length_population=50, graph_length=3):
  48.     zero_population_graph = []
  49.     for i in range(length_population):
  50.         selected_elements = np.array(random.sample(data, graph_length))
  51.         prufer_sequence = np.random.randint(0, graph_length, graph_length - 2)
  52.         G1 = nx.from_prufer_sequence(prufer_sequence)
  53.         if i == 0:
  54.             zero_population = np.copy(selected_elements)
  55.         else:
  56.             zero_population = np.concatenate(
  57.                 [zero_population, selected_elements], axis=0
  58.             )
  59.         zero_population_graph.append(G1)
  60.  
  61.     zero_population = np.vsplit(zero_population, length_population)
  62.     return zero_population, zero_population_graph
  63.  
  64.  
  65. def calculate_vertex_energy(vertex, vectors, k):
  66.     distances = [np.linalg.norm(vertex - vector) for vector in vectors]
  67.  
  68.     if 0.0 in distances:
  69.         distances[distances.index(0.0)] = np.inf
  70.  
  71.     sorted_indices = np.argsort(distances)
  72.  
  73.     nearest_vector = sorted_indices[0]
  74.  
  75.     energy = 0
  76.     energy += k * np.linalg.norm(vertex - vectors[nearest_vector]) ** 2
  77.     return energy
  78.  
  79.  
  80. def calculate_edge_energy(edge, vectors, k):
  81.     v1, v2 = vectors[edge[0] - 1], vectors[edge[1] - 1]
  82.     return k * np.linalg.norm(v1 - v2) ** 2
  83.  
  84.  
  85. def calculate_wedge_energy(wedge, vectors, k):
  86.     v1, v2, v3 = vectors[wedge[0] - 1], vectors[wedge[1] - 1], vectors[wedge[2] - 1]
  87.     return k * np.linalg.norm(v1 + v3 - 2 * v2) ** 2
  88.  
  89.  
  90. def fitness_function(data, points, graph):
  91.     fitness = 0
  92.     for node in graph.nodes:
  93.         vertex_energy = calculate_vertex_energy(points[int(node) - 1], data, VERTEX)
  94.         fitness += vertex_energy
  95.     for edge in graph.edges:
  96.         edge_energy = calculate_edge_energy(edge, points, EGDE)
  97.         fitness += edge_energy
  98.     sum_wedge_energy = 0.0
  99.     for nodes in itertools.combinations(graph.nodes, 3):
  100.         if graph.has_edge(nodes[0], nodes[1]) and graph.has_edge(nodes[0], nodes[2]):
  101.             wedge_energy = calculate_wedge_energy(
  102.                 [nodes[1], nodes[0], nodes[2]], points, WEGDE
  103.             )
  104.             sum_wedge_energy += wedge_energy
  105.         elif graph.has_edge(nodes[0], nodes[1]) and graph.has_edge(nodes[1], nodes[2]):
  106.             wedge_energy = calculate_wedge_energy(nodes, points, WEGDE)
  107.             sum_wedge_energy += wedge_energy
  108.         elif graph.has_edge(nodes[0], nodes[2]) and graph.has_edge(nodes[1], nodes[2]):
  109.             wedge_energy = calculate_wedge_energy(
  110.                 [nodes[1], nodes[2], nodes[0]], points, WEGDE
  111.             )
  112.             sum_wedge_energy += wedge_energy
  113.     fitness += sum_wedge_energy
  114.     # print(1000 - fitness)
  115.     return 1000 - fitness
  116.  
  117.  
  118. def get_zero_population(seed, count_population, demention_population):
  119.     zero_population = np.random.uniform(
  120.         -2.0, 2.0, (count_population, demention_population)
  121.     )
  122.     return zero_population
  123.  
  124.  
  125. def get_psi(g, NP, Lambda):
  126.     psi = ((g) * NP + 1) ** (1 / Lambda)
  127.     return psi
  128.  
  129.  
  130. def select_reference_vertor(data, clear_generation, graph, NP, g):
  131.     reference_vector = None
  132.     array_fitness_value = 0.0
  133.     sum_arr = 0.0
  134.     arr_ver = 0.0
  135.     psi = get_psi(g, NP, POPUL_LENGTH)
  136.     for item in range(len(clear_generation)):
  137.         num = fitness_function(data, clear_generation[item], graph[item])
  138.  
  139.         array_fitness_value = np.append(array_fitness_value, num**psi)
  140.         sum_arr += num**psi
  141.     for i in array_fitness_value:
  142.         arr_ver = np.append(arr_ver, i / sum_arr)
  143.  
  144.     id = np.random.choice(len(arr_ver), p=arr_ver)
  145.     reference_vector = clear_generation[id - 2]
  146.  
  147.     return reference_vector
  148.  
  149.  
  150. def calculate_A(x_min, x_max, x_r, e):
  151.     return np.arctan((x_max - x_r) / e) - np.arctan((x_min - x_r) / e)
  152.  
  153.  
  154. def calculate_e(g, NP, D):
  155.     return 1 / ((g) * (NP) + 1) ** (1 / (2 * D))
  156.  
  157.  
  158. def generate_potential_offspring(x_r, e, A):
  159.     return x_r + e * np.tan((np.random.rand() - 0.5) * A)
  160.  
  161.  
  162. def sofa(zero_population, graph, data_cloud, fitness, mod, steps_number, epsilon):
  163.     # TODO add data_cloud,fitness,mod,epsilon,true_answer
  164.     start_population = np.copy(zero_population)
  165.     mutant_populaion = np.copy(zero_population)
  166.     arr_value_best_item = np.array(
  167.         [fitness_function(data_cloud, zero_population[0], graph[0])]
  168.     )
  169.     value_best_item = np.copy(arr_value_best_item[0])
  170.     print(f"first_value_best: {value_best_item}")
  171.  
  172.     best_item = np.copy(mutant_populaion[0])
  173.     print(f"best_vector1: {best_item}")
  174.     for item in range(steps_number):
  175.         reference_vector = select_reference_vertor(
  176.             data_cloud, start_population, graph, len(start_population), item
  177.         )
  178.         e = calculate_e(item, len(start_population), len(start_population[0]))
  179.         for i in range(len(start_population)):
  180.             for j in range(len(start_population[0])):
  181.                 const_a = calculate_A(-1.0, 1.0, reference_vector[j], e)
  182.                 mutant_populaion[i][j] = reference_vector[j] + np.tan(
  183.                     (np.random.random(2) - 0.5) * const_a
  184.                 )
  185.  
  186.         for i in range(len(start_population)):
  187.             fit_mutant_popul = fitness_function(data, mutant_populaion[i], graph[i])
  188.             fit_start_popul = fitness_function(data, start_population[i], graph[i])
  189.             if fit_mutant_popul > fit_start_popul:
  190.                 start_population[i] = np.copy(mutant_populaion[i])
  191.                 if fit_mutant_popul > value_best_item:
  192.                     value_best_item = fit_mutant_popul
  193.                     print(f"value_best_item {value_best_item}")
  194.                     best_item = np.copy(mutant_populaion[i])
  195.  
  196.         arr_value_best_item = np.append(arr_value_best_item, value_best_item)
  197.  
  198.     print(f"best vector2: {best_item}")
  199.     print(f"global maximum: {value_best_item}")
  200.     index = list(np.arange(1.0, len(arr_value_best_item) + 1, 1))
  201.     return start_population, best_item, value_best_item
  202.  
  203.  
  204. if __name__ == "__main__":
  205.     data = data(GRAPH_LENGTH)
  206.     steps = int(input("steps = "))
  207.     a, graph = get_zero_population_graph(data, GRAPH_LENGTH)
  208.  
  209.     a, item, b = sofa(a, graph, data, None, None, steps, 0.0001)
  210.     visualize_graph(data, item, graph[0])
  211.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement