以下是原始记录:
出 | 在 | 金额 |
---|---|---|
A | B | 10 |
B | C | 6 |
C | A | 7 |
而且我想尽量减少它们之间的转移金额。我想得到的结果是:
出 | 在 | 金额 |
---|---|---|
A | B | 4 |
C | A | 1 |
有人可以告诉我如何实现这一目标吗?
目的只是尽量减少总量和步骤。可以看到,第一个表的总数为23,步数为3,而第二个表只需要2个步,总步数为5。
答案 0 :(得分:1)
从我之前的评论中充实了答案:
我们可以计算每个账户的净损益。请注意,这是计算最佳最终结果所需的唯一信息:只要每个人在一天结束时都有正确的净收益和损失,您就会达到预期的结果。
然后,我们可以将这个问题表述为二部图上的流问题。如果有 n
个净正账户和 m
个净负账户,我们可以创建一个完整的二分流图,其中包含 m
个源和 n
个接收器,每个接收器的容量相等到他们想要的净流量,然后问一个问题:为了达到最大流量,必须有多少条边流过它们?
这似乎是 this question on Theoretical Computer Science Stack Exchange 所要问的,看起来答案是问题是“NP Hard”,这大致意味着你不能比蛮力做得更好。
如果您处理的数字非常小,您还可以寻找伪多项式时间(这意味着它在 AMOUNTS 的大小方面是有效的(在您的示例中,金额为 6,7,1)只是问题的大小(在您的示例中,问题的大小是 3 个帐户))算法,如背包算法。
您发布的评论显示为 a greedy algorithm。贪心算法失败,例如如果值是
1 5
5 5
5 5
5 5
5 5
5 100
99
最理想的是,每个源帐户只需要进行 1 次交易。然而,贪心算法会为每个源账户产生大约 2 笔交易。一般来说,贪心算法可以产生大约两倍于最优的交易。
但在最坏的情况下,它会产生类似 n
的交易,其中 n
是帐户总数。 (证明:在图中永远不会有表示最终交易的循环,因此最大边数必须为 n-1
。)这仍然比根本不进行优化(可以有 {{ 1}} 笔交易)。