以下是原始记录:
out | in | 金额|
---|---|---|
A | B | <10>|
B | C | 6 |
C | A | 7 |
从我之前的评论中得到了清晰的答案:
我们可以计算每个账户的净收益或净损失。请注意,这是计算最佳最终结果所需的唯一信息:只要每个人在一天结束时都有正确的净损益,你就会达到你想要的结果。
然后,我们可以把这个问题表述为二分图上的流问题。如果有n
净正账户和m
净负账户,我们可以创建一个完整的具有m
源和n
汇的二分流图,每个源和汇的容量都等于它们所需的净流量,并问一个问题:为了实现最大流量,必须有多少边流过它们?
这似乎就是理论计算机科学堆栈交换上的这个问题所问的,看起来答案是问题是";NP Hard";,这大致意味着你不能比暴力做得更好。
如果你处理的数字很小,你也可以寻找一个伪多项式时间(这意味着它在AMOUNTS的大小方面是有效的(在你的例子中,数量是6,7,1(,而不仅仅是问题的大小(在你例子中,问题的大小是3个账户(算法,比如背包算法。
贪婪
你发布的评论显示了一个贪婪的算法。贪婪算法失败,例如,如果值是
1 5
5 5
5 5
5 5
5 5
5 100
99
最理想的情况是,每个源帐户只需要1笔交易。然而,贪婪算法将为每个源帐户产生大约2笔交易。一般来说,贪婪算法可以产生大约两倍于最优的事务。
但在最坏的情况下,它会产生类似n
的事务,其中n
是帐户总数。(证明:在表示最终事务的图中永远不会有一个循环,因此最大边数必须是n-1
。(与完全不进行优化(可以有O(n^2)
事务(相比,这仍然是一个很大的改进。