Example #1
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))
			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])
Example #2
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])
Example #3
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
Example #4
0
	def update(self):
		TestbedObject.update(self)
		self.game = read(self.json)
Example #5
0
	def __init__(self, name, granularity="structure"):
		TestbedObject.__init__(self, name, "games", "name", {"granularity": \
				granularity})
		self.game = read(self.json)
Example #6
0
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)
Example #7
0
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"