Генерация последовательностей сборки через кластеризацию и оптимизацию
This commit is contained in:
parent
deee7b4329
commit
862a61b1e7
3 changed files with 141 additions and 20 deletions
|
@ -0,0 +1,82 @@
|
||||||
|
import networkx as nx
|
||||||
|
|
||||||
|
|
||||||
|
class GraphProcessor:
|
||||||
|
graph = None
|
||||||
|
|
||||||
|
def __init__(self, adjacency_matrix):
|
||||||
|
self.adjacency_matrix = adjacency_matrix
|
||||||
|
self.graph = self.load_graph_from_data()
|
||||||
|
|
||||||
|
def load_graph_from_data(self):
|
||||||
|
G = nx.Graph()
|
||||||
|
|
||||||
|
for part1, neighbors in self.adjacency_matrix.items():
|
||||||
|
for neighbor in neighbors:
|
||||||
|
G.add_edge(part1, neighbor)
|
||||||
|
|
||||||
|
return G
|
||||||
|
|
||||||
|
|
||||||
|
class EdgeBetweensClustering:
|
||||||
|
def __init__(self, graph):
|
||||||
|
self.graph = graph.copy()
|
||||||
|
self.clusters = []
|
||||||
|
|
||||||
|
def cluster(self):
|
||||||
|
while self.graph.number_of_edges() > 0:
|
||||||
|
edge_betweens = nx.edge_betweenness_centrality(self.graph)
|
||||||
|
max_betweens_edge = max(edge_betweens, key=edge_betweens.get)
|
||||||
|
self.graph.remove_edge(*max_betweens_edge)
|
||||||
|
components = list(nx.connected_components(self.graph))
|
||||||
|
if components not in self.clusters:
|
||||||
|
self.clusters.append(components)
|
||||||
|
return []
|
||||||
|
|
||||||
|
def get_clusters(self):
|
||||||
|
return self.clusters
|
||||||
|
|
||||||
|
|
||||||
|
class ClusterisationSequenceUseCase:
|
||||||
|
def call(self, adjacency_matrix):
|
||||||
|
graph_processor = GraphProcessor(adjacency_matrix)
|
||||||
|
G = graph_processor.load_graph_from_data()
|
||||||
|
ebc = EdgeBetweensClustering(G)
|
||||||
|
ebc.cluster()
|
||||||
|
clusters = ebc.get_clusters()
|
||||||
|
|
||||||
|
for i in range(len(clusters)):
|
||||||
|
for j in range(len(clusters[i])):
|
||||||
|
clusters[i][j] = list(clusters[i][j])
|
||||||
|
|
||||||
|
# Создание списка последовательностей сборки
|
||||||
|
assembly_sequences = []
|
||||||
|
for cluster in clusters:
|
||||||
|
sequence = []
|
||||||
|
for component in cluster:
|
||||||
|
sequence.extend(component)
|
||||||
|
assembly_sequences.append(sequence)
|
||||||
|
|
||||||
|
return assembly_sequences
|
||||||
|
|
||||||
|
|
||||||
|
# # Вызов функции
|
||||||
|
# adjacency_matrix = {
|
||||||
|
# 'body_down': ['sol_gear', 'planet_gear', 'planet_gear003', 'planet_gear004', 'planet_gear005', 'planet_gear002', 'body_up', 'bolt', 'bolt2', 'bolt3', 'bolt4'],
|
||||||
|
# 'sol_gear': ['body_down', 'output_shaft', 'planet_gear', 'planet_gear003', 'planet_gear004', 'planet_gear005', 'planet_gear002'],
|
||||||
|
# 'output_shaft': ['sol_gear', 'planet_gear', 'planet_gear003', 'planet_gear004', 'planet_gear005', 'planet_gear002', 'body_up'],
|
||||||
|
# 'planet_gear': ['body_down', 'sol_gear', 'output_shaft'],
|
||||||
|
# 'planet_gear003': ['body_down', 'sol_gear', 'output_shaft'],
|
||||||
|
# 'planet_gear004': ['body_down', 'sol_gear', 'output_shaft'],
|
||||||
|
# 'planet_gear005': ['body_down', 'sol_gear', 'output_shaft'],
|
||||||
|
# 'planet_gear002': ['body_down', 'sol_gear', 'output_shaft'],
|
||||||
|
# 'body_up': ['body_down', 'output_shaft', 'bolt', 'bolt2', 'bolt3', 'bolt4'],
|
||||||
|
# 'bolt': ['body_down', 'body_up'],
|
||||||
|
# 'bolt2': ['body_down', 'body_up'],
|
||||||
|
# 'bolt3': ['body_down', 'body_up'],
|
||||||
|
# 'bolt4': ['body_down', 'body_up']
|
||||||
|
# }
|
||||||
|
# print(adjacency_matrix)
|
||||||
|
# use_case = ClusterisationSequenceUseCase()
|
||||||
|
# assembly_sequences = use_case.call(adjacency_matrix)
|
||||||
|
# print(assembly_sequences)
|
|
@ -7,6 +7,7 @@ import json
|
||||||
import FreeCAD as App
|
import FreeCAD as App
|
||||||
from geometric_feasibility_predicate.main import main as asm_analysis
|
from geometric_feasibility_predicate.main import main as asm_analysis
|
||||||
from constraints_operator import collect_assembly_settings
|
from constraints_operator import collect_assembly_settings
|
||||||
|
from clusterisation_sequences import ClusterisationSequenceUseCase
|
||||||
|
|
||||||
|
|
||||||
# === Для работы с json-файлами. Работает. ===
|
# === Для работы с json-файлами. Работает. ===
|
||||||
|
@ -94,42 +95,80 @@ def simplify_adjacency_matrix(assembly_settings, adjacency_matrix):
|
||||||
}
|
}
|
||||||
|
|
||||||
for part in adjacency_matrix["allParts"]:
|
for part in adjacency_matrix["allParts"]:
|
||||||
if part not in fasteners:
|
# Добавляем все детали, включая крепеж, в simplified_matrix["allParts"]
|
||||||
simplified_matrix["allParts"].append(part)
|
simplified_matrix["allParts"].append(part)
|
||||||
neighbors = [
|
|
||||||
neighbor for neighbor in adjacency_matrix["matrix"].get(part, [])
|
# Получаем соседей, исключая только крепежные элементы
|
||||||
if neighbor not in fasteners
|
neighbors = [
|
||||||
]
|
neighbor for neighbor in adjacency_matrix["matrix"].get(part, [])
|
||||||
if neighbors or part not in fasteners:
|
if neighbor not in fasteners
|
||||||
simplified_matrix["matrix"][part] = neighbors
|
]
|
||||||
|
|
||||||
|
# Если у части есть соседи, добавляем их в матрицу
|
||||||
|
if neighbors:
|
||||||
|
simplified_matrix["matrix"][part] = neighbors
|
||||||
|
|
||||||
return simplified_matrix
|
return simplified_matrix
|
||||||
|
|
||||||
def restore_full_sequence(assembly_settings, sequence):
|
|
||||||
full_sequence = []
|
|
||||||
sequence_set = set(sequence)
|
|
||||||
|
|
||||||
for item in sequence:
|
def restore_full_sequence(assembly_settings, sequences):
|
||||||
full_sequence.append(item)
|
full_sequences = []
|
||||||
|
|
||||||
|
for sequence in sequences:
|
||||||
|
full_sequence = []
|
||||||
|
sequence_set = set(sequence)
|
||||||
|
|
||||||
|
# Сначала добавляем все детали в полную последовательность
|
||||||
|
for item in sequence:
|
||||||
|
full_sequence.append(item)
|
||||||
|
|
||||||
|
# Теперь добавляем крепежные элементы после элемента с наибольшим порядковым номером
|
||||||
for setting in assembly_settings:
|
for setting in assembly_settings:
|
||||||
if setting.get("Type") == "fastener_set":
|
if setting.get("Type") == "fastener_set":
|
||||||
parent = setting["Parent"]
|
parent = setting["Parent"]
|
||||||
child = setting["Child"]
|
child = setting["Child"]
|
||||||
if parent in sequence_set and child in sequence_set:
|
fasteners = setting["Fasteners"]
|
||||||
full_sequence.append(setting["Fasteners"])
|
|
||||||
|
# Проверяем, если родитель и ребенок в последовательности
|
||||||
|
if (parent in sequence_set) and (child in sequence_set):
|
||||||
|
# Находим индексы родителя и ребенка в полной последовательности
|
||||||
|
parent_index = full_sequence.index(parent)
|
||||||
|
child_index = full_sequence.index(child)
|
||||||
|
|
||||||
|
# Находим максимальный индекс между родителем и ребенком
|
||||||
|
max_index = max(parent_index, child_index)
|
||||||
|
|
||||||
|
# Проверяем, содержатся ли крепежные элементы уже в последовательности
|
||||||
|
if not any(fastener in full_sequence for fastener in fasteners):
|
||||||
|
# Добавляем крепежные элементы после элемента child
|
||||||
|
full_sequence[max_index + 1:max_index + 1] = fasteners
|
||||||
|
|
||||||
|
full_sequences.append(full_sequence)
|
||||||
|
|
||||||
|
return full_sequences
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return full_sequence
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
|
App.open('/home/markvoltov/GitProjects/framework/test_models/test_reductor.FCStd')
|
||||||
if App.ActiveDocument:
|
if App.ActiveDocument:
|
||||||
intersection_geometry, sequences, topologyMatrix = asm_analysis()
|
intersection_geometry, sequences, topologyMatrix = asm_analysis()
|
||||||
print(sequences)
|
|
||||||
assembly_settings = collect_assembly_settings()
|
assembly_settings = collect_assembly_settings()
|
||||||
|
print(assembly_settings)
|
||||||
simplified_matrix = simplify_adjacency_matrix(assembly_settings, topologyMatrix)
|
simplified_matrix = simplify_adjacency_matrix(assembly_settings, topologyMatrix)
|
||||||
|
|
||||||
|
assembly_sequences = ClusterisationSequenceUseCase().call(topologyMatrix['matrix'])
|
||||||
|
# print('Последовательности 1', assembly_sequences)
|
||||||
|
assembly_sequences_simplified= ClusterisationSequenceUseCase().call(simplified_matrix['matrix'])
|
||||||
|
# print('Последовательности 2',assembly_sequences_simplified)
|
||||||
|
assembly_sequences_restored = restore_full_sequence(assembly_settings, assembly_sequences_simplified)
|
||||||
|
print('Последовательности 3',assembly_sequences_restored)
|
||||||
else:
|
else:
|
||||||
print('Ошибка. Нет активного документа!')
|
print('Ошибка. Нет активного документа!')
|
||||||
|
|
||||||
|
|
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue