def main(): args = parse_args() games = args.input profiles = read(args.profiles) if not isinstance(profiles, list): profiles = [profiles] if not isinstance(games, list): games = [games] * len(profiles) regrets = [] for g, prof_list in zip(games, profiles): if not isinstance(prof_list, list): prof_list = [prof_list] regrets.append([]) for prof in prof_list: if args.SW: regrets[-1].append(social_welfare(g, prof)) elif args.NE: eqr = equilibrium_regrets(g, prof) eqr_prof = {} for r in g.roles: eqr_prof[r] = {} for s in g.strategies[r]: eqr_prof[r][s] = eqr[g.index(r),g.index(r,s)] regrets[-1].append(eqr_prof) else: regrets[-1].append(regret(g, prof)) if len(regrets) > 1: print to_JSON_str(regrets) else: print to_JSON_str(regrets[0])
def main(): args = parse_args() games = args.input profiles = read(args.profiles) if not isinstance(profiles, list): profiles = [profiles] if not isinstance(games, list): games = [games] * len(profiles) regrets = [] for g, prof_list in zip(games, profiles): if not isinstance(prof_list, list): prof_list = [prof_list] regrets.append([]) for prof in prof_list: if args.sw: regrets[-1].append(social_welfare(g, prof)) else: regrets[-1].append(regret(g, prof)) if len(regrets) > 1: print to_JSON_str(regrets) else: print to_JSON_str(regrets[0])
def parse_args(): parser = ArgumentParser() parser.add_argument("game_func", type=str, default="", choices=sorted([ \ f[:-5] for f in RG.game_functions]), help="Specifies "+\ "the function generating random base games. If "+\ "empty, the script will look for a file with "+\ "simulated game data on stdin.") parser.add_argument("noise_func", type=str, default="", choices=sorted([ \ f[:-6] for f in RG.noise_functions]), help="Noise "+\ "model to perturb sample payoffs around the base "+\ "game payoff. May only be empty if first argument "+\ "is also empty.") parser.add_argument("-game_args", type=str, nargs="*", default=[], help=\ "Arguments to pass to game_func. Usually players "+\ "and strategies.") parser.add_argument("-noise_args", type=str, nargs="*", default=[], help=\ "Arguments to pass to noise_func. Should not include"+\ "noise magnitude or number of samples.") parser.add_argument("-num_games", type=int, default=1000, help="Number "+\ "of games to generate per stdev/subsample "+\ "combination. Default: 1000") parser.add_argument("-points", type=int, default=1000, help="Number of "+\ "bootstrap resamples per equilibrium. Default: 1000") parser.add_argument("-pair", type=str, default="game", choices=["game", \ "profile", "payoff"], help="Pairing level to use for "+\ "bootstrap resampling. Default: game") parser.add_argument("-agg", type=int, default=0, help="Number of samples "+\ "to pre-aggregate. Default: 0") parser.add_argument("-stdevs", type=float, nargs="*", default=\ [.1,1.,10.,100.], help="Noise magnitude parameters "+\ "passed to the noise model. Default: .1,1,10,100") parser.add_argument("-sample_sizes", type=int, nargs="*", default=\ [5,10,20,100,200,500], help="Numbers of samples "+\ "per profile at which to test the bootstrap. "+\ "Default: 5 10 20 100 200 500") parser.add_argument("--single", action="store_true", help="Set to use "+\ "the single_sample_regret function.") parser.add_argument("--rd", action="store_true", help="Set to compute "+\ "bootstrap distributions of equilibrium movement by "+\ "replicator dynamics.") parser.add_argument("--pure", action="store_true", help="Find an compute "+\ "bootstrap regret distributions for pure-strategy "+\ "(rather than role-symmetric mixed-strategy) Nash "+\ "equilibria.") args = parser.parse_args() if args.game_func == "none": game = read(stdin) args.game_func = lambda: game args.noise_func = lambda g,s,c: game.subsample(c) else: assert args.noise_func != "none", "Must specify a noise model." game_args = [] for a in args.game_args: try: game_args.append(int(a)) except ValueError: game_args.append(float(a)) noise_args = [] for a in args.noise_args: try: noise_args.append(int(a)) except ValueError: noise_args.append(float(a)) args.game_func = partial(getattr(RG, args.game_func + "_game"), \ *game_args) noise_func = getattr(RG, args.noise_func + "_noise") args.noise_func = lambda s,c: noise_func(s,c, *noise_args) if args.agg > 0: args.noise_func = lambda s,c: pre_aggregate(args.noise_func(s,c), \ args.agg) assert not (args.rd and args.pure), "Must use mixed_nash for rd bootstrap" args.bootstrap_args = ["resample" if not args.single else "singleSample", \ [args.pair] if not args.single else [], args.points] return args
def update(self): TestbedObject.update(self) self.game = read(self.json)
def __init__(self, name, granularity="structure"): TestbedObject.__init__(self, name, "games", "name", {"granularity": \ granularity}) self.game = read(self.json)
def main(): parser = io_parser() parser.description = "Detect all complete subgames in a partial game or "+\ "extract specific subgames." parser.add_argument("mode", choices=["detect","extract"], help="If mode "+\ "is set to detect, all complete subgames will be found, and the "+\ "output will be a JSON list of role:[strategies] maps "+\ "enumerating the complete subgames. If mode is set to extract, "+\ "then the output will be a JSON representation of a game or a "+\ "list of games with the specified subsets of strategies.") parser.add_argument("-k", metavar="known_subgames", type=str, default="", \ help="In 'detect' mode: file containing known complete subgames "+\ "from a prior run. If available, this will often speed up the "+\ "clique-finding algorithm.") parser.add_argument("--full", action="store_true", help="In 'detect' "+\ "mode: setting this flag causes the script to output games "+\ "instead of role:strategy maps.") parser.add_argument("-f", metavar="strategies file", type=str, default="", \ help="In 'extract' mode: JSON file with role:[strategies] map(s) "+\ "of subgame(s) to extract. The file should have the same format "+\ "as the output of detect mode (or to extract just one subgame, "+\ "a single map instead of a list of them).") parser.add_argument("-s", type=int, nargs='*', default=[], help="In "+\ "'extract' mode: a list of strategy indices to extract. A "+\ "strategy is specified by its zero-indexed position in a list "+\ "of all strategies sorted alphabetically by role and sub-sorted "+\ "alphabetically by strategy name. For example if role r1 has "+\ "strategies s1,s2,s2 and role r2 has strategies s1,s2, then the "+\ "subgame with all but the last strategy for each role is "+\ "extracted by './Subgames.py extract -s 0 1 3'. Ignored if -f "+\ "is also specified.") args = parser.parse_args() game = args.input if args.mode == "detect": if args.k != "": known = read(args.k) else: known = [] subgames = cliques(game, known) if args.full: subgames = [subgame(game,s) for s in subgames] else: if args.f != "": strategies = read(args.f) elif len(args.s) > 0: strategies = {r:[] for r in game.roles} l = 0 i = 0 for r in game.roles: while i < len(args.s) and args.s[i] < l + \ len(game.strategies[r]): strategies[r].append(game.strategies[r][args.s[i]-l]) i += 1 l += len(game.strategies[r]) strategies = [strategies] else: raise IOError("Please specify either -f or -s for extract mode.") subgames = [subgame(game, s) for s in strategies] if len(subgames) == 1: subgames = subgames[0] print to_JSON_str(subgames)
def main(args): input_game = read(args.game) print "input game =", abspath(args.game), "\n", input_game, "\n\n" #max social welfare soc_opt_prof, soc_opt_welf = max_social_welfare(input_game) print "max social welfare =", round(soc_opt_welf, 4) print "achieved by profile =", soc_opt_prof if len(input_game.roles) > 1: for r in input_game.roles: role_opt_prof, role_opt_welf = max_social_welfare(input_game, r) print "\tbest total value for", r, "=", role_opt_welf print "\tachieved by profile =", role_opt_prof print "\n\n" #iterated elimination of dominated strategies rational_game = iterated_elimination(input_game, pure_strategy_dominance, \ conditional=1) eliminated = {r:sorted(set(input_game.strategies[r]) - set( \ rational_game.strategies[r])) for r in input_game.roles} if any(map(len, eliminated.values())): print "dominated strategies:" for r in rational_game.roles: if eliminated[r]: print r, ":", ", ".join(eliminated[r]) else: print "no dominated strategies found" #pure strategy Nash equilibrium search pure_equilibria = pure_nash(rational_game, args.r) l = len(pure_equilibria) if l > 0: print "\n" + str(len(pure_equilibria)), "pure strategy Nash " +\ "equilibri" + ("um:" if l == 1 else "a:") for i, eq in enumerate(pure_equilibria): print str(i+1) + ". regret =", round(regret(input_game, eq), 4), \ "; social welfare =", round(social_welfare(input_game,eq),4) for role in input_game.roles: print " " + role + ":", ", ".join(map(lambda pair: \ str(pair[1]) + "x " + str(pair[0]), eq[role].items())) else: print "\nno pure strategy Nash equilibria found." mrp = min_regret_profile(rational_game) print "regret =", regret(input_game, mrp) print "minimum regret pure strategy profile (regret = " + \ str(round(regret(input_game, mrp), 4)) + "; social welfare = "+\ str(round(social_welfare(input_game, mrp), 4)) + "):" for role in input_game.roles: print " " + role + ":", ", ".join(map(lambda pair: \ str(pair[1]) + "x " + str(pair[0]), mrp[role].items())) if args.sg != "": subgames = read(args.sg) print "\n\n" + str(len(subgames)), "subgame" + \ ("s" if len(subgames) > 1 else "") + "\n" else: subgames = [rational_game.strategies] #mixed strategy Nash equilibrium search for i, sg_strat in enumerate(subgames): sg = subgame(rational_game, sg_strat) if args.sg != "": print "\nsubgame "+str(i+1)+":\n", "\n".join(map(lambda x: x[0] + \ ":\n\t\t" + "\n\t\t".join(x[1]), sorted( \ sg.strategies.items()))).expandtabs(4) mixed_equilibria = mixed_nash(sg, args.r, args.d, iters=args.i, \ converge_thresh=args.c) print "\n" + str(len(mixed_equilibria)), "approximate mixed strategy"+ \ " Nash equilibri" + ("um:" if len(mixed_equilibria) == 1 \ else "a:") for j, eq in enumerate(mixed_equilibria): full_eq = translate(eq, sg, input_game) all_data = all(map(lambda p: p in input_game, neighbors(\ input_game, full_eq))) BR = {r:(list(t[0])[0] if len(t[0]) > 0 else None) for r,t in \ best_responses(input_game, full_eq).items()} reg = max(map(lambda r: regret(input_game, full_eq, \ deviation=BR[r]), input_game.roles)) print str(j+1) + ". regret ", ("=" if all_data else ">=") , round(\ reg,4), "; social welfare =", round(social_welfare(sg,eq),4) if len(sg.roles) > 1: for r in sg.roles: print "\ttotal value for", r, "=", social_welfare(sg, eq, r) support = {r:[] for r in input_game.roles} for k,role in enumerate(input_game.roles): print role + ":" for l,strategy in enumerate(input_game.strategies[role]): if full_eq[k][l] >= args.s: support[role].append(strategy) print " " + strategy + ": " + str(round(100 * \ full_eq[k][l], 2)) + "%" if args.sg != "": print "best responses:" for role in input_game.roles: deviation_support = deepcopy(support) deviation_support[role].append(BR[role]) r = regret(input_game, full_eq, role, deviation=BR[role]) print "\t" + str(role) + ": " + BR[role] + ";\tgain =", \ (round(r, 4) if not isinf(r) else "?") print "Deviation subgame " + ("explored." if subgame( \ input_game, deviation_support).isComplete() else \ "UNEXPLORED!") + "\n"