这个问题需要一些解释。
项目的示例表
表:
items(id,size,score,value)
group(grpid,tsize,tscore,tvalue)
示例内容
items(1,2000,3000,4000)
,(2,4000,5000,8000)
,(3,8000,3000,1000)
,(4,12000,1000,400)
groups(1,14000,11000,13000) -> matches item 1,2,3 combined
想象一下,items表有数百到1000条记录,通常有10组3项
后续问题:4个,5个甚至10个大小的小组怎么样。
找到可能的组的最有效方法是什么(理论上,搜索可以找到多于一组与3组相匹配的组合)?
答案 0 :(得分:0)
一个解决方案可能看起来像这样......
SELECT x.size+y.size+z.size size
, x.score+y.score+z.score score
, x.value+y.value+z.value value
FROM items x
JOIN items y
ON y.id < x.id
JOIN items z
ON z.id < y.id
HAVING size = 14
AND score = 11
AND value = 13;
此解决方案需要与群组成员一样多的JOIN ...但是,我并不认为这么好。
答案 1 :(得分:0)
欢迎来到不幸的人:你遇到了subset sum problem,它是NP完全的,因此一般不能在多项式时间内解决。您(或多或少)将您的问题限制为大小为k=3
的组,这样可以稍微简化一下。然而,你有k * number_of_items
种可能性,这是非常多的。由于您没有指定进一步的信息,我认为必须尝试所有可能的组合。
实际上,我没有看到解决问题的简单解决方案。当然你可以尝试三次加入桌子。
这将返回可能的组:
SELECT a.id AS a_id, b.id AS b_id, c.id AS c_id,
(a.score + b.score + c.score) AS score_sum,
(a.value + b.value + c.value) AS value_sum,
(a.size + b.size + c.size) AS size_sum
FROM items a
INNER JOIN items b ON b.id < a.id
INNER JOIN items c ON c.id < b.id
可以理清代表等效解决方案的三元组,但只能在a,b和c之间进行排列。这可以通过将id约束为低于当前值来实现。
然后您必须将其与可用组进行比较:
SELECT a_id, b_id, c_id, groups.id
FROM
(SELECT a.id AS a_id, b.id AS b_id, c.id AS c_id,
(a.score + b.score + c.score) AS score_sum,
(a.value + b.value + c.value) AS value_sum,
(a.size + b.size + c.size) AS size_sum
FROM items a
INNER JOIN items b ON b.id < a.id
INNER JOIN items c ON c.id < b.id
) a
INNER JOIN groups ON a.score_sum = groups.score
AND a.value_sum = groups.value
AND a.size_sum = groups.size
虽然我不希望这个跑得快。只有利用您的特定问题才能加快速度。
您可能会重新考虑是否有其他信息可以帮助解决您的特定问题,或者尝试修改您的基础数据。