Paga collettivamente il problema del conto


23

Ci sono persone a un tavolo. Il ° persona deve pagare dollari.nipi

Alcune persone non hanno le fatture giuste per pagare esattamente , quindi escono con il seguente algoritmo.pi

Innanzitutto, tutti mettono un po 'dei loro soldi sul tavolo. Quindi ogni individuo riprende i soldi che ha pagato in eccesso.

Le fatture hanno un insieme fisso di tagli (non parte dell'input).

Un esempio: supponiamo che ci siano due persone, Alice e Bob. Alice deve $ 5 e ha cinque $ 1 di fatture. Bob deve $ 2 e ha una fattura di $ 5. Dopo che Alice e Bob hanno messo tutti i loro soldi sul tavolo, Bob riprende $ 3 e tutti sono felici.

Certo, ci sono momenti in cui uno non deve mettere tutti i suoi soldi sul tavolo. Ad esempio, se Alice avesse un migliaio di banconote da $ 1, non è necessario per lei metterle tutte sul tavolo e poi riprenderle.

Voglio trovare un algoritmo con le seguenti proprietà:

  1. L'input specifica il numero di persone, quanto deve ogni persona e quante fatture di ciascuna denominazione ha ciascuna.

  2. L'algoritmo dice a ogni persona quali fatture mettere sul tavolo al primo turno.

  3. L'algoritmo indica a ogni persona quali fatture rimuovere dal tavolo al secondo turno.

  4. Il numero di fatture messe sul tavolo + il numero di fatture rimosse dalla tabella è ridotto al minimo.

Se non esiste una soluzione fattibile, l'algoritmo restituisce solo un errore.


9
Le denominazioni delle banconote sono fissate in anticipo (diciamo alle denominazioni americane $ 1, $ 2, $ 5, $ 10, $ 20, $ 50 e $ 100) o parte dell'input? In altre parole, l'algoritmo deve gestire la possibilità che Mefistofele abbia tre fatture da $ 7, una fattura da $ 13 e quindici fatture da $ 4 ?
JeffE,

1
Le fatture sono fisse. Immagino che in quel caso non riesco a ridurre la somma dei sottoinsiemi e dimostrare che è NP-Hard. Lo modificherò.
Chao Xu,

1
È necessario un modo per esprimere 4/5 come una singola ottimizzazione. Non è possibile ottimizzare per queste due condizioni indipendenti. So cosa intendi, ho già avuto un problema simile prima, ma devi quantificare esattamente cosa significa ottimizzare per entrambe le condizioni.
edA-qa mort-ora-y

3
Penso che sarebbe meglio, come punto di partenza, supporre che o tutti paghino esattamente il conto o che l'algoritmo riporti semplicemente il fallimento.
JeffE,

2
Qual è esattamente la domanda qui, ci sono requisiti di complessità? Scrivere un algoritmo ingenuo sembra banale o mi sto perdendo qualcosa?
Stéphane Gimenez,

Risposte:


6

Se si riformula il problema in modo leggermente diverso (ma equivalente), un algoritmo diventa più ovvio:

Sono coinvolte parti: persone e un ristorante. Diciamo essere la quantità di denaro partito dovrei avere dopo il pasto è finito e pagato. Ad esempio, se Alice ha $ 36 e deve $ 25, Bob ha $ 12 e deve $ 11 e Carl ha $ 30 e deve $ 25, diciamo che è il ristorante e ha:nn1piip0

p=(61,11,1,5)

That is, when the meal is over the restaurant should have $61, Alice should have $11, Bob should have $1 and Carl should have $5.

Now let b enumerate all of the m bills involved. For example:

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

The denominations of the bills do not matter, but I have chosen denominations of paper US currency for this example because they are familiar.

We are seeking to minimize the number of bills that change hands, so we associate a "cost" with person i leaving with bill j by using a {0,1} matrix C. Entries of 0 in this matrix indicate which bills each party starts with (C0,j=0 for all j because the restaurant starts with no bills).

Continuing our example:

C=[0000000000000011111111110000111111111100]

indicates that Alice started with $1, $5, $10, $20, Bob started with $1, $1, $5, $5, and Carl started with $10 and $20.

Again, the goal is to minimize the number of bills that change hands. In other words:

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

The first constraint says that the solution can only assign a particular bill to one party, and the second ensures that everyone pays the appropriate amount.

This is the 0,1 INTEGER PROGRAMMING problem and is NP-complete (see [Karp 1972]). The Wikipedia page about linear programming has information on different algorithms that can be used for these types of problems.

There are potentially multiple optimal solutions; by hand the first solution to the example I came up with was:

x=[0101100111101000000000001000000000001000]

which means Alice pays exactly $5 and $20, Bob pays exactly $1, $5 and $5, and Carl overpays $10 and $20 and then removes a $5 from the table.

I also used the Mixed Integer Linear Program module of the Sage Math system which has the ability to use different solver backends (GLPK, COIN, CPLEX, or Gurobi). The first solution it gave was

x=[0101010111101000000000001000000000000100]

which is almost the same except that Carl took the "other" $5 that Bob put on the table.

Formulating the problem in this way satisfies all the properties you list (you can extrapolate which bills end up where from C and the solution matrix x). The exception is perhaps #4 which was discussed in the comments of the question. It is not clear to me what you would like to do in the situation that there is no feasible solution to the set of linear equations:

Identify a subset of people that can pay the reduced total? Or perhaps a subset of people which could still pay the entire bill, i.e. they pay for their friend.

Your final statement makes it seem like you are interested in the case that the denominations of the bills are fixed, this doesn't change the problem however.

In any case, there is also an O(1) solution in which every person pays with a credit card.


That this problem can be expressed as IP was (almost?) clear; but how good is this solution? Can IPs of the created form be solved efficiently? If not, is there a faster algorithm?
Raphael

There exist a more condensed form of this IP, by having a variable for number of bills of a particular denomination than a 0,1 variable. Fixed denominations do change the complexity by a little, if the number of people are fixed as well, Lenstra's algorithm can solve it in polynomial time.
Chao Xu

-2

Certainly some basic starts could be to include the smallest bills available to reach the total amount of the overall bill. If you don't care to allow $2 bills, each person could simply remove the largest bill they can take from the pool then and would get there relatively quickly. The $2 bill throws that off as it doesn't sub-divide nicely in to the other denominations and greatly complicates the problem. There are also certainly a number of other optimizations that could be done to make observations about the need for further funds to be added during round 1 (for example, if the total number of $1 bills is ever sufficient to cover the bill, then everyone can stop putting in unless they have not yet put in enough for their bill).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.