def test_ordered_permutations(): assert list(utils.ordered_permutations([])) == [] assert list(utils.ordered_permutations([None])) == [(None,)] result = list(utils.ordered_permutations([1, 2, 1, 2])) expected = [ (1, 1, 2, 2), (1, 2, 1, 2), (1, 2, 2, 1), (2, 1, 1, 2), (2, 1, 2, 1), (2, 2, 1, 1), ] assert result == expected, \ "ordered_permutations didn't produce the correct result"
def test_ordered_permutations(): assert list(utils.ordered_permutations([])) == [], \ "empty ordered permutations wasn't empty" result = list(utils.ordered_permutations([1, 2, 1, 2])) expected = [ (1, 1, 2, 2), (1, 2, 1, 2), (1, 2, 2, 1), (2, 1, 1, 2), (2, 1, 2, 1), (2, 2, 1, 1), ] assert result == expected, \ "ordered_permutations didn't produce the correct result"
def _compact_payoffs(game): """Given a game returns a compact representation of the payoffs In this case compact means that they're in one ndarray. This representation is inefficient for almost everything but an independent game with full data. Parameters ---------- game : Game The game to generate a compact payoff matrix for Returns ------- payoffs : ndarray; shape (s1, s2, ..., sn, n) payoffs[s1, s2, ..., sn, j] is the payoff to player j when player 1 plays s1, player 2 plays s2, etc. n is the total number of players. """ payoffs = np.empty(list(game.num_strategies) + [game.num_roles]) for profile, payoff in zip(game.profiles, game.payoffs): # This generator expression takes a role symmetric profile with payoffs # and generates tuples of strategy indexes and payoffs for every player # when that player plays the given strategy. # The first line takes results in the form: # (((r1i1, r1p1), (r1i2, r1p2)), ((r1i1, r2p1),)) that is grouped by # role, then by player in the role, then grouped strategy index and # payoff, and turns it into a single tuple of indices and payoffs. perms = (zip(*itertools.chain.from_iterable(sp)) # This product is over roles for sp in itertools.product(*[ # This computes all of the ordered permutations of # strategies in a given role, e.g. if two players play s1 # and one plays s2, this iterates over all possible ways # that could be expressed in an asymmetric game. utils.ordered_permutations(itertools.chain.from_iterable( # This iterates over the strategy counts, and # duplicates strategy indices and payoffs based on the # strategy counts. itertools.repeat((i, v), c) for i, (c, v) in enumerate(zip(p, pay)))) for p, pay in zip(game.role_split(profile), game.role_split(payoff))])) for indices, utilities in perms: payoffs[indices] = utilities return payoffs