グラフの上に要素のセットのすべてのユニークな順列を見つける方法

ダニエル・マルシャン:

私は合理的に確信しているnetworkxを使用して解決することができる材料科学の問題を抱えているが、私は方法がわからないんだけど。

まず私は、交換して、3つの要素のすべてのユニークな組み合わせを見つけるしたいと思います。この次のように私はすでにitertoolsで行っています:

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

これらの組み合わせのそれぞれについて、私は簡単なグラフの上にすべてのユニークな順列を見つけるしたいと思います。グラフは、3つのノードと、各ノードは他の2つのノードに接続されている3つのエッジを有しています。重要なことには、エッジは1の距離を有するが、縁の一方は、直角三角形のように、基本的に2の距離を有しています。

ノード1のような例えば何か<-Distance = 1->ノード2 <-Distance = 2 - >ノード3 <-Distance = 1->ノード1

だから、組み合わせ[「マグネシウム」、「銅」、「銅」]のために2個の固有の順列があるはずです。

A)のMg(SITE1)-1-のCu(SITE2)-1-のMg(site3)-2-たMg(SITE1)
B)のMg(SITE1)-1-のMg(SITE2)-1-のCu(site3)-2- MG(SITE1)
C)のCu(SITE1)-1- MG(SITE2)-1- MG(site3)-2-銅(SITE1)(これは同じであり、B

注:私は確信してグラフを定義するための最良の方法のないんだけど、それはのようなものが考えられます。

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-1-2:二- 1=1-21-1=2

1-2-3:三- 1=2-31-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=8251&siteId=1