Esempio n. 1
0
def aggfn_names(  # pylint: disable=too-many-arguments
        role_names,
        num_role_players,
        strat_names,
        action_weights,
        function_inputs,
        function_table,
        offsets=None):
    """Create an Aggfn with specified names

    Parameters
    ----------
    role_names : [str]
        The name of each role.
    num_role_players : ndarray
        The number of players for each role.
    strat_names : [[str]]
        The name of each strategy for each role.
    action_weights : ndarray
        The mapping of each function to the strategy weight for a player.
    function_inpits : ndarray
        The mask indicating which strategies are inputs to which function.
    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_names(role_names, num_role_players, strat_names),
        action_weights, function_inputs, function_table, offsets)
Esempio n. 2
0
def full_game(role_names, role_players, strat_names):
    """Return a full game"""
    base = rsgame.empty_names(
        role_names, role_players, strat_names)
    return paygame.game_replace(
        base, base.all_profiles(),
        np.zeros((base.num_all_profiles, base.num_strats)))
Esempio n. 3
0
def reduce_game(full_game, red_players):
    """Reduce a game using hierarchical reduction

    Parameters
    ----------
    full_game : Game
        The game to reduce.
    red_players : ndarray-like
        The reduced number of players for each role. This will be coerced
        into the proper shape if necessary.
    """
    red_game = rsgame.empty_names(full_game.role_names, red_players,
                                  full_game.strat_names)
    utils.check(np.all(red_game.num_role_players > 0),
                'all reduced players must be greater than zero')
    utils.check(
        np.all(full_game.num_role_players >= red_game.num_role_players),
        'all full counts must not be less than reduced counts')

    if full_game.is_empty():
        return red_game
    elif full_game.num_profiles < red_game.num_all_profiles:
        profiles = full_game.profiles()
        payoffs = full_game.payoffs()
    else:
        profiles = expand_profiles(full_game, red_game.all_profiles())
        payoffs = full_game.get_payoffs(profiles)
        valid = ~np.all(np.isnan(payoffs) | (profiles == 0), 1)
        profiles = profiles[valid]
        payoffs = payoffs[valid]

    red_profiles, mask = _common.reduce_profiles(
        full_game, red_game.num_role_players[None], profiles)
    return paygame.game_replace(red_game, red_profiles, payoffs[mask])
Esempio n. 4
0
def add_singleton_role(game, index, role_name, strat_name, num_players):
    """Add a singleton role to a game"""
    role_names = list(game.role_names)
    role_names.insert(index, role_name)
    strat_names = list(game.strat_names)
    strat_names.insert(index, [strat_name])
    role_players = np.insert(game.num_role_players, index, num_players)
    return rsgame.empty_names(role_names, role_players, strat_names)
Esempio n. 5
0
def reduce_game(full_game, red_players):  # pylint: disable=too-many-locals
    """Reduce a game using deviation preserving reduction

    Parameters
    ----------
    full_game : Game
        The game to reduce.
    red_players : ndarray-like
        The reduced number of players for each role. This will be coerced
        into the proper shape if necessary.
    """
    red_game = rsgame.empty_names(full_game.role_names, red_players,
                                  full_game.strat_names)
    utils.check(
        np.all((red_game.num_role_players > 1)
               | (full_game.num_role_players == 1)),
        'all reduced players must be greater than zero')
    utils.check(
        np.all(full_game.num_role_players >= red_game.num_role_players),
        'all full counts must not be less than reduced counts')

    if full_game.is_empty():
        return red_game
    elif full_game.num_profiles < red_game.num_all_dpr_profiles:
        full_profiles = full_game.profiles()
        full_payoffs = full_game.payoffs()
    else:
        full_profiles = expand_profiles(full_game, red_game.all_profiles())
        full_payoffs = full_game.get_payoffs(full_profiles)
        valid = ~np.all(np.isnan(full_payoffs) | (full_profiles == 0), 1)
        full_profiles = full_profiles[valid]
        full_payoffs = full_payoffs[valid]

    # Reduce
    red_profiles, red_inds, full_inds, strat_inds = _reduce_profiles(
        red_game, full_profiles, True)

    if red_profiles.size == 0:  # Empty reduction
        return red_game

    # Build mapping from payoffs to reduced profiles, and use bincount
    # to count the number of payoffs mapped to a specific location, and
    # sum the number of payoffs mapped to a specific location
    cum_inds = red_inds * full_game.num_strats + strat_inds
    payoff_vals = full_payoffs[full_inds, strat_inds]
    red_payoffs = np.bincount(cum_inds, payoff_vals,
                              red_profiles.size).reshape(red_profiles.shape)
    red_payoff_counts = np.bincount(
        cum_inds, minlength=red_profiles.size).reshape(red_profiles.shape)
    mask = red_payoff_counts > 1
    red_payoffs[mask] /= red_payoff_counts[mask]

    unknown = (red_profiles > 0) & (red_payoff_counts == 0)
    red_payoffs[unknown] = np.nan
    valid = ~np.all((red_profiles == 0) | np.isnan(red_payoffs), 1)
    return paygame.game_replace(red_game, red_profiles[valid],
                                red_payoffs[valid])
Esempio n. 6
0
def matgame_names(role_names, strat_names, payoff_matrix):
    """Create a game from a payoff matrix with names

    Parameters
    ----------
    role_names : [str]
        The name of each role.
    strat_names : [[str]]
        The name of each strategy for each role.
    payoff_matrix : ndarray-like
        The matrix mapping strategy indices to payoffs for each player.
    """
    return matgame_replace(
        rsgame.empty_names(
            role_names, np.ones(len(role_names), int), strat_names),
        payoff_matrix)
Esempio n. 7
0
def reduce_game(full_game, red_players):
    """Reduce a game using hierarchical reduction

    Parameters
    ----------
    full_game : Game
        The game to reduce.
    red_players : ndarray-like
        The reduced number of players for each role. This will be coerced
        into the proper shape if necessary.
    """
    red_game = rsgame.empty_names(
        full_game.role_names, red_players, full_game.strat_names)
    utils.check(
        np.all(red_game.num_role_players > 0),
        'all reduced players must be greater than zero')
    utils.check(
        np.all(full_game.num_role_players >= red_game.num_role_players),
        'all full counts must not be less than reduced counts')

    if full_game.is_empty():
        return red_game
    elif full_game.num_profiles < red_game.num_all_profiles:
        profiles = full_game.profiles()
        payoffs = full_game.payoffs()
    else:
        profiles = expand_profiles(
            full_game, red_game.all_profiles())
        payoffs = full_game.get_payoffs(profiles)
        valid = ~np.all(np.isnan(payoffs) | (profiles == 0), 1)
        profiles = profiles[valid]
        payoffs = payoffs[valid]

    red_profiles, mask = _common.reduce_profiles(
        full_game, red_game.num_role_players[None], profiles)
    return paygame.game_replace(red_game, red_profiles, payoffs[mask])
Esempio n. 8
0
def full_game(role_names, role_players, strat_names):
    """Return a full game"""
    base = rsgame.empty_names(role_names, role_players, strat_names)
    return paygame.game_replace(
        base, base.all_profiles(),
        np.zeros((base.num_all_profiles, base.num_strats)))
def reduce_game(full_game, red_players): # pylint: disable=too-many-locals
    """Reduce a game using deviation preserving reduction

    Parameters
    ----------
    full_game : Game
        The game to reduce.
    red_players : ndarray-like
        The reduced number of players for each role. This will be coerced
        into the proper shape if necessary.
    """
    red_game = rsgame.empty_names(
        full_game.role_names, red_players, full_game.strat_names)
    utils.check(
        np.all((red_game.num_role_players > 1) |
               (full_game.num_role_players == 1)),
        'all reduced players must be greater than zero')
    utils.check(
        np.all(full_game.num_role_players >= red_game.num_role_players),
        'all full counts must not be less than reduced counts')

    if full_game.is_empty():
        return red_game
    elif full_game.num_profiles < red_game.num_all_dpr_profiles:
        full_profiles = full_game.profiles()
        full_payoffs = full_game.payoffs()
    else:
        full_profiles = expand_profiles(
            full_game, red_game.all_profiles())
        full_payoffs = full_game.get_payoffs(full_profiles)
        valid = ~np.all(np.isnan(full_payoffs) |
                        (full_profiles == 0), 1)
        full_profiles = full_profiles[valid]
        full_payoffs = full_payoffs[valid]

    # Reduce
    red_profiles, red_inds, full_inds, strat_inds = _reduce_profiles(
        red_game, full_profiles, True)

    if red_profiles.size == 0:  # Empty reduction
        return red_game

    # Build mapping from payoffs to reduced profiles, and use bincount
    # to count the number of payoffs mapped to a specific location, and
    # sum the number of payoffs mapped to a specific location
    cum_inds = red_inds * full_game.num_strats + strat_inds
    payoff_vals = full_payoffs[full_inds, strat_inds]
    red_payoffs = np.bincount(
        cum_inds, payoff_vals, red_profiles.size).reshape(
            red_profiles.shape)
    red_payoff_counts = np.bincount(
        cum_inds, minlength=red_profiles.size).reshape(
            red_profiles.shape)
    mask = red_payoff_counts > 1
    red_payoffs[mask] /= red_payoff_counts[mask]

    unknown = (red_profiles > 0) & (red_payoff_counts == 0)
    red_payoffs[unknown] = np.nan
    valid = ~np.all((red_profiles == 0) | np.isnan(red_payoffs), 1)
    return paygame.game_replace(red_game, red_profiles[valid],
                                red_payoffs[valid])