2016-09-03 9 views
1

私はPython/numpyの新機能です。私は単純な組み合わせの問題の解決策である数値の配列に値を格納したい。 これには、与えられた2つの値xとyと、x < = boundとy < = boundという境界があります。私はすべての整数解を見つけ出す必要があります。x + b y < =正の整数 "a"と "b"で結ばれています。だから、私は "a"と "b"のすべての実行可能な入力を繰り返して、このソリューションを使って配列を拡張することでこれをやっています。配列にまだ存在しない値でnumpy配列を効率的に拡張する

問題は、解決策が1回しか表示されないことです。下のコード例のように、x = 3、y = 5、bound = 20の場合、解法15は(a、b)=(5,0)のa * 3 + b * 5の結果になります。 (a、b)=(0,3)である。私は冗長は必要ありません。私が今まで考え出した最良の方法は、計算された解がまだ格納されていない場合にifブロックをチェックインし、その場合にのみその値が配列に追加されることです。

これを行うより効率的な方法はありますか?1回の繰り返しステップごとに既存のアレイ全体をチェックすること以外にもありますか?自動的に値を格納するnp.append以外の関数と同じように、すでに存在していないのでしょうか? 計算されたすべての解を最初に保存する方法はありますが、冗長性のない値の配列だけを返しますか?

PS:私は非常に大きな境界で作業しており、配列には数千の値を格納する必要があります。ここで

import numpy as np 


x=3 
y=5 
bound=20 


arr=([]) # empty array at first 

for a in range(np.int(bound/x)+1): 
    for b in range(np.int((bound-a*x)/y)+1): 
     feasible_combination=a*x+b*y 

     if feasible_combination not in arr[:]: # no need for redundance 
      arr=np.append(arr,feasible_combination) 
arr=np.sort(arr) 
print(arr) 
+0

それは速く収集ARですリストの中の線。あるいは、ユニークな値については、 'set'を考慮してください。 – hpaulj

答えて

0

2つのより高速のバージョン、setを使用して1とnumpyの中の他のやってほとんどすべての作業:以下のサンプルについて

def combinations_set(x, y, bound): 
    combs = set() 
    for a in range(np.int(bound/x)+1): 
     for b in range(np.int((bound-a*x)/y)+1): 
      combs.add(a*x+b*y) 
    return np.sort(list(combs)) 

def combinations_ix(x, y, bound): 
    a, b = np.ix_(*[np.arange(int(bound/_)+1) for _ in (x, y)]) 
    combs = a*x + b*y 
    return np.sort(np.unique(combs[combs <= bound])) 

combinations_ixが比較私のマシン上で1607倍の高速化を提供します元のコードが、combinations_setにかなり競争力がある(とcombinations_ixより少ないメモリを使用する必要があります):

In [58]: %timeit combinations(200, 234, 100000) # original code as function 
1 loops, best of 3: 8.23 s per loop 

In [59]: %timeit combinations_set(200, 234, 100000) 
100 loops, best of 3: 16.1 ms per loop 

In [60]: %timeit combinations_ix(200, 234, 100000) 
100 loops, best of 3: 5.12 ms per loop 
関連する問題