Best Python code snippet using autotest_python
alpha_rank.py
Source:alpha_rank.py
...315 """Gets Markov transition matrix for multipopulation games."""316 num_strats_per_population = utils.get_num_strats_per_population(317 payoff_tables, payoffs_are_hpt_format318 )319 num_profiles = utils.get_num_profiles(num_strats_per_population)320 eta = 1.0 / (np.sum(num_strats_per_population - 1))321 c = np.zeros((num_profiles, num_profiles))322 rhos = np.zeros((num_profiles, num_profiles))323 for id_row_profile in range(num_profiles):324 row_profile = utils.get_strat_profile_from_id(325 num_strats_per_population, id_row_profile326 )327 next_profile_gen = utils.get_valid_next_profiles(328 num_strats_per_population, row_profile329 )330 for index_population_that_changed, col_profile in next_profile_gen:331 id_col_profile = utils.get_id_from_strat_profile(332 num_strats_per_population, col_profile333 )334 if use_inf_alpha:335 payoff_col = _get_payoff(336 payoff_tables[index_population_that_changed],337 payoffs_are_hpt_format,338 col_profile,339 k=index_population_that_changed,340 )341 payoff_row = _get_payoff(342 payoff_tables[index_population_that_changed],343 payoffs_are_hpt_format,344 row_profile,345 k=index_population_that_changed,346 )347 if np.isclose(payoff_col, payoff_row, atol=1e-14):348 c[id_row_profile, id_col_profile] = eta * 0.5349 elif payoff_col > payoff_row:350 # Transition to col strategy since its payoff is higher than row351 # strategy, but remove some small amount of mass, inf_alpha_eps, to352 # keep the chain irreducible353 c[id_row_profile, id_col_profile] = eta * (1 - inf_alpha_eps)354 else:355 # Transition with very small probability356 c[id_row_profile, id_col_profile] = eta * inf_alpha_eps357 else:358 rhos[id_row_profile, id_col_profile] = _get_rho_sr_multipop(359 payoff_table_k=payoff_tables[index_population_that_changed],360 payoffs_are_hpt_format=payoffs_are_hpt_format,361 k=index_population_that_changed,362 m=m,363 r=col_profile,364 s=row_profile,365 alpha=alpha,366 )367 c[id_row_profile, id_col_profile] = (368 eta * rhos[id_row_profile, id_col_profile]369 )370 # Special case of self-transition371 c[id_row_profile, id_row_profile] = 1 - sum(c[id_row_profile, :])372 return c, rhos373def _get_stationary_distr(c):374 """Gets stationary distribution of transition matrix c."""375 eigenvals, left_eigenvecs, _ = la.eig(c, left=True, right=True)376 mask = abs(eigenvals - 1.0) < 1e-10377 left_eigenvecs = left_eigenvecs[:, mask]378 num_stationary_eigenvecs = np.shape(left_eigenvecs)[1]379 if num_stationary_eigenvecs != 1:380 raise ValueError(381 "Expected 1 stationary distribution, but found %d"382 % num_stationary_eigenvecs383 )384 left_eigenvecs *= 1.0 / sum(left_eigenvecs)385 return left_eigenvecs.real.flatten()386def print_results(387 payoff_tables, payoffs_are_hpt_format, rhos=None, rho_m=None, c=None, pi=None388):389 """Prints the finite-population analysis results."""390 print("Payoff tables:\n")391 if payoffs_are_hpt_format:392 for payoff_table in payoff_tables:393 print(payoff_table())394 else:395 print(payoff_tables)396 if rho_m is not None:397 print("\nNeutral fixation probability (rho_m):\n", rho_m)398 if rhos is not None and rho_m is not None:399 print(400 "\nFixation probability matrix (rho_{r,s}/rho_m):\n",401 np.around(rhos / rho_m, decimals=2),402 )403 if c is not None:404 print("\nMarkov transition matrix (c):\n", np.around(c, decimals=2))405 if pi is not None:406 print("\nStationary distribution (pi):\n", pi)407def sweep_pi_vs_epsilon(408 payoff_tables,409 strat_labels=None,410 warm_start_epsilon=None,411 visualize=False,412 return_epsilon=False,413 min_iters=10,414 max_iters=100,415 min_epsilon=1e-14,416 num_strats_to_label=10,417 legend_sort_clusters=False,418):419 """Computes infinite-alpha distribution for a range of perturbations.420 The range of response graph perturbations is defined in epsilon_list.421 Note that min_iters and max_iters is necessary as it may sometimes appear the422 stationary distribution has converged for a game in the first few iterations,423 where in reality a sufficiently smaller epsilon is needed for the distribution424 to first diverge, then reconverge. This behavior is dependent on both the425 payoff structure and bounds, so the parameters min_iters and max_iters can be426 used to fine-tune this.427 Args:428 payoff_tables: List of game payoff tables, one for each agent identity.429 Each payoff_table may be either a numpy array, or a430 _PayoffTableInterface object.431 strat_labels: Human-readable strategy labels. See get_strat_profile_labels()432 in utils.py for formatting details.433 warm_start_epsilon: Initial value of epsilon to use.434 visualize: Plot the sweep results.435 return_epsilon: Whether to return the final epsilon used.436 min_iters: the minimum number of sweep iterations.437 max_iters: the maximum number of sweep iterations.438 min_epsilon: the minimum value of epsilon to be tested, at which point the439 sweep terminates (if not converged already).440 num_strats_to_label: Number of strats to label in legend441 legend_sort_clusters: If true, strategies in the same cluster are sorted in442 the legend according to orderings for earlier alpha values. Primarily for443 visualization purposes! Rankings for lower alpha values should be444 interpreted carefully.445 Returns:446 pi: AlphaRank stationary distribution.447 epsilon: The AlphaRank transition matrix noise level resulting from sweep.448 """449 payoffs_are_hpt_format = utils.check_payoffs_are_hpt(payoff_tables)450 num_populations = len(payoff_tables)451 num_strats_per_population = utils.get_num_strats_per_population(452 payoff_tables, payoffs_are_hpt_format453 )454 if num_populations == 1:455 num_profiles = num_strats_per_population[0]456 else:457 num_profiles = utils.get_num_profiles(num_strats_per_population)458 assert (459 strat_labels is None460 or isinstance(strat_labels, dict)461 or (len(strat_labels) == num_profiles)462 )463 pi_list = np.empty((num_profiles, 0))464 pi, alpha, m = None, None, None # Unused in infinite-alpha regime465 epsilon_list = []466 epsilon_pi_hist = {}467 num_iters = 0468 epsilon_mult_factor = 0.5469 alpharank_succeeded_once = False470 if warm_start_epsilon is not None:471 epsilon = warm_start_epsilon472 else:473 epsilon = 0.5474 while True:475 try:476 pi_prev = pi477 _, _, pi, _, _ = compute(478 payoff_tables,479 m=m,480 alpha=alpha,481 use_inf_alpha=True,482 inf_alpha_eps=epsilon,483 )484 epsilon_pi_hist[epsilon] = pi485 # Stop when pi converges486 if num_iters > min_iters and np.allclose(pi, pi_prev):487 break488 epsilon *= epsilon_mult_factor489 num_iters += 1490 alpharank_succeeded_once = True491 assert num_iters < max_iters, (492 "Alpharank stationary distr. not found"493 "after {} iterations of pi_vs_epsilon"494 "sweep".format(num_iters)495 )496 except ValueError as _:497 print("Error: ", _, epsilon, min_epsilon)498 # Case where epsilon has been decreased beyond desirable limits but no499 # distribution found.500 assert epsilon >= min_epsilon, (501 "AlphaRank stationary distr. not found &" "epsilon < min_epsilon."502 )503 # Case where epsilon >= min_epsilon, but still small enough that it causes504 # causes exceptions due to precision issues. So increase it.505 epsilon /= epsilon_mult_factor506 # Case where alpharank_succeeded_once (i.e., epsilon_list and pi_list have507 # at least one entry), and a) has not converged yet and b) failed on this508 # instance due to epsilon being too small. I.e., the rate of decreasing509 # of epsilon is too high.510 if alpharank_succeeded_once:511 epsilon_mult_factor = (epsilon_mult_factor + 1.0) / 2.0512 epsilon *= epsilon_mult_factor513 epsilon_list, pi_list = zip(514 *[515 (epsilon, epsilon_pi_hist[epsilon])516 for epsilon in sorted(epsilon_pi_hist.keys(), reverse=True)517 ]518 )519 pi_list = np.asarray(pi_list)520 if visualize:521 if strat_labels is None:522 strat_labels = utils.get_strat_profile_labels(523 payoff_tables, payoffs_are_hpt_format524 )525 alpharank_visualizer.plot_pi_vs_alpha(526 pi_list.T,527 epsilon_list,528 num_populations,529 num_strats_per_population,530 strat_labels,531 num_strats_to_label=num_strats_to_label,532 legend_sort_clusters=legend_sort_clusters,533 xlabel=r"Infinite-AlphaRank Noise $\epsilon$",534 )535 if return_epsilon:536 return pi_list[-1], epsilon_list[-1]537 else:538 return pi_list[-1]539def sweep_pi_vs_alpha(540 payoff_tables,541 strat_labels=None,542 warm_start_alpha=None,543 visualize=False,544 return_alpha=False,545 m=50,546 rtol=1e-5,547 atol=1e-8,548 num_strats_to_label=10,549 legend_sort_clusters=False,550):551 """Computes stationary distribution, pi, for range of selection intensities.552 The range of selection intensities is defined in alpha_list and corresponds553 to the temperature of the Fermi selection function.554 Args:555 payoff_tables: List of game payoff tables, one for each agent identity. Each556 payoff_table may be either a numpy array, or a _PayoffTableInterface557 object.558 strat_labels: Human-readable strategy labels. See get_strat_profile_labels()559 in utils.py for formatting details.560 warm_start_alpha: Initial value of alpha to use.561 visualize: Plot the sweep results.562 return_alpha: Whether to return the final alpha used.563 m: AlphaRank population size.564 rtol: The relative tolerance parameter for np.allclose calls.565 atol: The absolute tolerance parameter for np.allclose calls.566 num_strats_to_label: Number of strats to label in legend567 legend_sort_clusters: If true, strategies in the same cluster are sorted in568 the legend according to orderings for earlier alpha values. Primarily for569 visualization purposes! Rankings for lower alpha values should be570 interpreted carefully.571 Returns:572 pi: AlphaRank stationary distribution.573 alpha: The AlphaRank selection-intensity level resulting from sweep.574 """575 payoffs_are_hpt_format = utils.check_payoffs_are_hpt(payoff_tables)576 num_populations = len(payoff_tables)577 num_strats_per_population = utils.get_num_strats_per_population(578 payoff_tables, payoffs_are_hpt_format579 )580 if num_populations == 1:581 num_profiles = num_strats_per_population[0]582 else:583 num_profiles = utils.get_num_profiles(num_strats_per_population)584 assert (585 strat_labels is None586 or isinstance(strat_labels, dict)587 or (len(strat_labels) == num_profiles)588 )589 pi_list = np.empty((num_profiles, 0))590 alpha_list = []591 num_iters = 0592 alpha_mult_factor = 2.0593 if warm_start_alpha is not None:594 alpha = warm_start_alpha595 alpharank_succeeded_once = False596 else:597 alpha = 1e-4 # Reasonable default for most games, can be user-overridden598 while 1:599 try:600 _, _, pi, _, _ = compute(payoff_tables, alpha=alpha, m=m)601 pi_list = np.append(pi_list, np.reshape(pi, (-1, 1)), axis=1)602 alpha_list.append(alpha)603 # Stop when pi converges604 if num_iters > 0 and np.allclose(pi, pi_list[:, num_iters - 1], rtol, atol):605 break606 alpha *= alpha_mult_factor607 num_iters += 1608 alpharank_succeeded_once = True609 except ValueError as _:610 if warm_start_alpha is not None and not alpharank_succeeded_once:611 # When warm_start_alpha is used, there's a chance that612 # the initial warm_start_alpha is too large and causes exceptions due to613 # the Markov transition matrix being reducible. So keep decreasing until614 # a single success occurs.615 alpha /= 2616 elif not np.allclose(pi_list[:, -1], pi_list[:, -2], rtol, atol):617 # Sweep stopped due to multiple stationary distributions, but pi had618 # not converged due to the alpha scaling being too large.619 alpha /= alpha_mult_factor620 alpha_mult_factor = (alpha_mult_factor + 1.0) / 2.0621 alpha *= alpha_mult_factor622 else:623 break624 if visualize:625 if strat_labels is None:626 strat_labels = utils.get_strat_profile_labels(627 payoff_tables, payoffs_are_hpt_format628 )629 alpharank_visualizer.plot_pi_vs_alpha(630 pi_list.T,631 alpha_list,632 num_populations,633 num_strats_per_population,634 strat_labels,635 num_strats_to_label=num_strats_to_label,636 legend_sort_clusters=legend_sort_clusters,637 )638 if return_alpha:639 return pi, alpha640 else:641 return pi642def compute_and_report_alpharank(643 payoff_tables, m=50, alpha=100, verbose=False, num_top_strats_to_print=8644):645 """Computes and visualizes Alpha-Rank outputs.646 Args:647 payoff_tables: List of game payoff tables, one for each agent identity. Each648 payoff_table may be either a numpy array, or a _PayoffTableInterface649 object.650 m: Finite population size.651 alpha: Fermi distribution temperature parameter.652 verbose: Set to True to print intermediate results.653 num_top_strats_to_print: Number of top strategies to print.654 Returns:655 pi: AlphaRank stationary distribution/rankings.656 """657 payoffs_are_hpt_format = utils.check_payoffs_are_hpt(payoff_tables)658 rhos, rho_m, pi, _, _ = compute(payoff_tables, m=m, alpha=alpha)659 strat_labels = utils.get_strat_profile_labels(payoff_tables, payoffs_are_hpt_format)660 if verbose:661 print_results(payoff_tables, payoffs_are_hpt_format, pi=pi)662 utils.print_rankings_table(663 payoff_tables,664 pi,665 strat_labels,666 num_top_strats_to_print=num_top_strats_to_print,667 )668 m_network_plotter = alpharank_visualizer.NetworkPlot(669 payoff_tables, rhos, rho_m, pi, strat_labels, num_top_profiles=8670 )671 m_network_plotter.compute_and_draw_network()672 # print(strat_labels)673 return pi674def compute(675 payoff_tables,676 m=50,677 alpha=100,678 use_local_selection_model=True,679 verbose=False,680 use_inf_alpha=False,681 inf_alpha_eps=0.01,682):683 """Computes the finite population stationary statistics.684 Args:685 payoff_tables: List of game payoff tables, one for each agent identity. Each686 payoff_table may be either a numpy array, or a _PayoffTableInterface687 object.688 m: Finite population size.689 alpha: Fermi distribution temperature parameter.690 use_local_selection_model: Enable local evolutionary selection model, which691 considers fitness against the current opponent only, rather than the692 global population state.693 verbose: Set to True to print intermediate results.694 use_inf_alpha: Use infinite-alpha alpharank model.695 inf_alpha_eps: Noise term to use in infinite-alpha alpharank model.696 Returns:697 rhos: Matrix of strategy-to-strategy fixation probabilities.698 rho_m: Neutral fixation probability.699 pi: Finite population stationary distribution.700 num_strats: Number of available strategies.701 """702 payoffs_are_hpt_format = utils.check_payoffs_are_hpt(payoff_tables)703 num_populations = len(payoff_tables)704 num_strats_per_population = utils.get_num_strats_per_population(705 payoff_tables, payoffs_are_hpt_format706 )707 # Handles the trivial case of Markov chain with one state708 if np.array_equal(709 num_strats_per_population, np.ones(len(num_strats_per_population))710 ):711 rhos = np.asarray([[1]])712 rho_m = 1.0 / m if not use_inf_alpha else 1713 num_profiles = 1714 pi = np.asarray([1.0])715 return rhos, rho_m, pi, num_profiles, num_strats_per_population716 if verbose:717 print("Constructing c matrix")718 print("num_strats_per_population:", num_strats_per_population)719 if num_populations == 1:720 # User fast closed-form analysis for constant-sum single-population games721 game_is_constant_sum, payoff_sum = utils.check_is_constant_sum(722 payoff_tables[0], payoffs_are_hpt_format723 )724 if verbose:725 print(726 "game_is_constant_sum:",727 game_is_constant_sum,728 "payoff sum: ",729 payoff_sum,730 )731 # Single-population/symmetric game just uses the first player's payoffs732 c, rhos = _get_singlepop_transition_matrix(733 payoff_tables[0],734 payoffs_are_hpt_format,735 m,736 alpha,737 game_is_constant_sum,738 use_local_selection_model,739 payoff_sum,740 use_inf_alpha=use_inf_alpha,741 inf_alpha_eps=inf_alpha_eps,742 )743 num_profiles = num_strats_per_population[0]744 else:745 c, rhos = _get_multipop_transition_matrix(746 payoff_tables,747 payoffs_are_hpt_format,748 m,749 alpha,750 use_inf_alpha=use_inf_alpha,751 inf_alpha_eps=inf_alpha_eps,752 )753 num_profiles = utils.get_num_profiles(num_strats_per_population)754 pi = _get_stationary_distr(c)755 rho_m = 1.0 / m if not use_inf_alpha else 1 # Neutral fixation probability756 if verbose:757 print_results(payoff_tables, payoffs_are_hpt_format, rhos, rho_m, c, pi)758 return rhos, rho_m, pi, num_profiles, num_strats_per_population759def suggest_alpha(payoff_tables, tol=0.1):760 """Suggests an alpha for use in alpha-rank.761 The suggested alpha is approximately the smallest possible alpha such that762 the ranking has 'settled out'. It is calculated as763 -ln(tol)/min_gap_between_payoffs.764 The logic behind this settling out is that the fixation probabilities can be765 expanded as a series, and the relative size of each term in this series766 changes with alpha. As alpha gets larger and larger, one of the terms in767 this series comes to dominate, and this causes the ranking to settle768 down. Just how fast this domination happens is easy to calculate, and this769 function uses it to estimate the alpha by which the ranking has settled.770 You can find further discussion at the PR:771 https://github.com/deepmind/open_spiel/pull/403772 Args:773 payoff_tables: List of game payoff tables, one for each agent identity. Each774 payoff_table may be either a numpy array, or a _PayoffTableInterface775 object.776 tol: the desired gap between the first and second terms in the fixation777 probability expansion. A smaller tolerance leads to a larger alpha, and778 a 'more settled out' ranking.779 Returns:780 A suggested alpha.781 """782 payoffs_are_hpt_format = utils.check_payoffs_are_hpt(payoff_tables)783 num_strats_per_population = utils.get_num_strats_per_population(784 payoff_tables, payoffs_are_hpt_format785 )786 num_profiles = utils.get_num_profiles(num_strats_per_population)787 gap = np.inf788 for id_row_profile in range(num_profiles):789 row_profile = utils.get_strat_profile_from_id(790 num_strats_per_population, id_row_profile791 )792 next_profile_gen = utils.get_valid_next_profiles(793 num_strats_per_population, row_profile794 )795 for index_population_that_changed, col_profile in next_profile_gen:796 payoff_table_k = payoff_tables[index_population_that_changed]797 f_r = _get_payoff(798 payoff_table_k,799 payoffs_are_hpt_format,800 col_profile,...
alpharank.py
Source:alpharank.py
...287 inf_alpha_eps=0.1):288 """Gets Markov transition matrix for multipopulation games."""289 num_strats_per_population = utils.get_num_strats_per_population(290 payoff_tables, payoffs_are_hpt_format)291 num_profiles = utils.get_num_profiles(num_strats_per_population)292 eta = 1. / (np.sum(num_strats_per_population - 1))293 c = np.zeros((num_profiles, num_profiles))294 rhos = np.zeros((num_profiles, num_profiles))295 for id_row_profile in range(num_profiles):296 row_profile = utils.get_strat_profile_from_id(num_strats_per_population,297 id_row_profile)298 next_profile_gen = utils.get_valid_next_profiles(num_strats_per_population,299 row_profile)300 for index_population_that_changed, col_profile in next_profile_gen:301 id_col_profile = utils.get_id_from_strat_profile(302 num_strats_per_population, col_profile)303 if use_inf_alpha:304 payoff_col = _get_payoff(305 payoff_tables[index_population_that_changed],306 payoffs_are_hpt_format,307 col_profile,308 k=index_population_that_changed)309 payoff_row = _get_payoff(310 payoff_tables[index_population_that_changed],311 payoffs_are_hpt_format,312 row_profile,313 k=index_population_that_changed)314 if np.isclose(payoff_col, payoff_row, atol=1e-14):315 c[id_row_profile, id_col_profile] = eta * 0.5316 elif payoff_col > payoff_row:317 # Transition to col strategy since its payoff is higher than row318 # strategy, but remove some small amount of mass, inf_alpha_eps, to319 # keep the chain irreducible320 c[id_row_profile, id_col_profile] = eta * (1 - inf_alpha_eps)321 else:322 # Transition with very small probability323 c[id_row_profile, id_col_profile] = eta * inf_alpha_eps324 else:325 rhos[id_row_profile, id_col_profile] = _get_rho_sr_multipop(326 payoff_table_k=payoff_tables[index_population_that_changed],327 payoffs_are_hpt_format=payoffs_are_hpt_format,328 k=index_population_that_changed,329 m=m,330 r=col_profile,331 s=row_profile,332 alpha=alpha)333 c[id_row_profile,334 id_col_profile] = eta * rhos[id_row_profile, id_col_profile]335 # Special case of self-transition336 c[id_row_profile, id_row_profile] = 1 - sum(c[id_row_profile, :])337 return c, rhos338def _get_stationary_distr(c):339 """Gets stationary distribution of transition matrix c."""340 eigenvals, left_eigenvecs, _ = la.eig(c, left=True, right=True)341 mask = abs(eigenvals - 1.) < 1e-10342 left_eigenvecs = left_eigenvecs[:, mask]343 num_stationary_eigenvecs = np.shape(left_eigenvecs)[1]344 if num_stationary_eigenvecs != 1:345 raise ValueError('Expected 1 stationary distribution, but found %d' %346 num_stationary_eigenvecs)347 left_eigenvecs *= 1. / sum(left_eigenvecs)348 return left_eigenvecs.real.flatten()349def print_results(payoff_tables,350 payoffs_are_hpt_format,351 rhos=None,352 rho_m=None,353 c=None,354 pi=None):355 """Prints the finite-population analysis results."""356 print('Payoff tables:\n')357 if payoffs_are_hpt_format:358 for payoff_table in payoff_tables:359 print(payoff_table())360 else:361 print(payoff_tables)362 if rho_m is not None:363 print('\nNeutral fixation probability (rho_m):\n', rho_m)364 if rhos is not None and rho_m is not None:365 print('\nFixation probability matrix (rho_{r,s}/rho_m):\n',366 np.around(rhos / rho_m, decimals=2))367 if c is not None:368 print('\nMarkov transition matrix (c):\n', np.around(c, decimals=2))369 if pi is not None:370 print('\nStationary distribution (pi):\n', pi)371def sweep_pi_vs_epsilon(payoff_tables,372 strat_labels=None,373 warm_start_epsilon=None,374 visualize=False,375 return_epsilon=False,376 min_iters=10,377 max_iters=100,378 min_epsilon=1e-14,379 num_strats_to_label=10,380 legend_sort_clusters=False):381 """Computes infinite-alpha distribution for a range of perturbations.382 The range of response graph perturbations is defined in epsilon_list.383 Note that min_iters and max_iters is necessary as it may sometimes appear the384 stationary distribution has converged for a game in the first few iterations,385 where in reality a sufficiently smaller epsilon is needed for the distribution386 to first diverge, then reconverge. This behavior is dependent on both the387 payoff structure and bounds, so the parameters min_iters and max_iters can be388 used to fine-tune this.389 Args:390 payoff_tables: List of game payoff tables, one for each agent identity.391 Each payoff_table may be either a numpy array, or a392 _PayoffTableInterface object.393 strat_labels: Human-readable strategy labels. See get_strat_profile_labels()394 in utils.py for formatting details.395 warm_start_epsilon: Initial value of epsilon to use.396 visualize: Plot the sweep results.397 return_epsilon: Whether to return the final epsilon used.398 min_iters: the minimum number of sweep iterations.399 max_iters: the maximum number of sweep iterations.400 min_epsilon: the minimum value of epsilon to be tested, at which point the401 sweep terminates (if not converged already).402 num_strats_to_label: Number of strats to label in legend403 legend_sort_clusters: If true, strategies in the same cluster are sorted in404 the legend according to orderings for earlier alpha values. Primarily for405 visualization purposes! Rankings for lower alpha values should be406 interpreted carefully.407 Returns:408 pi: AlphaRank stationary distribution.409 epsilon: The AlphaRank transition matrix noise level resulting from sweep.410 """411 payoffs_are_hpt_format = utils.check_payoffs_are_hpt(payoff_tables)412 num_populations = len(payoff_tables)413 num_strats_per_population = utils.get_num_strats_per_population(414 payoff_tables, payoffs_are_hpt_format)415 if num_populations == 1:416 num_profiles = num_strats_per_population[0]417 else:418 num_profiles = utils.get_num_profiles(num_strats_per_population)419 assert (strat_labels is None or isinstance(strat_labels, dict)420 or (len(strat_labels) == num_profiles))421 pi_list = np.empty((num_profiles, 0))422 pi, alpha, m = None, None, None # Unused in infinite-alpha regime423 epsilon_list = []424 epsilon_pi_hist = {}425 num_iters = 0426 epsilon_mult_factor = 0.5427 alpharank_succeeded_once = False428 if warm_start_epsilon is not None:429 epsilon = warm_start_epsilon430 else:431 epsilon = 0.5432 while True:433 try:434 pi_prev = pi435 _, _, pi, _, _ = compute(payoff_tables, m=m, alpha=alpha,436 use_inf_alpha=True, inf_alpha_eps=epsilon)437 epsilon_pi_hist[epsilon] = pi438 # Stop when pi converges439 if num_iters > min_iters and np.allclose(pi, pi_prev):440 break441 epsilon *= epsilon_mult_factor442 num_iters += 1443 alpharank_succeeded_once = True444 assert num_iters < max_iters, ('Alpharank stationary distr. not found'445 'after {} iterations of pi_vs_epsilon'446 'sweep'.format(num_iters))447 except ValueError as _:448 print('Error: ', _, epsilon, min_epsilon)449 # Case where epsilon has been decreased beyond desirable limits but no450 # distribution found.451 assert epsilon >= min_epsilon, ('AlphaRank stationary distr. not found &'452 'epsilon < min_epsilon.')453 # Case where epsilon >= min_epsilon, but still small enough that it causes454 # causes exceptions due to precision issues. So increase it.455 epsilon /= epsilon_mult_factor456 # Case where alpharank_succeeded_once (i.e., epsilon_list and pi_list have457 # at least one entry), and a) has not converged yet and b) failed on this458 # instance due to epsilon being too small. I.e., the rate of decreasing459 # of epsilon is too high.460 if alpharank_succeeded_once:461 epsilon_mult_factor = (epsilon_mult_factor+1.)/2.462 epsilon *= epsilon_mult_factor463 epsilon_list, pi_list = zip(*[(epsilon, epsilon_pi_hist[epsilon])464 for epsilon in sorted(epsilon_pi_hist.keys(),465 reverse=True)])466 pi_list = np.asarray(pi_list)467 if visualize:468 if strat_labels is None:469 strat_labels = utils.get_strat_profile_labels(payoff_tables,470 payoffs_are_hpt_format)471 alpharank_visualizer.plot_pi_vs_alpha(472 pi_list.T,473 epsilon_list,474 num_populations,475 num_strats_per_population,476 strat_labels,477 num_strats_to_label=num_strats_to_label,478 legend_sort_clusters=legend_sort_clusters,479 xlabel=r'Infinite-AlphaRank Noise $\epsilon$')480 if return_epsilon:481 return pi_list[-1], epsilon_list[-1]482 else:483 return pi_list[-1]484def sweep_pi_vs_alpha(payoff_tables,485 strat_labels=None,486 warm_start_alpha=None,487 visualize=False,488 return_alpha=False,489 m=50,490 rtol=1e-5,491 atol=1e-8,492 num_strats_to_label=10,493 legend_sort_clusters=False):494 """Computes stationary distribution, pi, for range of selection intensities.495 The range of selection intensities is defined in alpha_list and corresponds496 to the temperature of the Fermi selection function.497 Args:498 payoff_tables: List of game payoff tables, one for each agent identity. Each499 payoff_table may be either a numpy array, or a _PayoffTableInterface500 object.501 strat_labels: Human-readable strategy labels. See get_strat_profile_labels()502 in utils.py for formatting details.503 warm_start_alpha: Initial value of alpha to use.504 visualize: Plot the sweep results.505 return_alpha: Whether to return the final alpha used.506 m: AlphaRank population size.507 rtol: The relative tolerance parameter for np.allclose calls.508 atol: The absolute tolerance parameter for np.allclose calls.509 num_strats_to_label: Number of strats to label in legend510 legend_sort_clusters: If true, strategies in the same cluster are sorted in511 the legend according to orderings for earlier alpha values. Primarily for512 visualization purposes! Rankings for lower alpha values should be513 interpreted carefully.514 Returns:515 pi: AlphaRank stationary distribution.516 alpha: The AlphaRank selection-intensity level resulting from sweep.517 """518 payoffs_are_hpt_format = utils.check_payoffs_are_hpt(payoff_tables)519 num_populations = len(payoff_tables)520 num_strats_per_population = utils.get_num_strats_per_population(521 payoff_tables, payoffs_are_hpt_format)522 if num_populations == 1:523 num_profiles = num_strats_per_population[0]524 else:525 num_profiles = utils.get_num_profiles(num_strats_per_population)526 assert (strat_labels is None or isinstance(strat_labels, dict)527 or (len(strat_labels) == num_profiles))528 pi_list = np.empty((num_profiles, 0))529 alpha_list = []530 num_iters = 0531 alpha_mult_factor = 2.532 if warm_start_alpha is not None:533 alpha = warm_start_alpha534 alpharank_succeeded_once = False535 else:536 alpha = 1e-4 # Reasonable default for most games, can be user-overridden537 while 1:538 try:539 _, _, pi, _, _ = compute(payoff_tables, alpha=alpha, m=m)540 pi_list = np.append(pi_list, np.reshape(pi, (-1, 1)), axis=1)541 alpha_list.append(alpha)542 # Stop when pi converges543 if num_iters > 0 and np.allclose(pi, pi_list[:, num_iters - 1], rtol,544 atol):545 break546 alpha *= alpha_mult_factor547 num_iters += 1548 alpharank_succeeded_once = True549 except ValueError as _:550 if warm_start_alpha is not None and not alpharank_succeeded_once:551 # When warm_start_alpha is used, there's a chance that552 # the initial warm_start_alpha is too large and causes exceptions due to553 # the Markov transition matrix being reducible. So keep decreasing until554 # a single success occurs.555 alpha /= 2556 elif not np.allclose(pi_list[:, -1], pi_list[:, -2], rtol, atol):557 # Sweep stopped due to multiple stationary distributions, but pi had558 # not converged due to the alpha scaling being too large.559 alpha /= alpha_mult_factor560 alpha_mult_factor = (alpha_mult_factor + 1.) / 2.561 alpha *= alpha_mult_factor562 else:563 break564 if visualize:565 if strat_labels is None:566 strat_labels = utils.get_strat_profile_labels(payoff_tables,567 payoffs_are_hpt_format)568 alpharank_visualizer.plot_pi_vs_alpha(569 pi_list.T,570 alpha_list,571 num_populations,572 num_strats_per_population,573 strat_labels,574 num_strats_to_label=num_strats_to_label,575 legend_sort_clusters=legend_sort_clusters)576 if return_alpha:577 return pi, alpha578 else:579 return pi580def compute_and_report_alpharank(payoff_tables,581 m=50,582 alpha=100,583 verbose=False,584 num_top_strats_to_print=8):585 """Computes and visualizes Alpha-Rank outputs.586 Args:587 payoff_tables: List of game payoff tables, one for each agent identity. Each588 payoff_table may be either a numpy array, or a _PayoffTableInterface589 object.590 m: Finite population size.591 alpha: Fermi distribution temperature parameter.592 verbose: Set to True to print intermediate results.593 num_top_strats_to_print: Number of top strategies to print.594 Returns:595 pi: AlphaRank stationary distribution/rankings.596 """597 payoffs_are_hpt_format = utils.check_payoffs_are_hpt(payoff_tables)598 rhos, rho_m, pi, _, _ = compute(payoff_tables, m=m, alpha=alpha)599 strat_labels = utils.get_strat_profile_labels(payoff_tables,600 payoffs_are_hpt_format)601 if verbose:602 print_results(payoff_tables, payoffs_are_hpt_format, pi=pi)603 utils.print_rankings_table(604 payoff_tables,605 pi,606 strat_labels,607 num_top_strats_to_print=num_top_strats_to_print)608 m_network_plotter = alpharank_visualizer.NetworkPlot(609 payoff_tables, rhos, rho_m, pi, strat_labels, num_top_profiles=8)610 m_network_plotter.compute_and_draw_network()611 return pi612def compute(payoff_tables,613 m=50,614 alpha=100,615 use_local_selection_model=True,616 verbose=False,617 use_inf_alpha=False,618 inf_alpha_eps=0.01):619 """Computes the finite population stationary statistics.620 Args:621 payoff_tables: List of game payoff tables, one for each agent identity. Each622 payoff_table may be either a numpy array, or a _PayoffTableInterface623 object.624 m: Finite population size.625 alpha: Fermi distribution temperature parameter.626 use_local_selection_model: Enable local evolutionary selection model, which627 considers fitness against the current opponent only, rather than the628 global population state.629 verbose: Set to True to print intermediate results.630 use_inf_alpha: Use infinite-alpha alpharank model.631 inf_alpha_eps: Noise term to use in infinite-alpha alpharank model.632 Returns:633 rhos: Matrix of strategy-to-strategy fixation probabilities.634 rho_m: Neutral fixation probability.635 pi: Finite population stationary distribution.636 num_strats: Number of available strategies.637 """638 payoffs_are_hpt_format = utils.check_payoffs_are_hpt(payoff_tables)639 num_populations = len(payoff_tables)640 num_strats_per_population = utils.get_num_strats_per_population(641 payoff_tables, payoffs_are_hpt_format)642 # Handles the trivial case of Markov chain with one state643 if np.array_equal(num_strats_per_population,644 np.ones(len(num_strats_per_population))):645 rhos = np.asarray([[1]])646 rho_m = 1. / m if not use_inf_alpha else 1647 num_profiles = 1648 pi = np.asarray([1.])649 return rhos, rho_m, pi, num_profiles, num_strats_per_population650 if verbose:651 print('Constructing c matrix')652 print('num_strats_per_population:', num_strats_per_population)653 if num_populations == 1:654 # User fast closed-form analysis for constant-sum single-population games655 game_is_constant_sum, payoff_sum = utils.check_is_constant_sum(656 payoff_tables[0], payoffs_are_hpt_format)657 if verbose:658 print('game_is_constant_sum:', game_is_constant_sum, 'payoff sum: ',659 payoff_sum)660 # Single-population/symmetric game just uses the first player's payoffs661 c, rhos = _get_singlepop_transition_matrix(662 payoff_tables[0],663 payoffs_are_hpt_format,664 m,665 alpha,666 game_is_constant_sum,667 use_local_selection_model,668 payoff_sum,669 use_inf_alpha=use_inf_alpha,670 inf_alpha_eps=inf_alpha_eps)671 num_profiles = num_strats_per_population[0]672 else:673 c, rhos = _get_multipop_transition_matrix(674 payoff_tables,675 payoffs_are_hpt_format,676 m,677 alpha,678 use_inf_alpha=use_inf_alpha,679 inf_alpha_eps=inf_alpha_eps)680 num_profiles = utils.get_num_profiles(num_strats_per_population)681 pi = _get_stationary_distr(c)682 rho_m = 1. / m if not use_inf_alpha else 1 # Neutral fixation probability683 if verbose:684 print_results(payoff_tables, payoffs_are_hpt_format, rhos, rho_m, c, pi)685 return rhos, rho_m, pi, num_profiles, num_strats_per_population686def suggest_alpha(payoff_tables, tol=.1):687 """Suggests an alpha for use in alpha-rank.688 The suggested alpha is approximately the smallest possible alpha such that689 the ranking has 'settled out'. It is calculated as690 -ln(tol)/min_gap_between_payoffs.691 The logic behind this settling out is that the fixation probabilities can be692 expanded as a series, and the relative size of each term in this series693 changes with alpha. As alpha gets larger and larger, one of the terms in694 this series comes to dominate, and this causes the ranking to settle695 down. Just how fast this domination happens is easy to calculate, and this696 function uses it to estimate the alpha by which the ranking has settled.697 You can find further discussion at the PR:698 https://github.com/deepmind/open_spiel/pull/403699 Args:700 payoff_tables: List of game payoff tables, one for each agent identity. Each701 payoff_table may be either a numpy array, or a _PayoffTableInterface702 object.703 tol: the desired gap between the first and second terms in the fixation704 probability expansion. A smaller tolerance leads to a larger alpha, and705 a 'more settled out' ranking.706 Returns:707 A suggested alpha.708 """709 payoffs_are_hpt_format = utils.check_payoffs_are_hpt(payoff_tables)710 num_strats_per_population = utils.get_num_strats_per_population(711 payoff_tables, payoffs_are_hpt_format)712 num_profiles = utils.get_num_profiles(num_strats_per_population)713 gap = np.inf714 for id_row_profile in range(num_profiles):715 row_profile = utils.get_strat_profile_from_id(num_strats_per_population,716 id_row_profile)717 next_profile_gen = utils.get_valid_next_profiles(num_strats_per_population,718 row_profile)719 for index_population_that_changed, col_profile in next_profile_gen:720 payoff_table_k = payoff_tables[index_population_that_changed]721 f_r = _get_payoff(payoff_table_k, payoffs_are_hpt_format, col_profile,722 index_population_that_changed)723 f_s = _get_payoff(payoff_table_k, payoffs_are_hpt_format, row_profile,724 index_population_that_changed)725 if f_r > f_s:726 gap = min(gap, f_r - f_s)...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!