vatman

бмо графы0.1

Nov 24th, 2023
697
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.39 KB | None | 0 0
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. from mpl_toolkits.mplot3d import Axes3D
  4. import networkx as nx
  5. from scipy.spatial import distance
  6. from scipy.spatial import distance_matrix
  7. import itertools
  8. vertex_k = 0.5 # Замените на ваше значение для коэффициента аппроксимации вершин
  9. edge_k =0.5  # Замените на ваше значение для коэффициента растяжения ребер
  10. wedge_k = 10 # Замените на ваше значение для коэффициента изгиба клиньев
  11. np.random.seed(8)  
  12. vectors = [np.random.randint(-6, 7, 3) for _ in range(100)]
  13.  
  14. # Выбираем три случайные точки (вектора)
  15. indices = np.random.choice(len(vectors),5, replace=False)
  16. selected_vectors = [vectors[i] for i in indices]
  17. print(indices)
  18. # Вычисляем матрицу расстояний между всеми векторами
  19. distances = distance_matrix(selected_vectors, selected_vectors)
  20.  
  21. # Заменяем диагональные элементы на бесконечность
  22. np.fill_diagonal(distances, np.inf)
  23.  
  24. # Создаем граф
  25. G = nx.Graph()
  26.  
  27. #Добавляем вершины в граф
  28. for i in range(len(selected_vectors)):
  29.     G.add_node(i)
  30.  
  31. # Выводим координаты всех вершин графа
  32. for node in G.nodes:
  33.     print(f"Вершина {node+1}: {selected_vectors[node]}")
  34.    
  35. # Добавляем ребра в граф, соединяя каждую вершину с ее ближайшей вершиной
  36. for i in range(len(selected_vectors)-1):
  37.     # Находим ближайшую вершину к текущей вершине
  38.     nearest_vertex = np.argmin(distances[i])
  39.     print(i,nearest_vertex)
  40.     # Добавляем ребро между текущей вершиной и ее ближайшей вершиной
  41.     G.add_edge(i, nearest_vertex)  
  42.  
  43.    
  44. # Расчет энергии вершины
  45. def calculate_vertex_energy(vertex, vectors, k):
  46.     energy = 0
  47.     for vector in vectors:
  48.         energy += np.linalg.norm(vertex - vector)**2
  49.     return k * energy
  50.  
  51. # Расчет энергии ребра
  52. def calculate_edge_energy(edge, vectors, k):
  53.     v1, v2 = vectors[edge[0]], vectors[edge[1]]
  54.     return k * np.linalg.norm(v1 - v2)**2
  55.  
  56. # Расчет энергии клина
  57. def calculate_wedge_energy(wedge, vectors, k):
  58.     v1, v2, v3 = vectors[wedge[0]], vectors[wedge[1]], vectors[wedge[2]]
  59.     return k * np.linalg.norm(v1 + v3 - 2*v2)**2
  60.  
  61. # Расчет энергии графа
  62. def calculate_energy(graph, vectors):
  63.     #vertex_k = 0.5 # Замените на ваше значение для коэффициента аппроксимации вершин
  64.     #edge_k = 0.5 # Замените на ваше значение для коэффициента растяжения ребер
  65.     #wedge_k = 0.5 # Замените на ваше значение для коэффициента изгиба клиньев
  66.    
  67.     energy = 0
  68.     for node in graph.nodes:
  69.         energy += calculate_vertex_energy(vectors[int(node)], vectors, vertex_k)
  70.     for edge in graph.edges:
  71.         energy += calculate_edge_energy(edge, vectors, edge_k)
  72.        
  73.     # Добавляем энергию клина для всех подграфов из трех вершин
  74.     for nodes in itertools.combinations(graph.nodes, 3):
  75.         if graph.has_edge(nodes[0], nodes[1]) and graph.has_edge(nodes[0], nodes[2]) and not graph.has_edge(nodes[1], nodes[2]):
  76.             p1 = calculate_wedge_energy(nodes, vectors, wedge_k)
  77.             print("Энергия клина:")
  78.             print(p1)
  79.             energy += p1
  80.         elif graph.has_edge(nodes[0], nodes[1]) and not graph.has_edge(nodes[0], nodes[2]) and graph.has_edge(nodes[1], nodes[2]):
  81.             p1 = calculate_wedge_energy(nodes, vectors, wedge_k)
  82.             print("Энергия клина:")
  83.             print(p1)
  84.             energy += p1
  85.         elif graph.has_edge(nodes[0], nodes[2]) and not graph.has_edge(nodes[0], nodes[1])  and graph.has_edge(nodes[1], nodes[2]):
  86.             p1 = calculate_wedge_energy(nodes, vectors, wedge_k)
  87.             print("Энергия клина:")
  88.             print(p1)
  89.             energy += p1    
  90.            
  91.        
  92.     return energy
  93.  
  94. energy = calculate_energy(G, selected_vectors)
  95. print(f'Энергия графа: {energy}')
  96.    
  97.    
  98. # Визуализация проекции графа и векторов
  99. fig = plt.figure()
  100. ax = fig.add_subplot(111, projection='3d')
  101.  
  102. # Отображаем все векторы на графике
  103. for vector in vectors:
  104.     ax.scatter(vector[0], vector[1], vector[2], color='b')
  105.  
  106. # Отображаем выбранные векторы на графике
  107. for vector in selected_vectors:
  108.     ax.scatter(vector[0], vector[1], vector[2], color='r')
  109.  
  110. # Добавляем ребра между вершинами
  111. for edge in G.edges:    
  112.     ax.plot([selected_vectors[edge[0]][0], selected_vectors[edge[1]][0]],
  113.             [selected_vectors[edge[0]][1], selected_vectors[edge[1]][1]],
  114.             [selected_vectors[edge[0]][2], selected_vectors[edge[1]][2]], 'r-')
  115. for edges in G.edges:
  116.     print(edges)
  117.    
  118. # Добавляем оси
  119. ax.set_xlabel('X')
  120. ax.set_ylabel('Y')
  121. ax.set_zlabel('Z')
  122. plt.show()
Advertisement
Add Comment
Please, Sign In to add comment