输入:给出var app = angular.module('myApp', []);
app.controller('ctrl', function($scope, $http) {
$http.get("data.json")
.success(function (response) {$scope.state = response;})
.error(function (response) {alert("Error")})
});
和items=[1,2,3]
,或者可以在values=[100,300,800]
中。
查找所有组合项,以使总和值小于500
解决方案:
dictionary={1:100,2:300,3:800}
[1]
[2]
必须对数百万个输入执行此操作。
WHat是实现此目标的最好,最快的算法?
答案 0 :(得分:2)
import copy
dictionary = {
100: 1,
200: 2,
800: 3,
}
value = sorted([100, 200, 800])
threshold = 500
res = []
def dfs(l, s, cur):
if s < threshold:
if len(l) > 0:
res.append(l)
else:
return
for i in range(cur + 1, len(value)):
tmp = copy.copy(l)
tmp.append(dictionary.get(value[i]))
dfs(tmp, s+value[i], i)
dfs([], 0, -1)
print res
时间复杂度为O(K)。 K是正确结果的数量。
答案 1 :(得分:0)
在先过滤掉大于限制的值之后,您可以在压缩的项目和值序列上使用itertools.combinations
:
from itertools import combinations
items=[1,2,3]
values=[100,300,800]
def sums_less_than(items, values, limit):
filtered = [(item, value) for item, value in zip(items, values) if value < limit]
return [[item for item, _ in c] for n in range(1, len(filtered) + 1) for c in combinations(filtered, n) if sum(value for _, value in c) < limit]
print(sums_less_than(items, values, 500))
这将输出:
[[1], [2], [1, 2]]
答案 2 :(得分:0)
经过修改:
import copy
dictionary = {
100: 1,
200: 2,
800: 3,
50 : 4,
}
value = sorted(dictionary.keys())
threshold = 500
res = []
thres_val=[]
def dfs(l, s, cur):
if s < threshold:
if len(l) > 0:
res.append(l)
thres_val.append(s)
else:
return
for i in range(cur + 1, len(value)):
tmp = copy.copy(l)
tmp.append(dictionary.get(value[i]))
dfs(tmp, s+value[i], i)
dfs([], 0, -1)
print(res)
print(thres_val)
print("\tItem list-->Value")
j=0
for i in res:
print("\t",i,"-->",thres_val[j])`
答案 3 :(得分:0)
一种更有效的方法是使用广度优先搜索,如果当前项目值加上当前总和已经达到限制,则进一步避免排队,以便在{ {1}}和限制[1, 2, 3, 4, 5]
,如果当前值组合为5
并且当前项目值为[1, 2]
,则由于我们发现3
已经存在不少于1 + 2 + 3
,我们不会排队5
进行进一步搜索。这大大减少了我们需要测试的组合数量:
[1, 2, 3]
这样:
from collections import deque
def sums_less_than(items, values, limit):
seeds = [(index, 0, [], item_value) for index, item_value in enumerate(zip(items, values))]
queue = deque(seeds)
while queue:
index, _sum, combination, (item, value) = queue.popleft()
new_sum = _sum + value
if new_sum < limit:
new_combination = combination + [item]
yield new_combination
for i in range(index + 1, len(seeds)):
queue.append((i, new_sum, new_combination, seeds[i][-1]))
将输出:
items=[1,2,3]
values=[100,300,800]
print(list(sums_less_than(items, values, 500)))