Example #1
0
 def dev_profs(red_players, full_players, mask, rst):
     """Deviation profiles for a particular role"""
     rgame = rsgame.empty(red_players, support)
     sub_profs = restrict.translate(rgame.all_profiles(), rest)
     game = rsgame.empty(full_players, full_game.num_role_strats)
     non_devs = hierarchical.expand_profiles(game, sub_profs)
     ndevs = np.sum(~mask)
     devs = np.zeros((ndevs, full_game.num_strats), int)
     devs[:, rst:rst + mask.size][:, ~mask] = np.eye(ndevs, dtype=int)
     profs = non_devs[:, None] + devs
     profs.shape = (-1, full_game.num_strats)
     return profs
 def dev_profs(red_players, full_players, mask, rst):
     """Deviation profiles for a particular role"""
     rgame = rsgame.empty(red_players, support)
     sub_profs = restrict.translate(rgame.all_profiles(), rest)
     game = rsgame.empty(full_players, full_game.num_role_strats)
     non_devs = hierarchical.expand_profiles(game, sub_profs)
     ndevs = np.sum(~mask)
     devs = np.zeros((ndevs, full_game.num_strats), int)
     devs[:, rst:rst + mask.size][:, ~mask] = np.eye(ndevs, dtype=int)
     profs = non_devs[:, None] + devs
     profs.shape = (-1, full_game.num_strats)
     return profs
Example #3
0
def test_random_hr_identity(_):
    """Test hierarchical identity"""
    num_strats = rand.randint(2, 20)
    profile = rand.randint(20, size=num_strats)[None]
    reduced_players = profile.sum()
    while reduced_players < 2:  # pragma: no cover
        profile[0, rand.randint(num_strats)] += 1
        reduced_players += 1
    full_players = rand.randint(reduced_players + 1, reduced_players ** 2)
    game = rsgame.empty(reduced_players, num_strats)
    full_profile = hr.expand_profiles(
        rsgame.empty(full_players, num_strats), profile)
    red_profile = hr.reduce_profiles(game, full_profile)
    assert np.all(red_profile == profile), "reduction didn't pass identity"
Example #4
0
def aggfn(  # pylint: disable=too-many-arguments
        num_role_players,
        num_role_strats,
        action_weights,
        function_inputs,
        function_table,
        offsets=None):
    """Create an Aggfn with default names

    Parameters
    ----------
    num_role_players : ndarray
        The number of players per role.
    num_role_strats : ndarray
        The number of strategies per role.
    action_weights : ndarray, float
        The action weights.
    function_inputs : ndarray, bool
        The input mask for each function.
    function_table : ndarray, float
        The function value relative to number of incoming edges.
    offsets : ndarray, float, optional
        A constant offset for each strategies payoff. Constant functions are
        not allowed in the function table as they are clutter, instead,
        constant functions can be specified here.
    """
    return aggfn_replace(rsgame.empty(num_role_players,
                                      num_role_strats), action_weights,
                         function_inputs, function_table, offsets)
Example #5
0
async def test_sparse_trace():
    """Test that tracing sparsely samples profiles"""
    base = rsgame.empty(4, 3)
    game1 = paygame.game_replace(base, base.all_profiles(),
                                 (base.all_profiles() > 0) * [1, 0, 0])
    game2 = paygame.game_replace(base, base.all_profiles(),
                                 (base.all_profiles() > 0) * [-0.5, 1.5, 0])
    save1 = savesched.savesched(gamesched.gamesched(game1))
    save2 = savesched.savesched(gamesched.gamesched(game2))

    sgame1 = schedgame.schedgame(save1)
    sgame2 = schedgame.schedgame(save2)

    await asyncio.gather(innerloop.inner_loop(sgame1),
                         innerloop.inner_loop(sgame2))

    # Assert that innerloop doesn't scheduler all profiles
    assert save1.get_game().num_profiles == 11
    assert save2.get_game().num_profiles == 11

    ((st1, *_, en1), _), ((st2, *_, en2), _) = (  # pylint: disable=too-many-star-expressions
        await trace.trace_all_equilibria(sgame1, sgame2))

    # Assert that trace found the expected equilibria
    assert np.isclose(st1, 0)
    assert np.isclose(en1, 1 / 3, atol=1e-3)
    assert np.isclose(st2, 1 / 3, atol=1e-3)
    assert np.isclose(en2, 1)

    # Assert that trace didn't need many extra profiles
    assert save1.get_game().num_profiles == 12
    assert save2.get_game().num_profiles == 12
Example #6
0
def normal_aggfn(role_players, role_strats, functions, *, input_prob=0.2,
                 weight_prob=0.2):
    """Generate a random normal AgfnGame

    Each function value is an i.i.d Gaussian random walk.

    Parameters
    ----------
    role_players : int or ndarray
        The number of players per role.
    role_strats : int or ndarray
        The number of strategies per role.
    functions : int
        The number of functions to generate.
    input_prob : float, optional
        The probability of a strategy counting towards a function value.
    weight_prob : float, optional
        The probability of a function producing non-zero payoffs to a strategy.
    """
    base = rsgame.empty(role_players, role_strats)
    inputs = _random_inputs(input_prob, base.num_strats, functions)
    weights = _random_weights(weight_prob, functions, base.num_strats)

    shape = (functions,) + tuple(base.num_role_players + 1)
    funcs = np.random.normal(0, 1 / np.sqrt(base.num_players + 1), shape)
    for role in range(1, base.num_roles + 1):
        funcs.cumsum(role, out=funcs)
    mean = funcs.mean(tuple(range(1, base.num_roles + 1)))
    mean.shape = (functions,) + (1,) * base.num_roles
    funcs -= mean
    return aggfn.aggfn_replace(base, weights, inputs, funcs)
Example #7
0
def test_hierarchical_dev_expansion():
    """Test that hierarchical dev expansion is correct"""
    game = rsgame.empty([9, 16], [4, 3])
    mask = [True, False, True, False, False, True, False]
    profs = hr.expand_deviation_profiles(game, mask, [3, 4])
    actual = utils.axis_to_elem(profs)
    expected = utils.axis_to_elem([
        [6, 3, 0, 0, 0, 16, 0],
        [3, 3, 3, 0, 0, 16, 0],
        [0, 3, 6, 0, 0, 16, 0],
        [6, 0, 0, 3, 0, 16, 0],
        [3, 0, 3, 3, 0, 16, 0],
        [0, 0, 6, 3, 0, 16, 0],
        [9, 0, 0, 0, 4, 12, 0],
        [6, 0, 3, 0, 4, 12, 0],
        [3, 0, 6, 0, 4, 12, 0],
        [0, 0, 9, 0, 4, 12, 0],
        [9, 0, 0, 0, 0, 12, 4],
        [6, 0, 3, 0, 0, 12, 4],
        [3, 0, 6, 0, 0, 12, 4],
        [0, 0, 9, 0, 0, 12, 4],
    ])
    assert np.setxor1d(actual, expected).size == 0

    profs = hr.expand_deviation_profiles(game, mask, [3, 4], 0)
    actual = utils.axis_to_elem(profs)
    expected = utils.axis_to_elem([
        [6, 3, 0, 0, 0, 16, 0],
        [3, 3, 3, 0, 0, 16, 0],
        [0, 3, 6, 0, 0, 16, 0],
        [6, 0, 0, 3, 0, 16, 0],
        [3, 0, 3, 3, 0, 16, 0],
        [0, 0, 6, 3, 0, 16, 0],
    ])
    assert np.setxor1d(actual, expected).size == 0
Example #8
0
def test_identity_dev_expansion():
    """Test that identity dev expansion is correct"""
    game = rsgame.empty([3, 4], [4, 3])
    mask = [True, False, True, False, False, True, False]
    profs = ir.expand_deviation_profiles(game, mask)
    actual = utils.axis_to_elem(profs)
    expected = utils.axis_to_elem([
        [2, 1, 0, 0, 0, 4, 0],
        [1, 1, 1, 0, 0, 4, 0],
        [0, 1, 2, 0, 0, 4, 0],
        [2, 0, 0, 1, 0, 4, 0],
        [1, 0, 1, 1, 0, 4, 0],
        [0, 0, 2, 1, 0, 4, 0],
        [3, 0, 0, 0, 1, 3, 0],
        [2, 0, 1, 0, 1, 3, 0],
        [1, 0, 2, 0, 1, 3, 0],
        [0, 0, 3, 0, 1, 3, 0],
        [3, 0, 0, 0, 0, 3, 1],
        [2, 0, 1, 0, 0, 3, 1],
        [1, 0, 2, 0, 0, 3, 1],
        [0, 0, 3, 0, 0, 3, 1],
    ])
    assert np.setxor1d(actual, expected).size == 0

    profs = ir.expand_deviation_profiles(game, mask, role_index=0)
    actual = utils.axis_to_elem(profs)
    expected = utils.axis_to_elem([
        [2, 1, 0, 0, 0, 4, 0],
        [1, 1, 1, 0, 0, 4, 0],
        [0, 1, 2, 0, 0, 4, 0],
        [2, 0, 0, 1, 0, 4, 0],
        [1, 0, 1, 1, 0, 4, 0],
        [0, 0, 2, 1, 0, 4, 0],
    ])
    assert np.setxor1d(actual, expected).size == 0
Example #9
0
def test_twins_dev_expansion():
    """Test that dpr dev expansion is correct

    Note, this is the only one that has "new" code, so it's the most important
    to test."""
    game = rsgame.empty([9, 16], [4, 3])
    mask = [True, False, True, False, False, True, False]
    profs = tr.expand_deviation_profiles(game, mask)
    actual = utils.axis_to_elem(profs)
    expected = utils.axis_to_elem([
        [8, 1, 0, 0, 0, 16, 0],
        [0, 1, 8, 0, 0, 16, 0],
        [8, 0, 0, 1, 0, 16, 0],
        [0, 0, 8, 1, 0, 16, 0],
        [9, 0, 0, 0, 1, 15, 0],
        [5, 0, 4, 0, 1, 15, 0],
        [0, 0, 9, 0, 1, 15, 0],
        [9, 0, 0, 0, 0, 15, 1],
        [5, 0, 4, 0, 0, 15, 1],
        [0, 0, 9, 0, 0, 15, 1],
    ])
    assert np.setxor1d(actual, expected).size == 0

    profs = tr.expand_deviation_profiles(game, mask, role_index=0)
    actual = utils.axis_to_elem(profs)
    expected = utils.axis_to_elem([
        [8, 1, 0, 0, 0, 16, 0],
        [0, 1, 8, 0, 0, 16, 0],
        [8, 0, 0, 1, 0, 16, 0],
        [0, 0, 8, 1, 0, 16, 0],
    ])
    assert np.setxor1d(actual, expected).size == 0
Example #10
0
def large_games():
    """Games that test functionality in large spaces"""
    yield rsgame.empty([1, 1], [5, 5])
    yield rsgame.empty([2, 2], [5, 5])
    yield rsgame.empty([5, 5], [2, 2])
    yield rsgame.empty([1, 1, 1, 1], 2)
    yield rsgame.empty([3, 3, 3], [3, 3, 3])
    yield rsgame.empty([2, 3, 4], [4, 3, 2])
    yield rsgame.empty(170, 2)
    yield rsgame.empty(180, 2)
Example #11
0
def test_empty_add_noise():
    """Test adding noise to an empty game"""
    base_game = rsgame.empty([3, 3], [4, 4])
    game = gamegen.gen_noise(base_game)
    assert game.is_empty()

    base_game = gamegen.game([3] * 3, 4)
    game = gamegen.gen_noise(base_game, 0, 0)
    assert game.is_empty()
Example #12
0
def test_empty_add_noise():
    """Test adding noise to an empty game"""
    base_game = rsgame.empty([3, 3], [4, 4])
    game = gamegen.gen_noise(base_game)
    assert game.is_empty()

    base_game = gamegen.game([3] * 3, 4)
    game = gamegen.gen_noise(base_game, 0, 0)
    assert game.is_empty()
Example #13
0
 def dev_profs(players, mask, rst):
     """Get deviation profiles"""
     rgame = rsgame.empty(players, support)
     non_devs = translate(rgame.all_profiles(), rest)
     ndevs = np.sum(~mask)
     devs = np.zeros((ndevs, game.num_strats), int)
     devs[:, rst:rst + mask.size][:, ~mask] = np.eye(ndevs, dtype=int)
     profs = non_devs[:, None] + devs
     profs.shape = (-1, game.num_strats)
     return profs
Example #14
0
 def dev_profs(players, mask, rst):
     """Get deviation profiles"""
     rgame = rsgame.empty(players, support)
     non_devs = translate(rgame.all_profiles(), rest)
     ndevs = np.sum(~mask)
     devs = np.zeros((ndevs, game.num_strats), int)
     devs[:, rst:rst + mask.size][:, ~mask] = np.eye(ndevs, dtype=int)
     profs = non_devs[:, None] + devs
     profs.shape = (-1, game.num_strats)
     return profs
Example #15
0
def games():
    """Test games"""
    yield rsgame.empty(1, 2)
    yield rsgame.empty(2, 2)
    yield rsgame.empty([2, 1], [1, 2])
    yield rsgame.empty([1, 2], [2, 1])
    yield rsgame.empty([2, 2], [2, 2])
    yield rsgame.empty([3, 2], [2, 3])
    yield rsgame.empty([1, 1, 1], 2)
Example #16
0
def basic_games():
    """Small basic games for testing"""
    yield rsgame.empty(1, 2)
    yield rsgame.empty(2, 2)
    yield rsgame.empty(2, 3)
    yield rsgame.empty(3, 2)
    yield rsgame.empty(3, 3)
    yield rsgame.empty([2, 3], [3, 2])
    yield rsgame.empty([1, 1, 1], 2)
Example #17
0
def test_identity_names():
    """Test identity with names"""
    base = rsgame.empty(3, 2)
    game = paygame.game_names(
        ['role'], 3, [['a', 'b']], base.all_profiles(),
        np.zeros((base.num_all_profiles, base.num_strats)))
    redgame = ir.reduce_game(game)
    expected = paygame.game_names(
        ['role'], 3, [['a', 'b']], redgame.all_profiles(),
        np.zeros((redgame.num_all_profiles, base.num_strats)))
    assert redgame == expected
Example #18
0
def test_dpr_names():
    """Test names for dpr game"""
    base = rsgame.empty(3, 2)
    game = paygame.game_names(
        ['role'], 3, [['a', 'b']], base.all_profiles(),
        np.zeros((base.num_all_profiles, base.num_strats)))
    redgame = dpr.reduce_game(game, 2)
    expected = paygame.game_names(
        ['role'], 2, [['a', 'b']], redgame.all_profiles(),
        np.zeros((redgame.num_all_profiles, base.num_strats)))
    assert redgame == expected
Example #19
0
def test_hierarchical_names():
    """Test hierarchical with names"""
    base = rsgame.empty(4, 2)
    game = paygame.game_names(
        ['role'], 4, [['a', 'b']], base.all_profiles(),
        np.zeros((base.num_all_profiles, base.num_strats)))
    redgame = hr.reduce_game(game, 2)
    expected = paygame.game_names(
        ['role'], 2, [['a', 'b']], redgame.all_profiles(),
        np.zeros((redgame.num_all_profiles, base.num_strats)))
    assert redgame == expected
Example #20
0
async def test_innerloop_dpr(redgame):
    """Test that inner loop handles dpr"""
    fullgame = rsgame.empty(redgame.num_role_players**2,
                            redgame.num_role_strats)
    profs = dpr.expand_profiles(fullgame, redgame.all_profiles())
    pays = np.random.random(profs.shape)
    pays[profs == 0] = 0
    sgame = paygame.samplegame_replace(fullgame, profs, [pays[:, None]])
    sched = gamesched.samplegamesched(sgame)
    game = schedgame.schedgame(sched, dpr, redgame.num_role_players)
    eqa = await innerloop.inner_loop(game)
    verify_dist_thresh(eqa)
Example #21
0
async def test_sim_delayed_fail(tmpdir):
    """Test delayed simulation fail"""
    game = rsgame.empty(4, 3)
    game_file = str(tmpdir.join("game.json"))
    with open(game_file, "w") as fil:
        json.dump(game.to_json(), fil)
    script = str(tmpdir.join("script.sh"))
    with open(script, "w") as fil:
        fil.write("sleep 1 && false")
    sched = "sim:game:{},command:bash {}".format(game_file, script)
    with stdin(json.dumps({})):
        assert not await run("brute", sched)
Example #22
0
def rand(players, strategies, functions):
    """Create random game"""
    base = rsgame.empty(players, strategies)
    action_weights = np.random.normal(0, 1, (functions, base.num_strats))
    function_inputs = np.random.random((base.num_strats, functions)) < .5
    for func in function_inputs.T:
        func[np.random.choice(base.num_strats, 2, False)] = [False, True]
    function_table = np.random.normal(
        0, 1, (functions,) + tuple(base.num_role_players + 1))
    offsets = np.random.normal(0, 1, base.num_strats)
    return aggfn.aggfn_replace(base, action_weights, function_inputs,
                               function_table, offsets)
Example #23
0
async def test_trace_norm():
    """Test tracing"""
    base_game = rsgame.empty([3, 2], [2, 3])
    async with mockserver.server() as server:
        game0 = add_singleton_role(base_game, 0, 'a', 'sx', 1)
        sched0 = await get_eosched(server, game0, 'game0')
        game1 = add_singleton_role(base_game, 1, 'r00', 's0', 3)
        sched1 = await get_eosched(server, game1, 'game1')
        with stdout() as out, stderr() as err:
            assert await run('trace', sched0, sched1), err.getvalue()
        traces = json.loads(out.getvalue())
    verify_trace_json(base_game, traces)
Example #24
0
async def test_trace_norm():
    """Test tracing"""
    base_game = rsgame.empty([3, 2], [2, 3])
    async with mockserver.server() as server:
        game0 = add_singleton_role(base_game, 0, "a", "sx", 1)
        sched0 = await get_eosched(server, game0, "game0")
        game1 = add_singleton_role(base_game, 1, "r00", "s0", 3)
        sched1 = await get_eosched(server, game1, "game1")
        with stdout() as out, stderr() as err:
            assert await run("trace", sched0, sched1), err.getvalue()
        traces = json.loads(out.getvalue())
    verify_trace_json(base_game, traces)
Example #25
0
def test_dpr_deviation_count():
    """Test dpr dev count"""
    game = rsgame.empty(3, 2)
    num_devs = restrict.num_dpr_deviation_profiles(
        game, [True, False])
    assert num_devs == 2

    game = rsgame.empty([1, 3], 2)
    num_devs = restrict.num_dpr_deviation_profiles(
        game, [True, True, True, False])
    assert num_devs == 6

    game = rsgame.empty(1, [3, 1])
    num_devs = restrict.num_dpr_deviation_profiles(
        game, [True, True, False, True])
    assert num_devs == 1

    game = rsgame.empty([3, 2, 1], [1, 2, 3])
    num_devs = restrict.num_dpr_deviation_profiles(
        game, [True, True, False, True, False, True])
    assert num_devs == 7
Example #26
0
def test_random_dpr(keep_prob, game_desc, _):
    """Simple test that dpr functions are consistent"""
    players, strategies, red_players = game_desc
    # Create game
    game = gamegen.game(players, strategies, keep_prob)

    # Try to reduce game
    red_game = dpr.reduce_game(game, red_players)
    assert (rsgame.empty(red_players, strategies) ==
            dpr.reduce_game(rsgame.empty(players, strategies),
                            red_players))

    # Assert that reducing all profiles covers reduced game
    reduced_profiles = utils.axis_to_elem(red_game.profiles())
    reduced_full_profiles = utils.axis_to_elem(
        dpr.reduce_profiles(red_game, game.profiles()))
    assert np.setdiff1d(reduced_profiles, reduced_full_profiles).size == 0, \
        "reduced game contained profiles it shouldn't have"

    # Assert that all contributing profiles are in the expansion of the reduced
    # game, we need to first filter for complete profiles
    full_profiles = utils.axis_to_elem(game.profiles())
    complete_profs = ~np.isnan(red_game.payoffs()).any(1)
    full_reduced_profiles = utils.axis_to_elem(
        dpr.expand_profiles(game, red_game.profiles()[complete_profs]))
    assert np.setdiff1d(full_reduced_profiles, full_profiles).size == 0, \
        'full game did not have data for all profiles required of reduced'

    # Assert that dpr counts are accurate
    num_dpr_profiles = dpr.expand_profiles(
        game, red_game.all_profiles()).shape[0]
    assert num_dpr_profiles == red_game.num_all_dpr_profiles

    # Test the dpr deviation profile counts are accurate
    rest = red_game.random_restriction()
    dpr_devs = dpr.expand_profiles(
        game, restrict.deviation_profiles(red_game, rest)).shape[0]
    num = restrict.num_dpr_deviation_profiles(red_game, rest)
    assert dpr_devs == num, \
        "num_dpr_deviation_profiles didn't return correct number"
Example #27
0
async def test_sim_delayed_fail(tmpdir):
    """Test delayed simulation fail"""
    game = rsgame.empty(4, 3)
    game_file = str(tmpdir.join('game.json'))
    with open(game_file, 'w') as fil:
        json.dump(game.to_json(), fil)
    script = str(tmpdir.join('script.sh'))
    with open(script, 'w') as fil:
        fil.write('sleep 1 && false')
    sched = 'sim:game:{},command:bash {}'.format(game_file, script)
    with stdin(json.dumps({})):
        assert not await run(
            'brute', sched)
Example #28
0
def samplegame(players, strats, *args, **kwargs):
    """Generate a random role symmetric sample game

    Parameters
    ----------
    players : int or [int]
        The number of players per role.
    strats : int or [int]
        The number of strategies per role.
    **args
        The arguments to pass to samplegame_replace.
    """
    return samplegame_replace(rsgame.empty(players, strats), *args, **kwargs)
Example #29
0
def matgame(payoff_matrix):
    """Create a game from a dense matrix with default names

    Parameters
    ----------
    payoff_matrix : ndarray-like
        The matrix of payoffs for an asymmetric game.
    """
    payoff_matrix = np.ascontiguousarray(payoff_matrix, float)
    return matgame_replace(
        rsgame.empty(
            np.ones(payoff_matrix.ndim - 1, int),
            np.array(payoff_matrix.shape[:-1], int)),
        payoff_matrix)
Example #30
0
def test_approximate_dpr_expansion():
    """Test expansion on approximate dpr"""
    full_game = rsgame.empty([8, 11], [2, 2])
    red_prof = [[1, 2, 2, 2]]
    full_profs = dpr.expand_profiles(
        full_game, red_prof)
    profs = utils.axis_to_elem(full_profs)
    expected = utils.axis_to_elem([
        [4, 4, 6, 5],
        [1, 7, 6, 5],
        [3, 5, 4, 7],
        [3, 5, 7, 4]])
    assert np.setxor1d(profs, expected).size == 0, \
        'generated different profiles than expected'
Example #31
0
def test_random_identity(keep_prob, game_desc, _):
    """Test random identity"""
    players, strategies = game_desc
    # Create game and reduction
    game = gamegen.game(players, strategies, keep_prob)
    assert (paygame.game_copy(rsgame.empty(players, strategies)) ==
            ir.reduce_game(rsgame.empty(players, strategies)))

    # Try to reduce game
    red_game = ir.reduce_game(game)

    # Assert that reducing all profiles covers reduced game
    reduced_full_profiles = utils.axis_to_elem(
        ir.reduce_profiles(red_game, game.profiles()))
    reduced_profiles = utils.axis_to_elem(red_game.profiles())
    assert np.setxor1d(reduced_full_profiles, reduced_profiles).size == 0, \
        "reduced game didn't match full game"

    full_profiles = utils.axis_to_elem(game.profiles())
    full_reduced_profiles = utils.axis_to_elem(
        ir.expand_profiles(game, red_game.profiles()))
    assert np.setxor1d(full_profiles, full_reduced_profiles).size == 0, \
        'full game did not match reduced game'
Example #32
0
def test_rand_dpr_dev_expandion(players, strategies, red_players, _):
    """Test that dpr devs works for random games"""
    game = rsgame.empty(players, strategies)
    sup = (rand.random(game.num_roles) * game.num_role_strats).astype(int) + 1
    inds = np.concatenate(
        [rand.choice(s, x) + o for s, x, o
         in zip(game.num_role_strats, sup, game.role_starts)])
    mask = np.zeros(game.num_strats, bool)
    mask[inds] = True
    devs = dpr.expand_deviation_profiles(game, mask, red_players)
    assert np.all(np.sum(devs * ~mask, 1) == 1)

    for r_ind in range(game.num_roles):
        r_devs = dpr.expand_deviation_profiles(game, mask, red_players, r_ind)
        assert np.all(np.sum(r_devs * ~mask, 1) == 1)
Example #33
0
def test_random_hierarchical(keep_prob, players, strategies, red_players, _):
    """Test random hierarchical"""
    # Create game and reduction
    game = gamegen.game(players, strategies, keep_prob)
    assert (rsgame.empty(red_players, strategies) ==
            hr.reduce_game(rsgame.empty(players, strategies), red_players))

    # Try to reduce game
    red_game = hr.reduce_game(game, red_players)

    # Assert that reducing all profiles covers reduced game
    reduced_full_profiles = utils.axis_to_elem(
        hr.reduce_profiles(red_game, game.profiles()))
    reduced_profiles = utils.axis_to_elem(red_game.profiles())
    assert np.setxor1d(reduced_profiles, reduced_full_profiles).size == 0, \
        "reduced game contained profiles it shouldn't have"

    # Assert that all contributing profiles are in the expansion of the reduced
    # game. Since hr doesn't add any incomplete profiles, it can't produce any
    full_profiles = utils.axis_to_elem(game.profiles())
    full_reduced_profiles = utils.axis_to_elem(
        hr.expand_profiles(game, red_game.profiles()))
    assert np.setdiff1d(full_reduced_profiles, full_profiles).size == 0, \
        'full game did not have data for all profiles required of reduced'
Example #34
0
def game(players, strats, prob=1.0, distribution=default_distribution):
    """Generate a random role symmetric game with sparse profiles

    Parameters
    ----------
    players : int or [int]
        The number of players per role.
    strats : int or [int]
        The number of strategies per role.
    prob : float, optional
        The probability of any profile being included in the game.
    distribution : (shape) -> ndarray, optional
        Distribution function to draw payoffs from.
    """
    return game_replace(rsgame.empty(players, strats), prob, distribution)
Example #35
0
def expand_profiles(full_game, profiles):
    """Expand profiles using twins reduction

    Parameters
    ----------
    full_game : Game
        Game that expanded profiles will be valid for.
    profiles : ndarray-like
        The profiles to expand
    """
    red_players = np.minimum(full_game.num_role_players, 2)
    profiles = np.asarray(profiles, int)
    red_game = rsgame.empty(red_players, full_game.num_role_strats)
    utils.check(red_game.is_profile(profiles).all(), 'profiles must be valid')
    return dpr.expand_profiles(full_game, profiles)
Example #36
0
def test_restriction():
    """Test basic restriction"""
    game = rsgame.empty([3, 4], [3, 2])
    rest = np.asarray([1, 0, 1, 0, 1], bool)
    devs = restrict.deviation_profiles(game, rest)
    assert devs.shape[0] == 7, \
        "didn't generate the right number of deviating profiles"
    adds = restrict.additional_strategy_profiles(game, rest, 1).shape[0]
    assert adds == 6, \
        "didn't generate the right number of additional profiles"
    rest2 = rest.copy()
    rest2[1] = True
    assert (game.restrict(rest2).num_all_profiles ==
            adds + game.restrict(rest).num_all_profiles), \
        "additional profiles didn't return the proper amount"
Example #37
0
def sparse_game(players, strats, num, distribution=default_distribution):
    """Generate a random role symmetric game with sparse profiles

    Parameters
    ----------
    players : int or [int]
        The number of players per role.
    strats : int or [int]
        The number of strategies per role.
    num : int
        The number of profiles to draw payoffs for.
    distribution : (shape) -> ndarray, optional
        Distribution function to draw payoffs from.
    """
    return gen_num_profiles(
        rsgame.empty(players, strats), num, distribution)
Example #38
0
def expand_profiles(full_game, profiles):
    """Expand profiles using twins reduction

    Parameters
    ----------
    full_game : Game
        Game that expanded profiles will be valid for.
    profiles : ndarray-like
        The profiles to expand
    """
    red_players = np.minimum(full_game.num_role_players, 2)
    profiles = np.asarray(profiles, int)
    red_game = rsgame.empty(red_players, full_game.num_role_strats)
    utils.check(
        red_game.is_profile(profiles).all(), 'profiles must be valid')
    return dpr.expand_profiles(full_game, profiles)
Example #39
0
def test_gen_profiles(players, strategies, _):
    """Test gen profiles"""
    base = rsgame.empty(players, strategies)
    game = gamegen.gen_profiles(base)
    assert game.is_complete(), "didn't generate a full game"
    assert np.all(players == game.num_role_players), \
        "didn't generate correct number of strategies"
    assert np.all(strategies == game.num_role_strats), \
        "didn't generate correct number of strategies"

    game = gamegen.gen_profiles(base, 0.0)
    assert game.is_empty(), "didn't generate a full game"

    game = gamegen.gen_profiles(base, 0.5)

    game = gamegen.gen_num_profiles(base, base.num_all_profiles // 2)
    assert game.num_profiles == game.num_all_profiles // 2
Example #40
0
def additional_strategy_profiles(game, rest, role_strat_ind):
    """Returns all profiles added by strategy at index"""
    # This uses the observation that the added profiles are all of the profiles
    # of the new restricted game with one less player in role, and then where
    # that last player always plays strat
    rest = np.asarray(rest, bool)
    utils.check(game.is_restriction(rest), 'restriction must be valid')
    new_players = game.num_role_players.copy()
    new_players[game.role_indices[role_strat_ind]] -= 1
    base = rsgame.empty(new_players, game.num_role_strats)
    new_mask = rest.copy()
    new_mask[role_strat_ind] = True
    profs = base.restrict(new_mask).all_profiles()
    expand_profs = np.zeros((profs.shape[0], game.num_strats), int)
    expand_profs[:, new_mask] = profs
    expand_profs[:, role_strat_ind] += 1
    return expand_profs
Example #41
0
def travellers_dilemma(players=2, max_value=100):
    """Return an instance of travellers dilemma

    Strategies range from 2 to max_value, thus there will be max_value - 1
    strategies."""
    utils.check(players > 1, 'players must be more than one')
    utils.check(max_value > 2, 'max value must be more than 2')
    base = rsgame.empty(players, max_value - 1)
    profiles = base.all_profiles()
    payoffs = np.zeros(profiles.shape)
    mins = np.argmax(profiles, -1)
    mask = profiles > 0
    payoffs[mask] = mins.repeat(mask.sum(-1))
    rows = np.arange(profiles.shape[0])
    ties = profiles[rows, mins] > 1
    lowest_pays = mins + 4
    lowest_pays[ties] -= 2
    payoffs[rows, mins] = lowest_pays
    return paygame.game_replace(base, profiles, payoffs)
Example #42
0
def test_max_pure_profile():
    """Test max_pure_prof"""
    profiles = [[2, 0],
                [1, 1],
                [0, 2]]
    payoffs = [[3, 0],
               [4, 4],
               [0, 1]]
    game = paygame.game(2, 2, profiles, payoffs)
    prof = regret.max_pure_social_welfare(game)[1]
    assert np.all(prof == [1, 1])

    game = rsgame.empty(2, 2)
    welfare, prof = regret.max_pure_social_welfare(game)
    assert np.isnan(welfare)
    assert prof is None

    (welfare,), (prof,) = regret.max_pure_social_welfare(game, by_role=True)
    assert np.isnan(welfare)
    assert prof is None
Example #43
0
def _random_aggfn( # pylint: disable=too-many-arguments
        role_players, role_strats, functions, input_prob, weight_prob,
        role_dist):
    """Base form for structured random aggfn generation

    role_dist takes a number of functions and a number of players and returns
    an ndarray of the function values.
    """
    base = rsgame.empty(role_players, role_strats)
    inputs = _random_inputs(input_prob, base.num_strats, functions)
    weights = _random_weights(weight_prob, functions, base.num_strats)

    funcs = np.ones((functions,) + tuple(base.num_role_players + 1))
    base_shape = [functions] + [1] * base.num_roles
    for role, play in enumerate(base.num_role_players):
        role_funcs = role_dist(functions, play)
        shape = base_shape.copy()
        shape[role + 1] = play + 1
        role_funcs.shape = shape
        funcs *= role_funcs
    return aggfn.aggfn_replace(base, weights, inputs, funcs)