In this eposide of Golden Balls, an inspired event takes place:

I retold the event at DIKU APL lunch (nice to have a job where game theory is a valid conversation topic), and we had a conversation about it. At first I thought this was prisoners dilemma, but it was quickly revealed that it is a different game. What is cool about it is, that Nick basically forces Abraham to pick split. I don’t think the same approach would work again though. The person in Abrahams position might be tempted to try a counter-steal. The person in Nicks position might be tempted to actually steal the money, which would be a dirty thing to do, but not completely unlikely.

Someone remarked that if each player was a random variable, stealing would be twice as successful as splitting, as on average you get half the money by stealing, while splitting only gets you one quarter of the money on average.

Clearly players are not random variables, so we talked a bit about what a genetic algorithm simulation would reveal. Obviously, if all people were stealers, everyone would loose all the time, so that might inspire people to try splitting. If most people were splitters, stealers would have a field day, which might inspire people to become stealers. Someone speculated that running a simulation would reveal some kind of oscillating pattern. I decided to build a model and implement a simulation in Python.

The way the simulation works is this: A population is initialized, with a certain ratio between stealers and splitters (I use a 50/50 split). A game of golden balls is played, by drawing two participants randomly from the population. If the outcome is a steal, it will have an propability of converting splitters in the population into stealers. If the outcome is a split, it will conversely have a propability of converting stealers into splitters. If the outcome is a mutual steal, and hence loss, it will have a (slightly bigger) propability of converting stealers into splitters.

`golden_balls.py`:

import random def main(): # constants POP_SIZE = 1000 INITIAL_STEALERS = 0.5 population = int(POP_SIZE*INITIAL_STEALERS)*[1] population.extend(int(POP_SIZE*(1-INITIAL_STEALERS))*[0]) GAMES = 100 CONVERT_TO_STEALER = 0.1 CONVERT_TO_SPLITTER = 0.05 CONVERT_TO_SPLITTER_ON_LOOSE = 0.1 ts = [['Generation', 'Percent stealers in population']] # generations for game in range(GAMES): # calc stealer percent stealers = round(reduce(lambda x,y: x+y, population) / float( len(population) ), 5) # record last generation ts.append([game, stealers]) # play game p1 = random.random() <= stealers p2 = random.random() <= stealers new_pop = [] for person in population: if (p1 or p2) and not (p1 and p2): # steal if random.random() <= CONVERT_TO_STEALER: # converted new_pop.append(1) else: new_pop.append(person) elif (not p1) and (not p2): # split if random.random() <= CONVERT_TO_SPLITTER: new_pop.append(0) else: new_pop.append(person) else: # loose if random.random() <= CONVERT_TO_SPLITTER_ON_LOOSE: new_pop.append(0) else: new_pop.append(person) population = new_pop print ts if __name__ == '__main__': main() |

The outcome of the simulation: