def plot_reactive_utility(opponents,
                          best_response_player=False,
                          filename=False):
    p_1, p_2 = sym.symbols("p_1, p_2")
    p = (p_1, p_2, p_1, p_2)

    p_one, p_two = np.linspace(0, 1, 50), np.linspace(0, 1, 50)
    utility = -opt_mo.tournament_utility(p, opponents)

    expr = sym.lambdify((p_1, p_2), utility.simplify())

    plt.figure()
    X, Y = np.meshgrid(p_one, p_two)
    Z = expr(X, Y)

    plot = plt.contourf(X, Y, Z), plt.colorbar()
    if best_response_player:
        plt.plot(
            best_response_player[0],
            best_response_player[1],
            marker="x",
            color="r",
            markersize=20,
            markeredgewidth=5,
        )
    plt.ylabel(r"$p_2$"), plt.xlabel(r"$p_1$")

    if filename:
        plt.savefig(filename, bbox_inches="tight")

    return plot
def get_candinate_reactive_best_responses(opponents):
    """
    Creates a set of possible optimal solutions.
    """
    p_1, p_2 = sym.symbols("p_1, p_2")
    utility = opt_mo.tournament_utility((p_1, p_2, p_1, p_2), opponents)

    derivatives = [sym.diff(utility, i) for i in [p_1, p_2]]
    derivatives = [expr.factor() for expr in derivatives]

    fractions = [sym.fraction(expr) for expr in derivatives]
    num, den = [[expr for expr in fraction] for fraction in zip(*fractions)]

    candinate_roots_p_one = _roots_using_eliminator_method(num, p_1, p_2)

    candinate_roots_p_two = set()
    if len(candinate_roots_p_one) > 0:
        candinate_roots_p_two.update(
            _roots_solving_system_of_singel_unknown(num, p_2,
                                                    candinate_roots_p_one,
                                                    p_1))

    for p_one in [0, 1]:
        coeffs = sym.Poly(num[1].subs({p_1: p_one}), p_2).all_coeffs()
        roots = _roots_in_bound(coeffs)
        candinate_roots_p_two.update(roots)

    candinate_set = candinate_roots_p_one | candinate_roots_p_two | set([0, 1])
    return candinate_set
Exemple #3
0
def get_evolutionary_best_response(
        opponents,
        best_response_function,
        tol=10**-5,
        initial=np.array([1, 1, 1, 1]),
        K=1,
):
    """
    This implements the best response dynamics algorithm (Algorithm 1) in the
    manuscript.

    Given a set of opponents it repeatedly finds the best response to the
    opponents including a `K` self interactions.

    In some cases a single strategy will not be found but a cycle will appear.
    The best response strategy is the strategy in the cycle that achieves the
    highest utility.

    In the edge case that the utilities of all the strategies in the cycle are
    NaN, the best response strategy is the first strategy in the cycle.
    """

    history = [initial]
    best_response = best_response_function(opponents + history * K)
    history.append(best_response)

    _, repeat_length = get_repeat_cycle_and_length(history, tol=tol)
    while repeat_length >= float("inf"):

        best_response = best_response_function(opponents + [history[-1]] * K)
        print("Next generation.")
        history.append(best_response)
        cycle, repeat_length = get_repeat_cycle_and_length(history, tol=tol)

    utilities = [
        opt_mo.tournament_utility(player, opponents + [player] * K)
        for player in cycle
    ]

    if all(np.isnan(utilities)):
        best_response = cycle[0]
    else:
        best_response = cycle[utilities.index(np.nanmax(utilities))]

    return best_response, history, repeat_length
def test_tournament_utility_against_cooperator_defector():
    q = (1, 1, 1, 1)
    z = (0, 0, 0, 0)
    assert opt_mo.tournament_utility((0, 0, 0, 0), [q, z]) == 3
    assert opt_mo.tournament_utility((1, 1, 1, 1), [q, z]) == 1.5
def test_tournament_utility_against_cooperators():
    q = (1, 1, 1, 1)
    z = (1, 1, 1, 1)
    assert opt_mo.tournament_utility((0, 0, 0, 0), [q, z]) == 5
    assert opt_mo.tournament_utility((1, 1, 1, 1), [q, z]) == 3
def test_tournament_utility_against_defectors():
    q = (0, 0, 0, 0)
    z = (0, 0, 0, 0)
    assert opt_mo.tournament_utility((0, 0, 0, 0), [q, z]) == 1
    assert opt_mo.tournament_utility((1, 1, 1, 1), [q, z]) == 0
def reactive_utility(p, opponents):
    utility = opt_mo.tournament_utility((p[0], p[1], p[0], p[1]), opponents)

    return utility
def get_argmax(opponents, solution_set):
    solutions = [(p_1, p_2,
                  opt_mo.tournament_utility((p_1, p_2, p_1, p_2), opponents))
                 for p_1, p_2 in itertools.product(solution_set, repeat=2)]
    return max(solutions, key=lambda item: item[-1])