0

場所と数量は辞書で管理されているので、場所の在庫を見つけるロジックを書いたのですが、

d={'loc2': 500.0, 'loc3': 200.0, 'loc1': 1000.0, 'loc4': 100.0, 'loc5': 50.0}

def find_combination(locations,qty): 
    new_list = sorted(locations.items(),key=lambda y: y[1],reverse=True)
    result = []
    while qty > 0:
        min_item = ''
        for item in new_list:
            if item[0] in result: 
                continue
            new_diff = abs(qty - item[1])
            if not min_item or new_diff <= min_diff:
                min_item = item[0]
                min_diff = new_diff
                min_val = item[1]
        result.append((min_item ,locations.get(min_item)))
        qty = qty - min_val
    return result

数量が口述の最大数量を下回ると、予期しない結果が生じます。

print find_combination(d,500)
OUTPUT: [('loc2', 500.0)]
print find_combination(d,1000)
OUTPUT: [('loc1', 1000.0)]
print find_combination(d,750)
OUTPUT: [('loc2', 500.0), ('loc3', 200.0), ('loc5', 50.0)]
print find_combination(d,1800)
OUTPUT: [('loc1', 1000.0), ('loc1', 1000.0)] # unexpected
4

3 に答える 3

2

その出力が予期しない理由を説明できますか? に1 つのloc1アイテムが追加されるresultと、 の値はqtyになります800。この行は、次の反復で再びnew_diff = abs(qty - item[1])項目の最小値 (200) を返すため、その項目がもう一度追加されます。それが完了すると、になるので、ループは終了します。関連する数量が変数よりも小さい場合にのみアイテムを追加する必要がありますか? その場合、それを行うにはさらにロジックが必要です。for ループを次のように変更できます。loc1resultqty-200whileqty

for item in [x for x in new_list if x[1] <= qty]:
于 2013-06-18T09:06:02.193 に答える
1

次のコードはあなたが望むことをしますか? 残りの数量を追跡するために整数除算を使用しました。


def find_combination(locations,qty): 
    new_list = sorted(locations.items(),key=lambda y: y[1],reverse=True)
    result = []
    for item in new_list:
        quotient = int(qty / item[1])
        result.extend(quotient*[item])
        qty -= quotient*item[1]
    return result

編集: check を使用したのでif item[0] not in result、結果でアイテムを繰り返したくないと仮定しています。その場合、HennyH の回答は問題なく機能します。この答えはうまくいきません。ただし、繰り返しが許可されている場合は、これが機能します。

于 2013-06-18T09:41:27.930 に答える