Settling Poker Debts is NP-hard
When I play poker with friends, we don't keep a designated banker who manages buy-ins before the game. Instead, we figure out the transactions later. This works well for our small group, but scaling this up to 9 players makes coordinating the transactions non-obvious. Imagine you have an outcome like this:
| Player | Net $ |
|---|---|
| Turing | +39 |
| Church | −23 |
| Gödel | +2 |
| Curry | −75 |
| Hoare | +11 |
| Kleene | −12 |
| McCarthy | +8 |
| Dijkstra | −37 |
| Shannon | +87 |
Who sends money to who?
The Banker
It would be smart to designate a centralized banker, which we can still do after the game. Anyone who ended with a loss sends money to the banker, and the banker sends money to all those who ended with a net gain. For a game with outstanding balances, this clears them all in transactions.
A Decentralized Method
What if we don't want the burden of payouts to be put on one person? Players who ended in a loss should be able to pay out players who ended in a gain directly. We can do this while still maintaining our bound of transactions by using a simple greedy approach.
Imagine the player with the most negative balance pays the player with the most positive balance. In doing so, at least one of those two players will have their balance cleared. When there are just two outstanding balances left, a single transaction clears both balances, since they must add up to 0. Because every transaction guarantees at least one player's balance is completely settled, and the final transaction settles two balances, it takes a maximum of transactions to clear everyone.
NP-hardness
Our upper bound on the number of transactions for both methods was . However, this is not always the tightest bound: it's possible for a single transaction to clear two balances at once (if a loser's debt exactly matches a winner's gain). So, can we write an efficient algorithm to find the actual minimum number of transactions needed?
Surprisingly, we can't! At least not in polynomial time, because it turns out that this problem is NP-hard. We can show this by reducing a known NP-hard problem to our problem in polynomial time. If we can do that, then we can say that a polynomial-time solution to our problem would be a polynomial-time solution to an NP-hard problem, which would prove .
Let's reduce the Partition Problem: Given a multiset of positive integers, is it possible to partition into two multisets , , such that the sum of equals the sum of .
Given a multiset , we construct an instance of our poker problem as follows: Let be the number of elements in , and be the total sum of all elements. For each element we say that there's a player with a net gain of . Then we add two players and , each with a net loss of . Thus we have players, with all outstanding balances summing to 0.
Given this construction, we run our theoretical algorithm to determine the minimum number of transactions needed to clear all balances. If the number of transactions is , we return YES to the partition problem. Otherwise we need transactions and return NO.
To see why this works, let's prove that can be partitioned into two sets of equal sum if and only if our construction needs exactly transactions to clear balances.
can be partitioned into two sets of equal sum, say and . had its elements summing to , so both and must have their elements sum to . Let's partition the winning players in our game into the same two sets. Now can make payments, one to each player in for their full amount. This clears balances for all players in , and it clears 's balance because sums to . In the same way, can make payments and clear the remaining balances. This took transactions. Furthermore, we know this is the lower bound because there are individual players with a net gain that each need a separate transaction.
Our construction needs exactly transactions to clear all balances. There are players with a net gain, so each one was involved in exactly one transaction for their full amount. But both and also cleared their balance in these transactions. This means that every transaction must have been between some winning player and one of . And every was involved in some transaction. Thus we can partition all by which they were paid from. Let be the set of players paid by and the set of players paid by . The sum of elements in must be the same as the balance of , which is . Similarly the sum of is also . Since all came from our input set , we showed that can be partitioned into two sets of equal sum.
Fairness
Okay, so we're stuck with our solution. This is still the minimal number of transactions in the general case (consider the example with losing players and 1 winning player). But what if we want to minimize the maximum number of transactions performed by a single person? Even in our decentralized solution we could have a single player performing all transactions.
Surprisingly, we can get away with just (up to) 1 transaction per person. The intuition here is that since each losing player can only transfer money once, they must send their entire outstanding balance in one transaction. To deal with splitting payments, let's chain together players and let payments from losing players accumulate, while winning players can "hold back" their wins before passing on the remainder of the accumulated amount.
Let's arrange everyone in a chain, from lowest net result to highest: . As before, let be the outstanding balance of player .
We start with player sending to , clearing their own balance. ( itself is a negative value if ended in a loss)
Then sends to player : their own outstanding balance , plus what they received from . This clears their own balance.
sends to , and so on.
In general, sends to .
So a particular player receives from the previous player and sends to the next. This means their net change after these transactions is
Which is exactly the outstanding balance they needed to clear!
(Arranging the players in increasing order of their result gives us the guarantee that the amount being sent is never negative. If it were to be negative, they would actually be requesting money from the next player, but that player is already sending money to someone else so our goal of 1 transaction per player would be violated.)
Thus we cleared all balances without forcing any player to perform more than a single transaction. This also gives us an upper bound of total transactions: only players to are sending money. Therefore this is undoubtedly the most optimal and fair way to handle transactions after a poker game!
Come to think of it, it's been a while since my friends have invited me to a game...
Credits
When asking Claude to proof read this post, it surfaced a blogpost with a similar premise -- I really liked the complexity theory analysis, which inspired me to find a similar reduction myself.