php – 连续背包问题和可变大小bin包装问题的组合算法
作者:互联网
我正在尝试解决一个问题(在PHP中,但编程语言并不重要).
我有很多人付钱,我有很多人要支付的金额与n人支付的金额相同.
我想计算这些人之间最短的汇款路线.可以将付款分开并支付给不同的人.
理想的是一个人只进行一两次交易.
有人可能会指出我正确的方向或帮助我吗?
一个例子:
A人已支付100美元
B人支付了200美元
C人已支付50美元
D人将支付24美元
E人将支付175美元
F先生将支付151美元
一个可能的解决方案是
E人向A人支付100美元,
人E向B人支付75美元,
F先生向B人支付125美元,
F先生向C人支付26美元
D人向C支付24美元
解决方法:
从理论上讲,这可以被视为一个优化问题:
基本上我们将建立一组约束来枚举问题的结构,为初始值设定种子,并确保我们按照您的指示分配所有资金.
初始条件限制:
A_paid = 100
B_paid = 200
C_paid = 50
D_out = 24
E_out = 175
F_out = 151
支付金额不能超过可用金额:(我们将D_to_A定义为一个变量,其中包含从人D支付给A人的金额)
D_out >= D_to_A + D_to_B + D_to_C
E_out >= E_to_A + E_to_B + E_to_C
F_out >= F_to_A + F_to_B + F_to_C
支付给每个人的金额必须等于他们已经支付的金额:
A_paid = D_to_A + E_to_A + F_to_A
B_paid = D_to_B + E_to_B + F_to_B
C_paid = D_to_C + E_to_C + F_to_C
如果我们现在停下来并将其解决为线性程序,我们会发现任何解决方案都跨越整个可变空间,但您希望尽量减少实际付款的数量.我们可以通过最小化与上述约束一致的所有X_to_Y变量来实现此目的.
min: D_to_A + D_to_B + D_to_C + ...
您可以使用自己喜欢的优化技术来解决问题,有很多可用的线性程序求解器,我喜欢lpsolve.
虽然这解决了您描述的具体示例,但通过添加更多变量可以很容易地看到它如何扩展到更大的问题……但是当您添加人员时,问题的复杂程度会大大增加.如果我没记错,背包问题是NP或NP难,所以这并不意外.
标签:php,optimization,algorithm,knapsack-problem,bin-packing 来源: https://codeday.me/bug/20190705/1383793.html