Как найти все уникальные перестановки множества элементов над графом

Daniel Маршан:

У меня есть проблема материальной науки которую я достаточно уверен, что может быть решена с помощью NetworkX, но я не знаю, как.

Во-первых, я хотел бы, чтобы найти все уникальные комбинации 3-х элементов, с заменой. Это я уже сделал с itertools следующим образом:

elements = ["Mg","Cu","Zn"]
combinations = list(itertools.combinations_with_replacement(elements, 3))

Для каждой из этих комбинаций, я хотел бы найти все уникальные перестановки более простого графа. Граф имеет три узла и три ребра, где каждый узел соединен с двумя другими узлами. Важно отметить, что ребра имеют расстояние 1, но одно из ребер имеют расстояние, равное 2. В принципе, как прямоугольный треугольник.

например, что-то вроде Node1 <-Расстояние = 1-> Node2 <-Расстояние = 2-> node3 <-Расстояние = 1-> Node1

Таким образом, для комбинации [ «Mg», «Си», «Си»] должно быть два уникальных перестановок:

) , Mg (сайт1) -1- Cu (сайт2) -1- Mg (site3) -2- Mg (сайт1)
б ) Mg (сайт1) -1- Mg (сайт2) -1- Cu (site3) -2- Mg (сайт1)
с ) Cu (сайт1) -1- Mg (сайт2) -1- Mg (site3) -2- Cu (сайт1) (Это то же самое , как б )

Примечание: Я не уверен, что лучший способ определить график, это может быть что-то вроде:

import networkx as nx
FG = nx.Graph()
FG.add_weighted_edges_from([(1, 2, 1), (2, 3, 1), (3, 1, 2)])
vurmux:

Уникальность критерии , которые вы хотите использовать, называется изоморфизмом графов . NetworkX имеет подмодуль для него: networkx.algorithms.isomorphism . Вы можете указать , как именно ваши узлы / края графиков следует рассматривать как «равный» с node_match/edge_matchпараметрами. Вот пример:

import networkx as nx

FG1 = nx.Graph()
FG1.add_node(1, element='Cu')
FG1.add_node(2, element='Cu')
FG1.add_node(3, element='Mg')
FG1.add_weighted_edges_from([(1, 2, 1), (2, 3, 1), (3, 1, 2)])

FG2 = nx.Graph()
FG2.add_node(1, element='Cu')
FG2.add_node(2, element='Mg')
FG2.add_node(3, element='Cu')
FG2.add_weighted_edges_from([(1, 3, 1), (2, 3, 1), (1, 2, 2)])

nx.is_isomorphic(
    FG1,
    FG2,
    node_match=lambda n1, n2: n1['element'] == n2['element'],
    edge_match=lambda e1, e2: e1['weight'] == e2['weight']
)

True

Если вы переименовать любой элемент или изменить какой-либо вес края, графики будут неизоморфными (с этими параметрами). Это то, как вы можете найти уникальные графики - множество неизоморфных графов. Замечу, что проблема изоморфизма графов очень вычислительные тяжелый, так что вы не должны использовать его даже для средних графиков.


Но ваша задача имеет столько ограничений, что использование графики не стоит. Если у вас есть только 3 элемента в «молекулы», вы будете иметь только 3 вида комбинаций элементов:

1-1-1

1-1-2

1-2-3

Для каждого из них можно рассчитать и указать количество уникальных комбинаций:

1-1-1: Один - 1=1-1

1-1-2: Два - 1=1-2и1-1=2

1-2-3: Три - 1=2-3, 1-2=3и1-2-3(=1)

Таким образом, вы можете просто умножить каждый itertools-комбинация с числом возможных комбинаций:

number_of_molecular_combinations = 0
for c in combinations:
    number_of_molecular_combinations += len(set(c))
print(number_of_molecular_combinations)

18

Этот метод будет работать гораздо быстрее, чем обработка графа, но может использоваться только в случае очень сильных ограничений, как ваша.

рекомендация

отhttp://10.200.1.11:23101/article/api/json?id=8249&siteId=1
рекомендация