2017-01-25 11 views
0

私はvectors respecting some symmetry groupsをすべてpythonでitertoolsを使用して生成しています。itertoolsは同等の要素を削除します

基本的にすべてはx、y、z軸と符号の並べ替えだけです。等価なベクトルが重複しないようにする最良の方法は何か分かりません。

  1. 0 = -0従って[1, 2, 0]のpermuationsちょうど[[1, 2, 0], [1, -2, 0], [-1, 2, 0], [-1, -2, 0]]
  2. itertools.permutations('AAB' )[('A', 'B', 'A'), ('B', 'A', 'A'), ('A', 'A', 'B')]すなわちequvalentの交換によって、各構成要素を複製しないが生成するはずであるべきである署名A

私の現在のソリューション:

餃子を取り除くにはlst = list(set(lst))のようにsetに渡します。しかし、私はあとでフィルタリングされるゴミをたくさん作りたくありません。また、要素の順序を任意に変更します。また、それは変換を必要とするハッシュ可能な要素(例えば、タプルではなく、リストまたはnumpy配列)を作成するだけで作成できます。

# using itertools.product and set filer 
def signPermut(t): 
    lst = [] 
    n = len(t) 
    for signs in itertools.product([-1,1], repeat=n): 
     p = [ ti*si for ti,si in zip(t,signs) ] 
     lst.append(tuple(p)) 
    #return lst 
    return list(set(lst)) 

この関数はゼロのチェックとサイン置換を行いますが、それはおそらく非常に非効率的である:

def permutSign(t): 
    lst = [ [] ] 
    for c in t: 
     lst_ = [] 
     if c != 0: 
      for p in lst: 
       lst_.append(p+[ c]) 
       lst_.append(p+[-c]) 
     else: 
      for p in lst: 
       lst_.append(p+[c]) 
     lst = lst_ 
    return lst 

それが動作しているが、私はプレハブの何かがあるかもしれないことを考えていた...もっと効率的に、シンプルで記号でリストを作成し、それを超えるitertools.productの使用に関するニシキヘビ

答えて

1

方法:

from itertools import product 

lst = [1, 2, 0] 

signs = [(1, -1) if item != 0 else (1,) for item in lst] 
print(signs) # [(1, -1), (1, -1), (1,)] 

res = [] 
for sign in product(*signs): 
    res.append([s*n for s, n in zip(sign, lst)]) 

print(res) # [[1, 2, 0], [1, -2, 0], [-1, 2, 0], [-1, -2, 0]] 

または一度で:

from itertools import product 

sgn_lst = [(n, -n) if n != 0 else (0,) for n in lst] 
print(sgn_lst) # [(1, -1), (2, -2), (0,)] 

res = [] 
for item in product(*sgn_lst): 
    res.append(item) 

print(res) # [(1, 2, 0), (1, -2, 0), (-1, 2, 0), (-1, -2, 0)] 

このようループ内でやるべきことがたくさんより少ない仕事があります。

2

多分これはPython的もう少しです:

import itertools 

def signProducts(vector): 
    svector = [[x,-x] if x != 0 else [x] for x in vector] 
    return itertools.product(*svector) 

#test: 
v = [1,2,0] 
for w in signProducts(v): print(w) 

出力:

(1, 2, 0) 
(1, -2, 0) 
(-1, 2, 0) 
(-1, -2, 0) 
0

私はあなたがitertools、セットまたはイテレータを使用することについてどのようにスマートに関係なく考える - 最も重要なことはしています例えば、理解しやすい方法でコードを書くそれは、より良いvarsの名前を傷つけ、あなたはベクトルを掛けていること、それは明らかにすることはありません。

import itertools 
import operator 

def genAxes(n): 
    return itertools.product((-1, 1), repeat=n) 

def multiplyVectors(x, y): 
    return itertools.imap(operator.mul, x, y) 

def signPermutation(v): 
    n = len(v) 
    axes = genAxes(n) 
    permut = map(lambda a: tuple(multiplyVectors(v, a)), axes) 
    return list(set(permut)) 

v = [0, 1, 2] 
print signPermutation(v) 

これは、それが簡単に私見を追跡するようにする方法を一例に過ぎません。

関連する問題