我正在建立一个匹配交易的程序。以下是我目前面临的问题的描述。我需要一些算法帮助。
鉴于两组交易A和B具有相似的属性(交易日期,账户,符号),我需要找到A中的交易子集a和B中的交易子集,其中sum(a)最接近sum(b)。这里sum()是该子集的特定属性(净钱)的总和。需要最接近匹配的原因是,如果我们没有得到完美匹配(理想情况),我们希望下一个最接近。注意:总和(a)可以大于或小于总和(b)。
我显然希望在不使用蛮力方法生成A和B的所有组合并进行比较的情况下这样做。
我觉得这可以通过一些动态编程方法来完成,但我无法想出任何具体的东西。非常感谢任何帮助。
答案 0 :(得分:4)
这个问题是NP难的。
证明是子集和的减少,已知是NP难的。给定子集和的任何实例,其中我们给出了要求总和的元素集S和一些目标数k,我们可以通过让A成为集合S并让B成为单子集{k}来构造问题的实例。 。如果我们解决你的问题并发现最接近的匹配并不完全是k,那么我们就知道没有办法总结S的子集来获得k。否则,如果有一种方法可以将S的元素总结为k,那么匹配将完全等于k,我们知道某个子集确实会累加到目标。
因为这个问题是NP难的,所以你不应该期望一个在多项式时间内运行的解决方案或者比蛮力更好的解决方案。我认为你需要稍微放松一下这个问题才能取得好成绩。
答案 1 :(得分:0)
哎呀,这听起来像subset-sum类固醇。了解你的问题规模(A和B的元素数量)会很好。问题肯定是NP难的,所以你可能无法使用如下所示的精确解决方案。
一个简单的DP解决方案是针对每个可能的总和值分别解决A和B的子集和。因此,如果每个集合最多有10个元素可以在0到50之间,那么,对于A和B,使用DP来回答问题“是否存在与X相加的子集”,对于X在0到500之间。然后只需通过这两组,看看它们有哪些共同的值,或者找到A中某些可能总和到B中可能总和的最小距离。
(注意:我说'简单',而不是'有效'!但是由于NP硬度等原因,没有比大O更快的解决方案。)
答案 2 :(得分:0)
因此对于强力算法,我们构建A和B的超集,并构建它们的所有组合,求和它们,构建求和的绝对值并找到最小值?
sa = superset (A) // () (a) (e) (i) (a, e), (a, i) (e, i) (a, e, i)
sb = superset (B)
sas = supersetAsums // 0, a, e, i, a+e, a+i, e+i, a+e+i
sbs = supersetAsums
ssas = sorted (sas)
ssbs = sorted (sbs)
现在你可以迭代这两个列表,如果ssas(i)< ssbs(j)你递增j,否则递增i,看看abs(diff)是否小于当前min(abs(diff))。
这里的问题是子集的构建,对于大多数已知的N样本来说,这些子集的速度非常快。:)