Beispiel #1
0
def test_init():
    env = DiscreteSynchronEnvironment(
        demand=LogitDemand(price_sensitivity=1.0, outside_quality=0.0),
        agents=[Qlearning(quality=1.0, marginal_cost=0.0), Qlearning(quality=1.0, marginal_cost=0.0)],
    )
    assert max(env.monopoly_prices) > min(env.nash_prices)
    assert sum(np.greater(env.nash_prices, env.monopoly_prices)) == 0

    env = DiscreteSynchronEnvironment(
        demand=LogitDemand(price_sensitivity=1.0, outside_quality=10.0),
        agents=[Qlearning(quality=10.0, marginal_cost=5.0), Qlearning(quality=10.0, marginal_cost=1.0)],
    )
    assert max(env.monopoly_prices) > min(env.nash_prices)
    assert sum(np.greater(env.nash_prices, env.monopoly_prices)) == 0

    env = DiscreteSynchronEnvironment(
        demand=PrisonersDilemmaDemand(),
        agents=[Qlearning(quality=10.0, marginal_cost=5.0), Qlearning(quality=10.0, marginal_cost=1.0)],
        possible_prices=[2, 3],
    )
    assert (env.monopoly_prices == np.array([3, 3])).all()
    assert (env.nash_prices == np.array([2, 2])).all()

    with pytest.raises(AssertionError):
        DiscreteSynchronEnvironment(
            demand=PrisonersDilemmaDemand(),
            agents=[Qlearning(quality=10.0, marginal_cost=5.0), Qlearning(quality=10.0, marginal_cost=1.0)],
        )
def test_vector_reaction():
    assert (
        np.round(
            EquilibriumCalculator(demand=LogitDemand(price_sensitivity=0.8, outside_quality=1.0)).get_nash_equilibrium(
                [1.2, 1.0, 0.8], [1.0, 0.9, 0.8]
            )[0],
            5,
        )
        == 1.88108  # noqa W503
    )
    assert (
        np.round(
            EquilibriumCalculator(demand=LogitDemand(price_sensitivity=0.8, outside_quality=1.0)).get_nash_equilibrium(
                [1.0, 1.0], [1000.0, 10000.0]
            )[0],
            5,
        )
        > 0.0  # noqa W503
    )
    assert (
        np.round(
            EquilibriumCalculator(demand=LogitDemand(price_sensitivity=0.5, outside_quality=1.0)).get_nash_equilibrium(
                [1.0, 1.0], [1.0, 1.0],
            )[0],
            4,
        )
        == 1.5227  # noqa W503
    )
    assert (
        np.round(
            EquilibriumCalculator(
                demand=LogitDemand(price_sensitivity=0.005, outside_quality=1.0)
            ).get_nash_equilibrium([1.0], [1.0],)[0],
            4,
        )
        == 1.005  # noqa W503
    )

    def profit(price, cost=1.0, quality=1.0):
        quantity = LogitDemand(price_sensitivity=0.005, outside_quality=1.0).get_quantities((price,), (quality,))[0]
        return -1 * (price - cost) * quantity

    assert np.round(
        EquilibriumCalculator(demand=LogitDemand(price_sensitivity=0.005, outside_quality=1.0)).get_nash_equilibrium(
            [1.0], [1.0],
        )[0],
        4,
    ) == np.round(  # noqa W503
        minimize(profit, np.array([1]), method="nelder-mead", options={"xatol": 1e-8}).x, 4
    )
Beispiel #3
0
def run():
    dqn_env = DiscreteSynchronEnvironment(
        markup=0.1,
        n_periods=100,
        possible_prices=[],
        n_prices=15,
        demand=LogitDemand(outside_quality=0.0, price_sensitivity=0.25),
        history_after=50,
        agents=[
            DiffDQN(
                discount=0.95,
                learning_rate=0.001,
                decision=DecreasingEpsilonGreedy(),
                marginal_cost=1.0,
                quality=2.0,
            ),
            Qlearning(
                discount=0.95,
                learning_rate=0.125,
                decision=DecreasingEpsilonGreedy(),
                marginal_cost=1.0,
                quality=2.0,
            ),
            AlwaysDefectAgent(marginal_cost=1.0, quality=2.0),
        ],
    )
    dqn_env.play_game()
    Analyzer.analyze(dqn_env)
Beispiel #4
0
def test_play_game():
    env = DiscreteSynchronEnvironment(
        demand=LogitDemand(price_sensitivity=1.0, outside_quality=10.0),
        agents=[Qlearning(quality=10.0, marginal_cost=5.0), Qlearning(quality=10.0, marginal_cost=1.0)],
        markup=0.0,
        n_prices=10,
        n_periods=1,
    )
    env.play_game()
    assert len(env.possible_prices) == 10
    assert min(env.possible_prices) == min(env.nash_prices)
    assert max(env.possible_prices) == max(env.monopoly_prices)

    env = DiscreteSynchronEnvironment(
        demand=PrisonersDilemmaDemand(),
        agents=[Qlearning(quality=10.0, marginal_cost=5.0), Qlearning(quality=10.0, marginal_cost=1.0)],
        possible_prices=[3, 4],
        markup=0.1,
        n_prices=10,
        n_periods=1,
    )
    env.play_game()
    assert len(env.possible_prices) == 2
    assert min(env.possible_prices) == min(env.nash_prices)
    assert max(env.possible_prices) == max(env.monopoly_prices)
def test_equilibrium_calculation():
    """See Anderson & de Palma (1992) for theoretical equilibrium as outside quality goes to -inf."""
    a0 = -1000000000
    mcs = [1.0, 1.0]
    mu = 0.5
    assert (
        np.around(
            EquilibriumCalculator(demand=LogitDemand(price_sensitivity=mu, outside_quality=a0)).get_nash_equilibrium(
                mcs, mcs
            ),
            4,
        )
        == np.around(np.asarray(mcs) + (mu * len(mcs)) / (len(mcs) - 1), 4)  # noqa W503
    ).all()

    mcs = [1.0, 1.0, 1.0, 1.0]
    mu = 0.1
    assert (
        np.around(
            EquilibriumCalculator(demand=LogitDemand(price_sensitivity=mu, outside_quality=a0)).get_nash_equilibrium(
                mcs, mcs
            ),
            4,
        )
        == np.around(np.asarray(mcs) + (mu * len(mcs)) / (len(mcs) - 1), 4)  # noqa W503
    ).all()

    # more loyal consumers thus price increase
    assert (
        EquilibriumCalculator(demand=LogitDemand(price_sensitivity=0.8, outside_quality=1.0)).get_nash_equilibrium(
            mcs, mcs
        )
        >= EquilibriumCalculator(  # noqa W503
            demand=LogitDemand(price_sensitivity=0.5, outside_quality=1.0)
        ).get_nash_equilibrium(mcs, mcs)
    ).all()

    # for mu -> inf consumers become equally distributed across products
    demand = np.around(
        EquilibriumCalculator(demand=LogitDemand(price_sensitivity=10000.0, outside_quality=1.0)).get_nash_equilibrium(
            mcs, mcs
        ),
        3,
    )
    assert np.all(demand == demand[0])
def test_profit():
    assert (
        EquilibriumCalculator(demand=LogitDemand(price_sensitivity=0.5, outside_quality=1.0)).profit(
            4.0, np.array([10.0, 10.0]), np.array([2.0, 1.0]), np.array([4.0, 1.0]), 0
        )
        == 0.0  # noqa W503
    )
    assert EquilibriumCalculator(demand=LogitDemand(price_sensitivity=0.5, outside_quality=1.0)).profit(
        4.1, np.array([10.0, 10.0]), np.array([2.0, 1.0]), np.array([4.0, 1.0]), 0
    ) < EquilibriumCalculator(demand=LogitDemand(price_sensitivity=0.5, outside_quality=1.0)).profit(
        4.0, np.array([10.0, 10.0]), np.array([2.0, 1.0]), np.array([4.0, 1.0]), 0
    )
    assert (
        EquilibriumCalculator(demand=PrisonersDilemmaDemand()).profit(
            5.0, np.array([10.0, 10.0]), np.array([2.0, 1.0]), np.array([4.0, 1.0]), 0
        )
        == -1.0  # noqa W503
    )
Beispiel #7
0
def test_environment_advanced_qlearning():
    test_1 = DiscreteSynchronEnvironment(
        n_periods=10000,
        possible_prices=[2, 3],
        demand=LogitDemand(),
        agents=[
            Qlearning(discount=0.95, learning_rate=0.3, decision=EpsilonGreedy(eps=0.1)),
            Qlearning(
                discount=0.95, learning_rate=0.3, marginal_cost=4.0, quality=5.0, decision=EpsilonGreedy(eps=0.1)
            ),
            AlwaysDefectAgent(marginal_cost=0.1),
        ],
    )

    assert test_1.play_game()
Beispiel #8
0
def test_logit_demand():
    assert all(q > 0.0
               for q in LogitDemand().get_quantities((0.1, 0.3, 10.4), (
                   0.5, 0.5, 0.5))), "Negative quantities in logit demand"
    assert (
        LogitDemand().get_quantities(
            (1, 2), (3, 2))[0] > LogitDemand().get_quantities((1, 2),
                                                              (3, 2))[1]
    ), "First product should be bought more often than the second (is cheaper and better quality)"
    assert (
        LogitDemand().get_quantities(
            (1, 1), (3, 2))[0] > LogitDemand().get_quantities((1, 1),
                                                              (3, 2))[1]
    ), "First product should be bought more often than the second (better quality)"
    assert (
        LogitDemand().get_quantities(
            (1, 2), (1, 1))[0] > LogitDemand().get_quantities((1, 2),
                                                              (1, 1))[1]
    ), "First product should be bought more often than the second (cheaper)"
def test_reaction_function():
    assert (
        EquilibriumCalculator(demand=LogitDemand(price_sensitivity=0.5, outside_quality=1.0)).reaction_function(
            np.array([10.0, 10.0]), np.array([1.0, 1.0]), np.array([1.0, 1.0]), 0
        )
        <= 10.0  # noqa W503
    )

    assert EquilibriumCalculator(demand=LogitDemand(price_sensitivity=0.5, outside_quality=1.0)).reaction_function(
        np.array([10.0, 10.0]), np.array([2.0, 1.0]), np.array([4.0, 1.0]), 0
    ) == EquilibriumCalculator(demand=LogitDemand(price_sensitivity=0.5, outside_quality=1.0)).reaction_function(
        np.array([10.0, 10.0]), np.array([1.0, 2.0]), np.array([1.0, 4.0]), 1
    )

    best_response = EquilibriumCalculator(
        demand=LogitDemand(price_sensitivity=0.5, outside_quality=1.0)
    ).reaction_function(np.array([10.0, 10.0]), np.array([2.0, 1.0]), np.array([4.0, 1.0]), 0)
    assert EquilibriumCalculator(demand=LogitDemand(price_sensitivity=0.5, outside_quality=1.0)).profit(
        best_response, np.array([10.0, 10.0]), np.array([1.0, 2.0]), np.array([1.0, 1.0]), 1
    ) > EquilibriumCalculator(demand=LogitDemand(price_sensitivity=0.5, outside_quality=1.0)).profit(
        best_response - 0.001, np.array([10.0, 10.0]), np.array([1.0, 2.0]), np.array([1.0, 1.0]), 1
    )
 def profit(price, cost=1.0, quality=1.0):
     quantity = LogitDemand(price_sensitivity=0.005, outside_quality=1.0).get_quantities((price,), (quality,))[0]
     return -1 * (price - cost) * quantity
Beispiel #11
0
def test_prepare_profit_calculation():
    env = DiscreteSynchronEnvironment(
        n_periods=1, agents=[Qlearning(), Qlearning(), Qlearning(), Qlearning()], demand=LogitDemand(),
    )
    env.play_game()
    nash_profits, monopoly_profits = analyzer.prepare_profit_calculation(env)
    assert len(nash_profits) == len(env.agents)
    assert len(monopoly_profits) == len(env.agents)
    assert (nash_profits < monopoly_profits).all()