Advertisement
vatman

Untitled

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