集体支付账单问题


23

一张桌子有个人。第个人必须支付美元。p nipi

有些人没有正确的账单来支付,因此他们提出了以下算法。pi

首先,每个人都把一些钱放在桌子上。然后,每个人都收回他们多付的钱。

钞票有固定的面额集(不是输入的一部分)。

一个例子:假设有两个人,爱丽丝和鲍勃。爱丽丝欠5 美元,有5张1 美元的钞票。鲍勃欠2 美元,有一张5 美元的钞票。爱丽丝和鲍勃把所有的钱都放在桌子上之后,鲍勃收回 3 美元,每个人都很高兴。

当然,有时候人们不必把所有的钱都放在桌子上。例如,如果爱丽丝有上千元的1 美元钞票,那么她就不必将它们全部放到桌子上,然后再将其中的大部分拿回来。

我想找到一种具有以下属性的算法:

  1. 输入指定人数,每个人欠多少钱以及每个人拥有多少种面额的钞票。

  2. 该算法告诉每个人第一轮要把哪些钞票放在桌子上。

  3. 该算法告诉每个人第二轮要从表中删除哪些账单。

  4. 放在桌子上的钞票数+从桌子上取出的钞票数被最小化。

如果没有可行的解决方案,该算法将返回错误。


9
钞票的面额是预先确定的(例如,对美国的面额为$ 1,$ 2,$ 5,$ 10,$ 20,$ 50和$ 100)还是输入的一部分?换句话说,它的算法必须处理梅菲斯特有可能3 $ 7票,一个$ 13法案和15对$ 4对账单
JeffE

1
账单是固定的。我想在那种情况下我无法减少子集和并证明它是NP-Hard。我将对其进行编辑。
赵超

1
您需要一种将4/5表示为单个优化的方法。无法针对这两个独立条件进行优化。我知道您的打算,我之前也遇到过类似的问题,但是您需要准确地量化针对两种情况进行优化的含义。
edA-qa mort-ora-y

3
作为起点,我认为最好是假设每个人都准确地支付了账单,或者算法仅报告失败。
JeffE

2
这里到底是什么问题,是否有复杂性要求?编写朴素的算法似乎微不足道,还是我错过了一些东西?
斯特凡希门尼斯

Answers:


6

如果以稍微不同(但等效)的方式重述该问题,则算法将变得更加明显:

有参与方:个人和一个餐厅。令为在饭食完结并支付应该拥有的金额。例如,如果爱丽丝(Alice)有36 美元并欠25 美元,鲍勃(Bob)有12 美元并欠11 美元,卡尔(Carl)有30 美元并欠25 美元,我们说是餐厅,并且有:nn1piip0

p=(61,11,1,5)

就是说,当饭食​​在餐厅时应 61 美元,爱丽丝应 11 美元,鲍勃应 1 美元,卡尔应 5 美元

现在,让列举所有涉及的账单。例如:bm

b=(1,5,10,20,1,1,5,5,10,20)

钞票的面额无关紧要,但是在此示例中,我选择了纸币的美元面额,因为它们很熟悉。

我们正在设法减少易手票据的数量,因此我们使用矩阵将“成本”与离开票据的人相关联。该矩阵中的0项指示每个方以哪个帐单开头(对于所有,因为餐厅以无帐单开头)。ij{0,1}CC0,j=0j

继续我们的示例:

C=[0000000000000011111111110000111111111100]

表示Alice以$ 1,$ 5,$ 10,$ 20开始,Bob以$ 1,$ 1,$ 5,$ 5开始,而Carl以$ 10和$ 20开始。

同样,目标是最大程度地减少易手的票据数量。换一种说法:

Minimize:i=0n1j=0m1Ci,jxi,jsubject to:i=0n1xi,j=1 for 0j<m,j=0m1xi,jbj=pi for 0i<n,andxi,j0

第一个约束条件是该解决方案只能将特定的账单分配给一方,第二个约束条件可以确保每个人都支付适当的金额。

这是0,1整数编程问题,并且是NP完全的(请参阅[ Karp 1972 ])。有关线性编程的Wikipedia页面包含有关可用于这些类型问题的不同算法的信息。

可能有多个最佳解决方案。手工解决这个例子的第一个方法是:

x=[0101100111101000000000001000000000001000]

这意味着爱丽丝恰好支付$ 5和$ 20中,鲍勃恰好支付$ 1 $ 5和$ 5,和卡尔支付高价$ 10和$ 20,然后删除一个$从表5。

我还使用了Sage Math系统的Mixed Integer Linear Program模块,该模块具有使用不同求解器后端(GLPKCOINCPLEXGurobi)的能力。它给出的第一个解决方案是

x=[0101010111101000000000001000000000000100]

这几乎是一样的,除了卡尔拿走了鲍勃在桌上的“其他” 5美元。

以这种方式解决问题可以满足您列出的所有属性(您可以从和解决方案矩阵推断出哪些票据最终会出现在哪里)。也许是#4例外,该问题的评论中对此进行了讨论。我不清楚在线性方程组没有可行解的情况下您要做什么:XCx

确定可以支付减少的总额的一部分人?也许还有一部分人仍然可以支付全部账单,即他们为朋友付款。

您的最终声明使您似乎对票据面额固定的情况感兴趣,但这并不会改变问题。

无论如何,还有一种解决方案,其中每个人都使用信用卡付款。O(1)


这个问题可以用IP表示(几乎?)。但是这个解决方案有多好?创建表格的IP是否可以有效解决?如果没有,是否有更快的算法?
拉斐尔

该IP存在一种更简化的形式,即具有特定面额的票据数量的变量而不是0.1变量。固定面额确实会稍微改变复杂度,如果人数也固定,Lenstra的算法可以在多项式时间内求解。
赵超

-2

当然,一些基本的开始可能是要包括可用于达到总账单总额的最小账单。如果您不愿意允许2 美元的钞票,那么每个人都可以简单地从泳池中取出最大的钞票,然后相对较快地到达那里。在$ 2法案抛出掉,因为它没有进行细分,很好地在其他教派和大大的问题复杂化。当然,还可以进行很多其他优化,以观察是否需要在第一轮中添加更多资金(例如,如果1 美元面额的纸币的总金额足以支付该金额,那么每个人可以停止投入,除非他们尚未投入足够的账单)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.