2016-11-04 4 views
3

これは、要素自体に加えて配列要素のインデックスを返したいthis questionの変更です。 arraysums()arraysums_recursive()を正常に変更しましたが、arraysums_recursive_anyvals()と苦労しています。ここでは詳細は以下のとおりです。任意の数の配列のすべての可能な組み合わせを合計し、制限を適用してインデックスを返す

私はarraysums()を変更:

def arraysums(arrays,lower,upper): 
    products = itertools.product(*arrays) 
    result = list() 

    indices = itertools.product(*[np.arange(len(arr)) for arr in arrays]) 
    index = list() 

    for n,k in zip(products,indices): 
     s = sum(n) 
     if lower <= s <= upper: 
      result.append(n) 
      index.append(k)     
    return result,index 

それは今の要素と要素のインデックスを返します。

N = 8 
a = np.arange(N) 
b = np.arange(N)-N/2  
arraysums((a,b),lower=5,upper=6) 


([(2, 3), 
    (3, 2), 
    (3, 3), 
    (4, 1), 
    (4, 2), 
    (5, 0), 
    (5, 1), 
    (6, -1), 
    (6, 0), 
    (7, -2), 
    (7, -1)], 
[(2, 7), 
    (3, 6), 
    (3, 7), 
    (4, 5), 
    (4, 6), 
    (5, 4), 
    (5, 5), 
    (6, 3), 
    (6, 4), 
    (7, 2), 
    (7, 3)]) 

私もまた返しunutbuの再帰的なソリューション@に変更しますarraysums()と同じ結果:

def arraysums_recursive(arrays, lower, upper): 
    if len(arrays) <= 1: 
     result = [(item,) for item in arrays[0] if lower <= item <= upper] 
     index = [] # this needs to be fixed 
    else: 
     result = [] 
     index = [] 
     for item in arrays[0]: 
      subarrays = [[item2 for item2 in arr if item2 <= upper-item] 
         for arr in arrays[1:]] 
      result.extend(
       [(item,)+tup for tup in arraysums(
        subarrays, lower-item, upper-item)[0]]) 
      index.extend(
       [(item,)+tup for tup in arraysums(
        subarrays, lower-item, upper-item)[1]]) 

    return result,index 

最後に、私はarraysums_recursive_anyvals()を変更し、私はそれがインデックスを返さない理由を理解するように見えることはできません。

def arraysums_recursive_anyvals(arrays, lower, upper): 
    if len(arrays) <= 1: 
     result = [(item,) for item in arrays[0] if lower <= item <= upper] 
     index = [] # this needs to be fixed 
    else: 
     minval = min(item for arr in arrays for item in arr) 
     # Subtract minval from arrays to guarantee all the values are positive 
     arrays = [[item-minval for item in arr] for arr in arrays] 
     # Adjust the lower and upper bounds accordingly 
     lower -= minval*len(arrays) 
     upper -= minval*len(arrays) 

     result = [] 
     index = [] 
     for item in arrays[0]: 
      subarrays = [[item2 for item2 in arr if item2 <= upper-item] 
         for arr in arrays[1:]] 
      if min(len(arr) for arr in subarrays) == 0: 
       continue 
      result.extend(
       [(item,)+tup for tup in arraysums_recursive(
        subarrays, lower-item, upper-item)[0]]) 
      index.extend(
       [(item,)+tup for tup in arraysums_recursive(
        subarrays, lower-item, upper-item)[1]]) 

     # Readjust the result by adding back minval 
     result = [tuple([item+minval for item in tup]) for tup in result] 
    return result,index 

結果:arraysums_recursiveの重要な特徴は、それが値をスローすること

arraysums_recursive_anyvals((a,b),lower=5,upper=6) 

([(2, 3), 
    (3, 2), 
    (3, 3), 
    (4, 1), 
    (4, 2), 
    (5, 0), 
    (5, 1), 
    (6, -1), 
    (6, 0), 
    (7, -2), 
    (7, -1)], 
[]) 

答えて

2

です結果にはあまり寄与しない可能性があります:

subarrays = [[item2 for item2 in arr if item2 <= upper-item] 
       for arr in arrays[1:]] 

インデックスを記録するのが複雑ですが、あまり難しくありません。

def arraysums_recursive(arrays, lower, upper): 
    arrays = [[(i, item) for i, item in enumerate(arr)] for arr in arrays] 
    ... 
    index, result = zip(*arraysums_recursive_all_positive(arrays, lower, upper)) 
    return result, index 

今すぐ(index, item)タプルのリストのリストで構成さarraysを処理するためにarraysums_recursive_all_positiveを書き換える: まず、arraysums_recursiveにインデックスだけでなく、項目の値が含まれるようにarraysを展開します。


def arraysums_recursive(arrays, lower, upper): 
    arrays = [[(i, item) for i, item in enumerate(arr)] for arr in arrays] 
    minval = min(item for arr in arrays for i, item in arr) 
    # Subtract minval from arrays to guarantee all the values are positive 
    arrays = [[(i, item-minval) for i, item in arr] for arr in arrays] 
    # Adjust the lower and upper bounds accordingly 
    lower -= minval*len(arrays) 
    upper -= minval*len(arrays) 
    index, result = zip(*arraysums_recursive_all_positive(arrays, lower, upper)) 
    # Readjust the result by adding back minval 
    result = [tuple([item+minval for item in tup]) for tup in result] 
    return result, index 

def arraysums_recursive_all_positive(arrays, lower, upper): 
    # Assumes all values in arrays are positive 
    if len(arrays) <= 1: 
     result = [((i,), (item,)) for i, item in arrays[0] if lower <= item <= upper] 
    else: 
     result = [] 
     for i, item in arrays[0]: 
      subarrays = [[(i, item2) for i, item2 in arr if item2 <= upper-item] 
         for arr in arrays[1:]] 
      if min(len(arr) for arr in subarrays) == 0: 
       continue 
      result.extend(
       [((i,)+i_tup, (item,)+item_tup) for i_tup, item_tup in 
       arraysums_recursive_all_positive(subarrays, lower-item, upper-item)]) 
    return result 

import numpy as np 
N = 8 
a = np.arange(N) 
b = np.arange(N)-N/2  
result, index = arraysums_recursive((a,b),lower=5,upper=6) 

利回りresult

[(2.0, 3.0), 
(3.0, 2.0), 
(3.0, 3.0), 
(4.0, 1.0), 
(4.0, 2.0), 
(5.0, 0.0), 
(5.0, 1.0), 
(6.0, -1.0), 
(6.0, 0.0), 
(7.0, -2.0), 
(7.0, -1.0)] 

index

((2, 7), 
(3, 6), 
(3, 7), 
(4, 5), 
(4, 6), 
(5, 4), 
(5, 5), 
(6, 3), 
(6, 4), 
(7, 2), 
(7, 3)) 
+0

一つの問題までトリミングされるトンでありますindex_mapsにはわずかなエラー(おそらくいくつかの浮動小数点演算)があるキーが含まれています:[{-17.25:11、-21.579999999999998:6、-7.6100000000000003:16、...}]。これによりKeyErrorがスローされることがあります。 – justin

+0

さて、良い点。その場合、索引の慎重な記録(対応する値とペア)がおそらく最善の方法です。私が意味することを示すコードを修正しました。 – unutbu

関連する問題