Advertisement
vatman

Untitled

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