📚 Math in Society
⇩ Download ▾

5.3 How not to divide with 3 parties

When first approaching the question of 3-party fair division, it is very tempting to propose this method: Randomly designate one participant to be the divider, and designate the rest choosers. Proceed as follows:

# Math in Society 5.3 -- Why the obvious 3-party method is NOT fair
# "Divider cuts three pieces, chooser 1 picks, chooser 2 picks, divider takes the
# rest." It looks fair. Run it and check the last chooser.
table = {"Chooser 1": [40, 30, 30],       # each row is that person's valuation,
         "Chooser 2": [45, 30, 25],       # as a percent of the whole. EDIT any row.
         "Divider":   [100/3, 100/3, 100/3]}
PICK_ORDER = ["Chooser 1", "Chooser 2"]   # EDIT: reverse this and re-run

people = list(table)
n = len(people)
fair = 100 / n
divider = [p for p in people if p not in PICK_ORDER][0]

print(f"{n} parties, so a fair share is {fair:.1f}% of the whole in your own eyes.")
print(f"   {'':<11}" + "".join(f"{'Piece '+str(i+1):>10}" for i in range(n)))
for p in people:
    print(f"   {p:<11}" + "".join(f"{v:>9.1f}%" for v in table[p]))

left = list(range(n))
got, offered = {}, {}
print()
for p in PICK_ORDER:
    offered[p] = list(left)
    best = max(left, key=lambda i: table[p][i])
    got[p] = best
    left.remove(best)
    print(f"   {p} picks the best piece still on the table: Piece {best+1}"
          f", worth {table[p][best]:.1f}%")
got[divider] = left[0]
print(f"   {divider} is left with Piece {left[0]+1}, worth {table[divider][left[0]]:.1f}%")

print()
short = []
for p in people:
    v = table[p][got[p]]
    ok = v >= fair - 1e-9
    if not ok:
        short.append(p)
    print(f"   {p:<11} ends with {v:>5.1f}%   "
          + ("at least a fair share" if ok else "SHORT -- this division is NOT fair"))

if short:
    p = short[0]
    menu = ", ".join(f"Piece {i+1} at {table[p][i]:.1f}%" for i in offered[p])
    print(f"\n{p} picked last and never had a fair share on offer: the choice was")
    print(f"   {menu}")
    print(f"and nothing there reaches {fair:.1f}%. A method is only fair if a fair")
    print("share is guaranteed to be available no matter what the others do first.")
else:
    print("\nEveryone did fine THIS time -- but a method is only fair if it works for")
    print("every valuation table, not the friendly ones.")

print("\nTry it: change Chooser 2's row to [40, 35, 25] and re-run. Now the method")
print("happens to work. Change it back and reverse PICK_ORDER: the unfairness just")
print("moves to whoever ends up last. The fix is in Section 5.4, Lone Divider.")

1) Have the divider divide the item into 3 pieces

2) Have the first chooser select any of the three pieces they feel is worth a fair share

3) Have the second chooser select either of the remaining pieces

4) The divider gets the piece left.

To handle division with 3 or more parties, we’ll have to take a more clever approach.

Adapted from Math in Society by David Lippman, hosted on LibreTexts (math.libretexts.org) and licensed under CC BY-SA 3.0. Changes were made. License: CC-BY-SA-3.0.

These eBooks are a prerelease and are not yet certified conformant with WCAG 2.1 AA or ADA Title II. Every page is built against an automated accessibility gate, and the published editions will meet ADA Title II requirements when they release in late September 2026. If something is unusable, please tell us.