示例#1
0
    def nearby_profs(self, prof, num_devs):
        """Returns profiles reachable by at most num_devs deviations"""
        # XXX this is the bottleneck for gpgame.neighbor_EVs. It seems like
        # there should be some clever way to speed it up.
        assert num_devs >= 0
        dev_players = utils.acomb(self.num_roles, num_devs, True)
        mask = np.all(dev_players <= self.num_players, 1)
        dev_players = dev_players[mask]
        supp = prof > 0
        sub = subgame.subgame(rsgame.BaseGame(self), supp)

        profs = [prof[None]]
        for players in dev_players:
            to_dev_profs = rsgame.BaseGame(
                players, self.num_strategies).all_profiles()
            from_dev_profs = subgame.translate(
                rsgame.BaseGame(players, sub.num_strategies).all_profiles(),
                supp)
            before_devs = prof - from_dev_profs
            before_devs = before_devs[np.all(before_devs >= 0, 1)]
            before_devs = utils.unique_axis(before_devs)
            nearby = before_devs[:, None] + to_dev_profs
            nearby.shape = (-1, self.num_role_strats)
            profs.append(utils.unique_axis(nearby))
        profs = np.concatenate(profs)
        return utils.unique_axis(profs)
示例#2
0
def test_acomb():
    actual = utils.acomb(5, 0)
    assert actual.shape == (1, 5)
    assert not actual.any()

    actual = utils.acomb(5, 5)
    assert actual.shape == (1, 5)
    assert actual.all()

    actual = utils.acomb(6, 4)
    expected = np.zeros_like(actual)
    for i, inds in enumerate(itertools.combinations(range(6), 4)):
        expected[i, inds] = True
    assert array_set_equals(actual, expected)

    actual = utils.acomb(6, 4, True)
    expected = np.zeros_like(actual)
    for i, inds in enumerate(map(list, itertools.combinations_with_replacement(
            range(6), 4))):
        np.add.at(expected[i], inds, 1)
    assert array_set_equals(actual, expected)
示例#3
0
def test_acomb():
    """Test acomb"""
    actual = utils.acomb(5, 0)
    assert actual.shape == (1, 5)
    assert not actual.any()

    actual = utils.acomb(5, 5)
    assert actual.shape == (1, 5)
    assert actual.all()

    actual = utils.acomb(6, 4)
    expected = np.zeros_like(actual)
    for i, inds in enumerate(itertools.combinations(range(6), 4)):
        expected[i, inds] = True
    assert array_set_equals(actual, expected)

    actual = utils.acomb(6, 4, True)
    expected = np.zeros_like(actual)
    for i, inds in enumerate(
            map(list, itertools.combinations_with_replacement(range(6), 4))):
        np.add.at(expected[i], inds, 1)
    assert array_set_equals(actual, expected)
示例#4
0
    def grid_mixtures(self, num_points):
        """Returns all of the mixtures in a grid with n points

        Arguments
        ---------
        num_points : int > 1
            The number of points to have along one dimensions
        """
        assert num_points > 1, "Must have at least two points on a dimensions"
        role_mixtures = [utils.acomb(num_strats, num_points - 1, True) /
                         (num_points - 1)
                         for num_strats in self.num_strategies]
        return utils.acartesian2(*role_mixtures)
示例#5
0
def test_acomb():
    actual = utils.acomb(5, 0)
    assert actual.shape == (1, 5)
    assert not actual.any()

    actual = utils.acomb(5, 5)
    assert actual.shape == (1, 5)
    assert actual.all()

    actual = utils.acomb(6, 4)
    expected = np.zeros_like(actual)
    for i, inds in enumerate(itertools.combinations(range(6), 4)):
        expected[i, inds] = True
    assert np.setxor1d(utils.axis_to_elem(actual),
                       utils.axis_to_elem(expected)).size == 0

    actual = utils.acomb(6, 4, True)
    expected = np.zeros_like(actual)
    for i, inds in enumerate(map(list, itertools.combinations_with_replacement(
            range(6), 4))):
        np.add.at(expected[i], inds, 1)
    assert np.setxor1d(utils.axis_to_elem(actual),
                       utils.axis_to_elem(expected)).size == 0
示例#6
0
def congestion(num_players, num_facilities, num_required, degree=2,
               coef_dist=lambda d: -np.random.exponential(10. ** (1 - d))):
    """Generate a congestion game

    Parameters
    ----------
    num_players : int
    num_facilities : int
    num_required : int
    degree : int, optional
        Degree of payoff polynomials
    coef_dist : f(int) -> float, optional
        Numpy compatible function for generating random coefficients
        conditioned on degree. Leading degree must be negative to generate a
        true congestion game.
    """
    function_inputs = utils.acomb(num_facilities, num_required)
    table_dist = random_poly_dist(coef_dist, np.insert(np.zeros(degree), 2, 1))
    functions = table_dist((num_facilities, num_players + 1))
    return aggfn.aggfn(num_players, function_inputs.shape[0],
                       function_inputs.T, function_inputs, functions)
示例#7
0
def congestion(num_players, num_facilities, num_required, *, degree=2):
    """Generate a congestion game

    A congestion game is a symmetric game, where there are a given number of
    facilities, and each player must choose to use some amount of them. The
    payoff for each facility decreases as more players use it, and a players
    utility is the sum of the utilities for every facility.

    In this formulation, facility payoffs are random polynomials of the number
    of people using said facility.

    Parameters
    ----------
    num_players : int > 1
        The number of players.
    num_facilities : int > 1
        The number of facilities.
    num_required : 0 < int < num_facilities
        The number of required facilities.
    degree : int > 0, optional
        Degree of payoff polynomials.
    """
    utils.check(num_players > 1, 'must have more than one player')
    utils.check(num_facilities > 1, 'must have more than one facility')
    utils.check(
        0 < num_required < num_facilities,
        'must require more than zero but less than num_facilities')
    utils.check(degree > 0, 'degree must be greater than zero')

    function_inputs = utils.acomb(num_facilities, num_required)
    functions = -_random_monotone_polynomial(num_facilities, num_players,
                                             degree)

    facs = tuple(utils.prefix_strings('', num_facilities))
    strats = tuple('_'.join(facs[i] for i, m in enumerate(mask) if m)
                   for mask in function_inputs)
    return aggfn.aggfn_names(
        ['all'], num_players, [strats], function_inputs.T, function_inputs,
        functions)
示例#8
0
 def all_profiles(self):
     """Return all profiles"""
     role_arrays = [utils.acomb(n_strats, players, True)
                    for n_strats, players
                    in zip(self.num_strategies, self.num_players)]
     return utils.acartesian2(*role_arrays)