我写了一个逻辑来查找位置的可用数量, 用字典管理位置和数量:
d={'loc2': 500.0, 'loc3': 200.0, 'loc1': 1000.0, 'loc4': 100.0, 'loc5': 50.0}
from operator import itemgetter
def find_combination(locs,qty):
locs = sorted(locs.items(),key=itemgetter(1),reverse=True)
result = []
for loc,val in locs:
if qty <= 0:
break
elif qty - val >= 0:
qty -= val
result.append((loc,val))
return result
现在当数量低于dict中的最大数量时,它会给出这些意想不到的结果:
print find_combination(d,1000)
[('loc1', 1000.0)]
print find_combination(d,750)
[('loc2', 500.0), ('loc3', 200.0), ('loc5', 50.0)]
print find_combination(d,1900)
[('loc1', 1000.0), ('loc2', 500.0), ('loc3', 200.0), ('loc4', 100.0), ('loc5', 50.0)]
print find_combination(d,150)
[('loc4', 100.0), ('loc5', 50.0)]
print find_combination(d,34)
[] # unexpected # should be [('loc5', 50.0)]
print find_combination(d,88)
[('loc5', 50.0)] # should be [('loc4', 100.0)]
答案 0 :(得分:2)
我不确定你的算法是否是你需要的算法。如果想要从不同的位置获得一定的数量,那么你的算法将找不到最佳组合,只是一个好的组合。
您的问题可以被视为0-1 knapsack problem,可以使用Dynamic Programming
在伪多项式时间内解决答案 1 :(得分:1)
您只需使用dictionray键创建一个存储所有可能组合的字典,这将给出:
d={'loc2': 500.0, 'loc3': 200.0, 'loc1': 1000.0, 'loc4': 100.0, 'loc5': 50.0}
from itertools import combinations
comb = {}
for i in range(1,len(d)):
[comb.__setitem__(sum(j),k) for k,j in zip(combinations(d.keys() ,i),
combinations(d.values(),i))]
comb
字典如下:
{50.0: ('loc5',),
100.0: ('loc4',),
150.0: ('loc4', 'loc5'),
200.0: ('loc3',),
250.0: ('loc3', 'loc5'),
300.0: ('loc3', 'loc4'),
350.0: ('loc3', 'loc4', 'loc5'),
500.0: ('loc2',),
550.0: ('loc2', 'loc5'),
600.0: ('loc2', 'loc4'),
650.0: ('loc2', 'loc4', 'loc5'),
700.0: ('loc2', 'loc3'),
750.0: ('loc2', 'loc3', 'loc5'),
800.0: ('loc2', 'loc3', 'loc4'),
850.0: ('loc2', 'loc3', 'loc4', 'loc5'),
1000.0: ('loc1',),
1050.0: ('loc1', 'loc5'),
1100.0: ('loc1', 'loc4'),
1150.0: ('loc1', 'loc4', 'loc5'),
1200.0: ('loc3', 'loc1'),
1250.0: ('loc3', 'loc1', 'loc5'),
1300.0: ('loc3', 'loc1', 'loc4'),
1350.0: ('loc3', 'loc1', 'loc4', 'loc5'),
1500.0: ('loc2', 'loc1'),
1550.0: ('loc2', 'loc1', 'loc5'),
1600.0: ('loc2', 'loc1', 'loc4'),
1650.0: ('loc2', 'loc1', 'loc4', 'loc5'),
1700.0: ('loc2', 'loc3', 'loc1'),
1750.0: ('loc2', 'loc3', 'loc1', 'loc5'),
1800.0: ('loc2', 'loc3', 'loc1', 'loc4')}
然后,如果给定的组合存在,您可以构建一个chekc函数:
find_combination = lambda num: comb.get(num, 'NOT A VALID COMBINATION')
示例:
find_combination(1750)
#('loc2', 'loc3', 'loc1', 'loc5')
find_combination(1):
#'NOT A VALID COMBINATION'
编辑:如果你的字典太大,最好根据迭代器使用这个函数:
def find_combination(d, num):
from itertools import combinations,izip
t = ((sum(j),k) for i in range(1,len(d)) \
for j,k in izip(combinations(d.values(),i),
combinations(d.keys() ,i)))
for comb,k in t:
if comb==num: return k
答案 2 :(得分:0)
这是一个意想不到的结果?
当qty = 34
和val = 50
,qty - val >= 0
评估为假时。
与qty = 88
和val = 100
你的程序结果对我来说听起来不错:)
旁注:
def find_combination(locs,qty):
locs = sorted(d.items(),key=itemgetter(1),reverse=True)
但我想你的意思是locs = sorted(locs.items(), ...