예제 #1
0
 def _checked_iterated_dominance(self, *args, **kwargs):
   reduced_game, live_actions = lp_solver.iterated_dominance(*args, **kwargs)
   if isinstance(reduced_game, pyspiel.MatrixGame):
     payoffs_shape = [2, reduced_game.num_rows(), reduced_game.num_cols()]
   else:
     payoffs_shape = list(reduced_game.shape)
   self.assertLen(live_actions, payoffs_shape[0])
   self.assertListEqual(payoffs_shape[1:], [
       np.sum(live_actions_for_player)
       for live_actions_for_player in live_actions
   ])
   return reduced_game, live_actions
예제 #2
0
def main(_):
    game = pyspiel.load_game(FLAGS.game)
    print("loaded game")

    # convert game to matrix form if it isn't already a matrix game
    if not isinstance(game, pyspiel.MatrixGame):
        game = pyspiel.extensive_to_matrix_game(game)
        num_rows, num_cols = game.num_rows(), game.num_cols()
        print("converted to matrix form with shape (%d, %d)" %
              (num_rows, num_cols))

    # use iterated dominance to reduce the space unless the solver is LP (fast)
    if FLAGS.solver != "linear":
        if FLAGS.mode == "all":
            game, _ = lp_solver.iterated_dominance(
                game, tol=FLAGS.tol, mode=lp_solver.DOMINANCE_STRICT)
            num_rows, num_cols = game.num_rows(), game.num_cols()
            print(
                "discarded strictly dominated actions yielding shape (%d, %d)"
                % (num_rows, num_cols))
        if FLAGS.mode == "one":
            game, _ = lp_solver.iterated_dominance(
                game, tol=FLAGS.tol, mode=lp_solver.DOMINANCE_VERY_WEAK)
            num_rows, num_cols = game.num_rows(), game.num_cols()
            print(
                "discarded very weakly dominated actions yielding shape (%d, %d)"
                % (num_rows, num_cols))

    # game is now finalized
    num_rows, num_cols = game.num_rows(), game.num_cols()
    row_actions = [game.row_action_name(row) for row in range(num_rows)]
    col_actions = [game.col_action_name(col) for col in range(num_cols)]
    row_payoffs, col_payoffs = utils.game_payoffs_array(game)
    pure_nash = list(
        zip(*((row_payoffs >= row_payoffs.max(0, keepdims=True) - FLAGS.tol)
              & (col_payoffs >= col_payoffs.max(1, keepdims=True) - FLAGS.tol)
              ).nonzero()))
    if pure_nash:
        print("found %d pure equilibria" % len(pure_nash))
    if FLAGS.mode == "pure":
        if not pure_nash:
            print("found no pure equilibria")
            return
        print("pure equilibria:")
        for row, col in pure_nash:
            print("payoffs %f, %f:" %
                  (row_payoffs[row, col], col_payoffs[row, col]))
            print("row action:")
            print(row_actions[row])
            print("col action:")
            print(col_actions[col])
            print("")
        return
    if FLAGS.mode == "one" and pure_nash:
        print("pure equilibrium:")
        row, col = pure_nash[0]
        print("payoffs %f, %f:" %
              (row_payoffs[row, col], col_payoffs[row, col]))
        print("row action:")
        print(row_actions[row])
        print("col action:")
        print(col_actions[col])
        print("")
        return
    for row, action in enumerate(row_actions):
        print("row action %s:" % row)
        print(action)
    print("--")
    for col, action in enumerate(col_actions):
        print("col action %s:" % col)
        print(action)
    print("--")
    if num_rows == 1 or num_cols == 1:
        equilibria = itertools.product(np.eye(num_rows), np.eye(num_cols))
    elif FLAGS.solver == "linear":
        if FLAGS.mode != "one" or (row_payoffs + col_payoffs).max() > (
                row_payoffs + col_payoffs).min() + FLAGS.tol:
            raise ValueError(
                "can't use linear solver for non-constant-sum game or "
                "for finding all optima!")
        print("using linear solver")

        def gen():
            p0_sol, p1_sol, _, _ = lp_solver.solve_zero_sum_matrix_game(
                pyspiel.create_matrix_game(row_payoffs - col_payoffs,
                                           col_payoffs - row_payoffs))
            yield (np.squeeze(p0_sol, 1), np.squeeze(p1_sol, 1))

        equilibria = gen()
    elif FLAGS.solver == "lrsnash":
        print("using lrsnash solver")
        equilibria = lrs_solve(row_payoffs, col_payoffs)
    elif FLAGS.solver == "nashpy":
        if FLAGS.mode == "all":
            print("using nashpy vertex enumeration")
            equilibria = nashpy.Game(row_payoffs,
                                     col_payoffs).vertex_enumeration()
        else:
            print("using nashpy Lemke-Howson solver")
            equilibria = lemke_howson_solve(row_payoffs, col_payoffs)
    print("equilibria:" if FLAGS.mode == "all" else "an equilibrium:")
    equilibria = iter(equilibria)
    # check that there's at least one equilibrium
    try:
        equilibria = itertools.chain([next(equilibria)], equilibria)
    except StopIteration:
        print("not found!")
    for row_mixture, col_mixture in equilibria:
        print("payoffs %f, %f for %s, %s" %
              (row_mixture.dot(row_payoffs.dot(col_mixture)),
               row_mixture.dot(
                   col_payoffs.dot(col_mixture)), row_mixture, col_mixture))
        if FLAGS.mode == "one":
            return