def DeviationPreservingReduction(game, players={}): if not players: return TwinsReduction(game) DPR_game = Game(game.roles, players, game.strategies) for reduced_profile in DPR_game.allProfiles(): try: role_payoffs = {} for role in game.roles: role_payoffs[role] = [] for s in reduced_profile[role]: full_profile = {} for r in game.roles: if r == role: opp_prof = reduced_profile.asDict()[r] opp_prof[s] -= 1 full_profile[r] = FullGameProfile(opp_prof, \ game.players[r] - 1) full_profile[r][s] += 1 else: full_profile[r] = FullGameProfile(reduced_profile[\ r], game.players[r]) role_payoffs[r].append(payoff_data(s, reduced_profile[r\ ][s], game.getPayoff(Profile(full_profile), r, s))) DPR_game.addProfile(role_payoffs) except KeyError: continue return DPR_game
def congestion_game(N, facilities, required): """ Generates random congestion games with N players and nCr(f,r) strategies. Congestion games are symmetric, so all players belong to role All. Each strategy is a subset of size #required among the size #facilities set of available facilities. Payoffs for each strategy are summed over facilities. Each facility's payoff consists of three components: -constant ~ U[0,#facilities] -linear congestion cost ~ U[-#required,0] -quadratic congestion cost ~ U[-1,0] """ roles = ["All"] players = {"All": N} strategies = {"+".join(["f" + str(f) for f in strat]): strat for strat in combinations(range(facilities), required)} facility_values = [array([U(facilities), U(-required), U(-1)]) for __ in range(facilities)] g = Game(roles, players, {"All": strategies.keys()}) for prof in g.allProfiles(): payoffs = [] useage = [0] * facilities for strat, count in prof["All"].items(): for facility in strategies[strat]: useage[facility] += count for strat, count in prof["All"].items(): payoffs.append( PayoffData(strat, count, [sum(useage[f] ** arange(3) * facility_values[f]) for f in strategies[strat]]) ) g.addProfile({"All": payoffs}) return g
def HierarchicalReduction(game, players={} ): if not players: players = {r : game.players[r] / 2 for r in game.roles} HR_game = Game(game.roles, players, game.strategies) for reduced_profile in HR_game.allProfiles(): try: full_profile = Profile({r:FullGameProfile(reduced_profile[r], \ game.players[r]) for r in game.roles}) HR_game.addProfile({r:[payoff_data(s, reduced_profile[r][s], \ game.getPayoff(full_profile, r, s)) for s in \ full_profile[r]] for r in full_profile}) except KeyError: continue return HR_game
def DPR_profiles(game, players={}): """Returns the profiles from game that contribute to the DPR game.""" if not players: players = {r:2 for r in game.roles} elif len(game.roles) == 1 and isinstance(players, int): players = {game.roles[0]:players} elif isinstance(players, list): players = dict(zip(game.roles, players)) DPR_game = Game(game.roles, players, game.strategies) profiles = [] for DPR_prof in DPR_game.allProfiles(): for r in game.roles: for s in DPR_prof[r]: full_prof = full_prof_DPR(DPR_prof, r, s, game.players) profiles.append(full_prof) return profiles
def Subgame(game, strategies={}): """ Creates a game with a subset each role's strategies. default settings result in a subgame with no strategies """ if not strategies: strategies = {r:[] for r in game.roles} sg = Game(game.roles, game.players, strategies) if sg.size <= len(game): for p in sg.allProfiles(): if p in game: sg.addProfile({r:[payoff_data(s, p[r][s], \ game.getPayoff(p,r,s)) for s in p[r]] for r in p}) else: for p in game: if all([all([s in sg.strategies[r] for s in p[r]]) for r in p]): sg.addProfile({r:[payoff_data(s, p[r][s], \ game.getPayoff(p,r,s)) for s in p[r]] for r in p}) return sg
def DPR_profiles(game, players={}): if not players: players = {r:2 for r in game.roles} DPR_game = Game(game.roles, players, game.strategies) profiles = [] for reduced_profile in DPR_game.allProfiles(): for role in game.roles: for s in reduced_profile[role]: full_profile = {} for r in game.roles: if r == role: opp_prof = reduced_profile.asDict()[r] opp_prof[s] -= 1 full_profile[r] = FullGameProfile(opp_prof, \ game.players[r] - 1) full_profile[r][s] += 1 else: full_profile[r] = FullGameProfile(reduced_profile[\ r], game.players[r]) profiles.append(Profile(full_profile)) return profiles
def SubgameAvailable(game, strategies = {}): sg = Game(game.roles, game.players, strategies) for p in sg.allProfiles(): if p not in game: return False return True