算法是连续背包问题和可变大小的装箱问题的组合

时间:2010-08-22 13:25:02

标签: php algorithm optimization knapsack-problem bin-packing

我正在尝试解决问题(在php中,但编程语言并不重要)。 我有一个 n 已经付钱的人数,而且我有一个 m 的人数将会支付相同的金额。 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美元

1 个答案:

答案 0 :(得分:2)

理论上,这可以被视为优化问题:

基本上我们将建立一组约束来枚举问题的结构,为初始值设定种子,并确保我们按照您的指示分配所有资金。

初始条件限制:

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难,所以这并不意外。