def test_jacobian_zeros(_): """Test that jacobian has appropriate zeros""" cgame = congestion.gen_congestion_game(3, 3, 1) _, jac = cgame.deviation_payoffs(cgame.random_mixtures()[0], jacobian=True) np.fill_diagonal(jac, 0) assert np.allclose(jac, 0), \ "deviation jacobian wasn't diagonal" cgame = congestion.gen_congestion_game(5, 4, 2) _, jac = cgame.deviation_payoffs(cgame.random_mixtures()[0], jacobian=True) ns = cgame.num_strategies[0] opp_diag = np.arange(ns - 1, ns ** 2 - 1, ns - 1) assert np.allclose(jac.flat[opp_diag], 0), \ ("jacobian with non interfering strategies didn't have appropriate " "zeros")
def test_warning_on_bad_serial(): cgame = congestion.gen_congestion_game(3, 2, 1) serial = gameio.GameSerializer(['all'], [['unserscore_fac', '0', '1']]) with pytest.warns(UserWarning): cgame.to_json(serial) with pytest.warns(UserWarning): cgame.to_str(serial)
def test_to_str(): cgame = congestion.gen_congestion_game(3, 3, 2) serial = cgame.gen_serializer() expected = ('CongestionGame:\n Players: 3\n Required Facilities: 2\n' ' Facilities: 0, 1, 2\n') assert cgame.to_str() == expected assert cgame.to_str(serial) == expected
def test_payoff_bounds(players, facilities, required): cgame = congestion.gen_congestion_game(3, 2, 1) minp = cgame.min_payoffs()[0] - EPS maxp = cgame.max_payoffs()[0] + EPS profiles = cgame.all_profiles() payoffs = np.sum(cgame.get_payoffs(profiles) * profiles, 1) assert np.all(minp <= payoffs) assert np.all(maxp >= payoffs)
def test_serial_to_base_game(players, facilities, required): """Test that reading a congestion game as a base game works""" cgame = congestion.gen_congestion_game(players, facilities, required) serial1 = cgame.gen_serializer() base1 = rsgame.BaseGame(cgame) base2, serial2 = gameio.read_base_game(cgame.to_json(serial1)) assert base1 == base2 assert serial1 == serial2
def test_json_copy(players, facilities, required): """Test that manually copying a congestion game works""" cgame1 = congestion.gen_congestion_game(players, facilities, required) cgame2, _ = congestion.read_congestion_game(cgame1.to_json()) mixes = cgame1.random_mixtures(20) for mix in mixes: dev1 = cgame1.deviation_payoffs(mix) dev2 = cgame2.deviation_payoffs(mix) assert np.allclose(dev1, dev2)
def test_manual_copy(players, facilities, required): """Test that manually copying a congestion game works""" cgame1 = congestion.gen_congestion_game(players, facilities, required) cgame2 = congestion.CongestionGame(players, required, cgame1.facility_coefs) mixes = cgame1.random_mixtures(20) for mix in mixes: dev1 = cgame1.deviation_payoffs(mix) dev2 = cgame2.deviation_payoffs(mix) assert np.allclose(dev1, dev2)
def test_deviation_payoffs(players, facilities, required): """Test that deviation payoff formulation is accurate""" cgame = congestion.gen_congestion_game(players, facilities, required) game = cgame.to_game() mixes = game.random_mixtures(20) for mix in mixes: dev, jac = cgame.deviation_payoffs(mix, jacobian=True) tdev, tjac = game.deviation_payoffs(mix, jacobian=True, assume_complete=True) assert np.allclose(dev, tdev) # We need to project the Jacobian onto the simplex gradient subspace jac -= jac.mean(-1, keepdims=True) tjac -= tjac.mean(-1, keepdims=True) assert np.allclose(jac, tjac)
def congestion_game(num_players, num_facilities, num_required, return_serial=False): """Generates a random congestion game with num_players players and nCr(f, r) strategies Congestion games are symmetric, so all players belong to one role. 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, num_facilities] -linear congestion cost ~ U[-num_required, 0] -quadratic congestion cost ~ U[-1, 0] """ game = congestion.gen_congestion_game(num_players, num_facilities, num_required) if return_serial: return game.to_game(), game.gen_serializer() else: return game.to_game()
def main(args): game = congestion.gen_congestion_game( args.num_players, args.num_facilities, args.num_required) json.dump(game.to_json(), args.output) args.output.write('\n')
def test_repr(): """Test repr""" cgame = congestion.gen_congestion_game(3, 3, 1) assert repr(cgame) == "CongestionGame(3, 1, 3)"
def test_serializer(): """Test that serializer works""" cgame = congestion.gen_congestion_game(3, 3, 1) serial = cgame.gen_serializer() serial.to_prof_json(cgame.random_mixtures()[0])
def test_nash_finding(players, facilities, required): """Test that nash works on congestion games""" cgame = congestion.gen_congestion_game(players, facilities, required) eqa = nash.mixed_nash(cgame) assert eqa.size > 0, "didn't find any equilibria"