From 185fe85acf14ad8b2f6fa2d2aecf422dd5a67c9f Mon Sep 17 00:00:00 2001 From: ssmaddila <siva-sri-prasanna.maddila@inrae.fr> Date: Mon, 14 Oct 2024 15:22:42 +0200 Subject: [PATCH 01/13] Simplified definition of `NFG.generate_joint_actions` --- gtnash/game/normalformgame.py | 245 +++++++++++++++++----------------- 1 file changed, 122 insertions(+), 123 deletions(-) diff --git a/gtnash/game/normalformgame.py b/gtnash/game/normalformgame.py index e9790b6..783caac 100644 --- a/gtnash/game/normalformgame.py +++ b/gtnash/game/normalformgame.py @@ -34,7 +34,7 @@ class NFG(AbstractGame): else: self.index_to_player = index_to_player - def generate_joint_actions(self, players_actions): + def generate_joint_actions(self, players_actions=None): """Generates all the possible joint strategies. :param list of lists players_actions: The list of all @@ -43,21 +43,9 @@ class NFG(AbstractGame): :returns: A matrix which rows are the joint strategies. :rtype: np.matrix of int. """ - matA = np.mat([]) - for p_a in reversed(players_actions): - p_i = np.mat(p_a) - p_i = p_i.transpose() - if matA.size == 0: - matA = p_i - else: - one_vec = np.ones((matA.shape[0], 1)) - mat = np.concatenate((int(p_i[0]) * one_vec, matA), axis=1) - for action_i in p_i[1:]: - mati = np.concatenate((int(action_i) * one_vec, matA), - axis=1) - mat = np.concatenate((mat, mati), axis=0) - matA = mat - return matA.astype(int) + if players_actions is None: + players_actions = self.players_actions + return np.matrix([jaction for jaction in itertools.product(*players_actions)]) def all_response_of_player(self, player_ind, action): """Generates all the possible joint strategies obtained by @@ -88,8 +76,9 @@ class NFG(AbstractGame): excluding player *player_ind*'s action. :rtype: np.matrix. """ - action_in_use = [act for i, act in enumerate(self.players_actions) - if (i != player_ind)] + action_in_use = [ + act for i, act in enumerate(self.players_actions) if (i != player_ind) + ] return self.generate_joint_actions(action_in_use) def get_sub_jointact_of_n(self, player_ind): @@ -110,15 +99,14 @@ class NFG(AbstractGame): tmp_act = list(tmp_jact) tmp_act.insert(player_ind, i) tmp_index_of_alt += [ - np.where( - (self.joint_actions == np.array(tmp_act) - ).all(1))[0][0]] + np.where((self.joint_actions == np.array(tmp_act)).all(1))[0][0] + ] tmp_index_of_all += [tmp_index_of_alt] return tmp_index_of_all def transform_utilities(self): """Computes the disutility matrix of the utility - matrix of the considered game. + matrix of the considered game. """ for i in range(self.n_players): @@ -137,8 +125,9 @@ class NFG(AbstractGame): :returns: rows' indices of the joint strategies list. :rtype: list of integers. """ - return np.where(action_value == np.array( - self.joint_actions[:, player_id]).flatten())[0] + return np.where( + action_value == np.array(self.joint_actions[:, player_id]).flatten() + )[0] def disutil_of_row(self, player_id, action_value): """Returns the disutility of joint strategies where the @@ -152,8 +141,7 @@ class NFG(AbstractGame): :rtype: list. """ ind_row = self.row_where_p_is_i(player_id, action_value) - return np.array(self.disutilities[ind_row, player_id] - ).flatten().astype(int) + return np.array(self.disutilities[ind_row, player_id]).flatten().astype(int) def util_of_row(self, player_id, action_value): """Returns the utility of joint strategies where the @@ -166,8 +154,11 @@ class NFG(AbstractGame): :rtype: list. """ ind_row = self.row_where_p_is_i(player_id, action_value) - return np.array([self.utilities[player_id][tmp_ind] - for tmp_ind in ind_row]).flatten().astype(object) + return ( + np.array([self.utilities[player_id][tmp_ind] for tmp_ind in ind_row]) + .flatten() + .astype(object) + ) def util_of_joint_action(self, player_id, jact): """Returns the utility of joint action *jact* for @@ -217,19 +208,16 @@ class NFG(AbstractGame): prob_nbis = mixed_joint_strat[nbis] if not (nbis == n): for j, prob_nbis_j in enumerate(prob_nbis): - index_nbis_j = \ - self.row_where_p_is_i( - nbis, - self.players_actions[nbis][j]) + index_nbis_j = self.row_where_p_is_i( + nbis, self.players_actions[nbis][j] + ) for ind_nbis in index_nbis_j: - util_of_n[ind_nbis] = \ - util_of_n[ind_nbis] * prob_nbis_j + util_of_n[ind_nbis] = util_of_n[ind_nbis] * prob_nbis_j # Get the expected utility of each action value_all_i = [] for i in range(len(prob_n)): value_i = 0 - index_n_i = self.row_where_p_is_i(n, - self.players_actions[n][i]) + index_n_i = self.row_where_p_is_i(n, self.players_actions[n][i]) for ind_n in index_n_i: value_i += util_of_n[ind_n] value_all_i += [value_i] @@ -258,19 +246,16 @@ class NFG(AbstractGame): prob_nbis = mixed_joint_strat[nbis] if not (nbis == n): for j, prob_nbis_j in enumerate(prob_nbis): - index_nbis_j = \ - self.row_where_p_is_i( - nbis, - self.players_actions[nbis][j]) + index_nbis_j = self.row_where_p_is_i( + nbis, self.players_actions[nbis][j] + ) for ind_nbis in index_nbis_j: - util_of_n[ind_nbis] = \ - util_of_n[ind_nbis] * prob_nbis_j + util_of_n[ind_nbis] = util_of_n[ind_nbis] * prob_nbis_j # Get the expected utility of each action value_all_i = [] for i in range(len(prob_n)): value_i = 0 - index_n_i = self.row_where_p_is_i(n, - self.players_actions[n][i]) + index_n_i = self.row_where_p_is_i(n, self.players_actions[n][i]) for ind_n in index_n_i: value_i += util_of_n[ind_n] value_all_i += [value_i] @@ -315,18 +300,21 @@ class NFG(AbstractGame): Nash equilibrium and *False* if not. :rtype: boolean. """ - expected_util_of_mixed_joint_strategy = \ - self.expected_utilities(mixed_joint_strategy) + expected_util_of_mixed_joint_strategy = self.expected_utilities( + mixed_joint_strategy + ) for play in range(self.n_players): for ai in range(len(self.players_actions[play])): other_strategy = mixed_joint_strategy.copy() - other_strategy[play] = \ - np.zeros(len(mixed_joint_strategy[play])) + other_strategy[play] = np.zeros(len(mixed_joint_strategy[play])) other_strategy[play][ai] = 1 - expected_util_of_other = \ - self.expected_utilities_of_n(play, other_strategy) - if not (expected_util_of_other <= - expected_util_of_mixed_joint_strategy[play] + gap): + expected_util_of_other = self.expected_utilities_of_n( + play, other_strategy + ) + if not ( + expected_util_of_other + <= expected_util_of_mixed_joint_strategy[play] + gap + ): return False return True @@ -335,8 +323,7 @@ class NFG(AbstractGame): alt_jact = self.all_response_of_player(n, pure_joint_strategy) currentutil = self.util_of_joint_action(n, pure_joint_strategy) for tmp_jact in alt_jact: - if not (self.util_of_joint_action(n, tmp_jact) <= - currentutil+gap): + if not (self.util_of_joint_action(n, tmp_jact) <= currentutil + gap): return False return True @@ -355,18 +342,18 @@ class NFG(AbstractGame): """ all_valuediff = [] for play in range(self.n_players): - expected_util_of_mixed_joint_strategy = \ - self.expected_utilities(mixed_joint_strategy) + expected_util_of_mixed_joint_strategy = self.expected_utilities( + mixed_joint_strategy + ) for ai in range(len(self.players_actions[play])): other_strategy = mixed_joint_strategy.copy() - other_strategy[play] = np.zeros( - len(mixed_joint_strategy[play])) + other_strategy[play] = np.zeros(len(mixed_joint_strategy[play])) other_strategy[play][ai] = 1 - expected_util_of_other =\ - self.expected_utilities(other_strategy) - all_valuediff += \ - [expected_util_of_other[play] - - expected_util_of_mixed_joint_strategy[play]] + expected_util_of_other = self.expected_utilities(other_strategy) + all_valuediff += [ + expected_util_of_other[play] + - expected_util_of_mixed_joint_strategy[play] + ] return max(all_valuediff) def get_all_PNE(self): @@ -381,9 +368,13 @@ class NFG(AbstractGame): all_pne = [] all_pure_strat = list(itertools.product(*self.players_actions)) for pure_strat in all_pure_strat: - tmp_dic_strat = {i: [1 if self.players_actions[i][s_i] == s else 0 - for s_i in range(len(self.players_actions[i])) - ] for i, s in enumerate(pure_strat)} + tmp_dic_strat = { + i: [ + 1 if self.players_actions[i][s_i] == s else 0 + for s_i in range(len(self.players_actions[i])) + ] + for i, s in enumerate(pure_strat) + } pure_stratbis = list(pure_strat) if self.is_pure_equilibrium(pure_stratbis): all_pne += [tmp_dic_strat] @@ -415,9 +406,12 @@ class NFG(AbstractGame): all_pure_strat = list(itertools.product(*self.players_actions)) for pure_strat in all_pure_strat: tmp_dic_strat = { - i: [1 if self.players_actions[i][s_i] == s else 0 - for s_i in range(len(self.players_actions[i]))] - for i, s in enumerate(pure_strat)} + i: [ + 1 if self.players_actions[i][s_i] == s else 0 + for s_i in range(len(self.players_actions[i])) + ] + for i, s in enumerate(pure_strat) + } pure_stratbis = list(pure_strat) if self.is_pure_equilibrium(pure_stratbis): return tmp_dic_strat @@ -435,20 +429,19 @@ class NFG(AbstractGame): """ n_players = self.n_players players_actions = deepcopy(self.players_actions) - joint_actions_before = self.generate_joint_actions( - self.players_actions) + joint_actions_before = self.generate_joint_actions(self.players_actions) for n in partial_mixed_strategy.keys(): players_actions[n] = [-1] joint_actions_after = self.generate_joint_actions(players_actions) - utilities = [[0 for a in range(len(joint_actions_after))] - for n in range(n_players)] + utilities = [ + [0 for a in range(len(joint_actions_after))] for n in range(n_players) + ] for aa in range(len(joint_actions_after)): for ab in range(len(joint_actions_before)): are_equal = True for n in range(n_players): if n not in partial_mixed_strategy.keys(): - if joint_actions_after[aa, n] !=\ - joint_actions_before[ab, n]: + if joint_actions_after[aa, n] != joint_actions_before[ab, n]: are_equal = False break if are_equal: @@ -456,7 +449,8 @@ class NFG(AbstractGame): local_proba = 1 for m in partial_mixed_strategy.keys(): local_proba *= partial_mixed_strategy[m][ - joint_actions_before[ab, m]] + joint_actions_before[ab, m] + ] utilities[n][aa] += local_proba * self.utilities[n][ab] nfg_out = NFG(players_actions, utilities) return nfg_out @@ -480,8 +474,7 @@ class NFG(AbstractGame): # For each actions gives its probability dict_actions_proba = {} for j, proba_k_j in enumerate(proba_k): - dict_actions_index[j] = self.row_where_p_is_i( - self.n_players - 1, j) + dict_actions_index[j] = self.row_where_p_is_i(self.n_players - 1, j) dict_actions_proba[j] = proba_k_j new_util = [] new_players_action = [] @@ -495,9 +488,9 @@ class NFG(AbstractGame): new_util_i = 0 # Compute the new utility given the probability for j in range(len(proba_k)): - new_util_i += util_of_n[ - dict_actions_index[j][i] - ] * dict_actions_proba[j] + new_util_i += ( + util_of_n[dict_actions_index[j][i]] * dict_actions_proba[j] + ) new_util_of_n += [new_util_i] new_players_action += [new_players_action_of_n] new_util += [new_util_of_n] @@ -571,15 +564,15 @@ class NFG(AbstractGame): tmp_n_act = [] for a_i, a in enumerate(act_n): if played_strat[n][a_i] == 1: - tmp_n_set = tmp_n_set.union( - list(self.row_where_p_is_i(n, a)) - ) + tmp_n_set = tmp_n_set.union(list(self.row_where_p_is_i(n, a))) tmp_n_act += [a] valid_row = valid_row.intersection(tmp_n_set) new_player_actions += [tmp_n_act] list_row = sorted(valid_row) - new_util = [[self.utilities[n][i] for i in list_row] - for n in range(len(new_player_actions))] + new_util = [ + [self.utilities[n][i] for i in list_row] + for n in range(len(new_player_actions)) + ] return NFG(new_player_actions, new_util) @classmethod @@ -600,27 +593,26 @@ class NFG(AbstractGame): """ # Read file - file_read = open(file_path, 'r') + file_read = open(file_path, "r") content = file_read.read() # List of content (3 String: NFG, string and rest) content_list = content.split('"', 2) game_info = content_list[2] file_read.close() - iterTest = re.finditer('{(.*?)}', game_info) + iterTest = re.finditer("{(.*?)}", game_info) p_actions = [] # Get the name and actions of the players for i, s in enumerate(iterTest): if i > 0: - p_actions = [int(str_int) - for str_int in shlex.split(s.group(1))] + p_actions = [int(str_int) for str_int in shlex.split(s.group(1))] payoff_value = [] - iterTest = re.finditer('\n{1,}(.*?)\n', game_info) + iterTest = re.finditer("\n{1,}(.*?)\n", game_info) # Get the string of payoff, an iterator is use # but there is only 1 element to iterate on for s in iterTest: - payoff_value = [int(sub_int) - for sub_int in s.group(0).strip('\n').split(" ") - if sub_int] + payoff_value = [ + int(sub_int) for sub_int in s.group(0).strip("\n").split(" ") if sub_int + ] n_players = len(p_actions) # Initialize the list of utility u = [[] for i in range(n_players)] @@ -635,8 +627,9 @@ class NFG(AbstractGame): p_actions.reverse() # Generate list of actions like [[0,1,2][0,1][0,1,2,4]] # (for 3 player where one they have 3,2 and 4 actions) - players_actions = [[j for j in range(p_actions[i])] - for i in range(len(p_actions))] + players_actions = [ + [j for j in range(p_actions[i])] for i in range(len(p_actions)) + ] return NFG(players_actions, u) def writeNFGpayoff(self, file_path): @@ -660,8 +653,11 @@ class NFG(AbstractGame): jact = self.joint_actions # Get the utilities as a list util_list = self.utilities - payoffwrite = [util_list[n][i] for i in range(len(jact)) - for n in reversed(range(n_players))] + payoffwrite = [ + util_list[n][i] + for i in range(len(jact)) + for n in reversed(range(n_players)) + ] # Reverse the order of the actions p_actions.reverse() # Create a string that correspond to the @@ -699,7 +695,7 @@ class NFG(AbstractGame): :rtype: list of lists of integers. """ # Read file - my_file = open(file_path, 'r') + my_file = open(file_path, "r") content = my_file.read() # List of content (3 String: NFG, string and rest) content_list = content.split('"', 2) @@ -710,16 +706,16 @@ class NFG(AbstractGame): # Get actions of the players for i, s in enumerate(iterTest): p_actions += [len(shlex.split(s.group(0)))] - iterTest = re.finditer('{(.*?)}', - (game_info.split("\n\n")[2]).replace(',', '')) + iterTest = re.finditer("{(.*?)}", (game_info.split("\n\n")[2]).replace(",", "")) payoff_value = [] # Get Payoff, write it in a list as if it were written # like in the nfg payoff version for i, s in enumerate(iterTest): - payoff_value += [int(sub_int) - for sub_ind, sub_int in - enumerate(shlex.split(s.group(1))) - if sub_ind != 0] + payoff_value += [ + int(sub_int) + for sub_ind, sub_int in enumerate(shlex.split(s.group(1))) + if sub_ind != 0 + ] # payoff_value=[int(sub_int) for sub_ind,sub_int in # enumerate(shlex.split(s.group(1))) if sub_ind!=0 for i,s # in enumerate(iterTest)] @@ -731,8 +727,9 @@ class NFG(AbstractGame): u[i % n_players] += [pay] u.reverse() p_actions.reverse() - players_actions = [[j for j in range(p_actions[i])] - for i in range(len(p_actions))] + players_actions = [ + [j for j in range(p_actions[i])] for i in range(len(p_actions)) + ] self.players_actions = players_actions self.utilities = u util_table = NFG(self.players_actions, self.utilities) @@ -788,11 +785,11 @@ class NFG(AbstractGame): str_payoff += '{ ""' for n, p_n in enumerate(p): if n < len(p_actions) - 1: - str_payoff += f' {p_n},' + str_payoff += f" {p_n}," else: - str_payoff += f' {p_n}' - str_payoff += ' }\n' - str_payoff += '}\n' + str_payoff += f" {p_n}" + str_payoff += " }\n" + str_payoff += "}\n" str_jact = [str(i + 1) for i in range(len(jact))] str_payoff += " ".join(str_jact) + "\n" gamedescript = "nothing" @@ -826,14 +823,14 @@ class NFG(AbstractGame): :returns: utilities table. :rtype: list of lists of integers. """ - file_read = open(file_path, 'r') + file_read = open(file_path, "r") text = file_read.readlines() number_of_line = len(text) if number_of_line == 3: - print('Payoff nfg file.') + print("Payoff nfg file.") util_table = NFG.readNFGpayoff(self, file_path) else: - print('Outcome nfg file.') + print("Outcome nfg file.") util_table = NFG.readNFGoutcome(self, file_path) return util_table @@ -851,10 +848,10 @@ class NFG(AbstractGame): """ if isinstance(self, NFG): - file_path = file_path + '.nfg' + file_path = file_path + ".nfg" NFG.writeNFGpayoff(self, file_path) else: - print('Unrecognized') + print("Unrecognized") def __str__(self): """ @@ -862,14 +859,16 @@ class NFG(AbstractGame): """ label = [] for i in range(len(self.players_actions)): - label.append('Ax'.replace("x", str(i))) - for i in range(len(self.players_actions), - 2 * (len(self.players_actions))): - label.append('Ux'.replace("x", str(i - len(self.players_actions)))) + label.append("Ax".replace("x", str(i))) + for i in range(len(self.players_actions), 2 * (len(self.players_actions))): + label.append("Ux".replace("x", str(i - len(self.players_actions)))) mat_utilities = np.transpose(self.utilities) mat_utilities = mat_utilities.astype(str) tableau_final = np.concatenate( - (np.mat(label), - np.concatenate((self.joint_actions, mat_utilities), axis=1)), - axis=0) + ( + np.mat(label), + np.concatenate((self.joint_actions, mat_utilities), axis=1), + ), + axis=0, + ) return str(tableau_final) -- GitLab From 7cef5ad7a65c98deca7d37d9cbec1afb8a12d5d5 Mon Sep 17 00:00:00 2001 From: ssmaddila <siva-sri-prasanna.maddila@inrae.fr> Date: Mon, 14 Oct 2024 15:27:49 +0200 Subject: [PATCH 02/13] minor rewrites for conciseness --- gtnash/game/normalformgame.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/gtnash/game/normalformgame.py b/gtnash/game/normalformgame.py index 783caac..68bb9d9 100644 --- a/gtnash/game/normalformgame.py +++ b/gtnash/game/normalformgame.py @@ -154,10 +154,10 @@ class NFG(AbstractGame): :rtype: list. """ ind_row = self.row_where_p_is_i(player_id, action_value) - return ( - np.array([self.utilities[player_id][tmp_ind] for tmp_ind in ind_row]) - .flatten() - .astype(object) + return list( + np.array( + [self.utilities[player_id][tmp_ind] for tmp_ind in ind_row] + ).flatten() ) def util_of_joint_action(self, player_id, jact): @@ -387,8 +387,7 @@ class NFG(AbstractGame): and *False* if not. :rtype: boolean. """ - all_pure_strat = list(itertools.product(*self.players_actions)) - for pure_strat in all_pure_strat: + for pure_strat in self.generate_joint_actions(): pure_stratbis = list(pure_strat) if self.is_pure_equilibrium(pure_stratbis): return True -- GitLab From 8cb1605a89b15994ed944b10cd11a4edafd4b857 Mon Sep 17 00:00:00 2001 From: ssmaddila <siva-sri-prasanna.maddila@inrae.fr> Date: Mon, 14 Oct 2024 15:37:00 +0200 Subject: [PATCH 03/13] added gitignore --- .gitignore | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..38a0e6b --- /dev/null +++ b/.gitignore @@ -0,0 +1,173 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints +.ipynb* + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +#env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +# Vim specific swap files +*.swp +\\ + +# Ctags files +tags + +*.zip + +# Documentation artifacts +public/ -- GitLab From 6ca26b64d8e0597d2e353a0354cf69823e4d147d Mon Sep 17 00:00:00 2001 From: Prasanna Maddila <maddilaprasanna10@gmail.com> Date: Wed, 13 Nov 2024 08:40:40 +0100 Subject: [PATCH 04/13] moved to pyproject.toml format --- pyproject.toml | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 pyproject.toml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..40013a7 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,70 @@ +[build-system] +requires = ["setuptools", "setuptools-scm"] +build-backend = "setuptools.build_meta" + +[project] + name = 'gtnash' + version = '1.0.0' + authors=[ + {name = "Regis Sabbadin", email = "regis.sabbadin@inrae.fr"} + ] + description = "Python Nash Equilibrium Computation Utilities" + readme = 'README.md' + dependencies = ['numpy'] + +[tool.setuptools] + packages = ['gtnash'] + +[project.urls] + Documentation = "https://game-theory-tools-group.pages.mia.inra.fr/gtnash/main" + Repository = "https://forgemia.inra.fr/game-theory-tools-group/gtnash/" + Issues = "https://forgemia.inra.fr/game-theory-tools-group/gtnash/-/issues" + +[project.optional-dependencies] + code = ['pylint', 'black', 'pytest', 'coverage', 'pre-commit'] + docs=['sphinx','sphinx-rtd-theme','gitpython','myst_parser'] + +[tool.black] + line-length = 79 + target-version = ['py38'] + +[tool.pytest.ini_options] + minversion = '6.0' + addopts = '-ra -q -W ignore::DeprecationWarning' + testpaths = ['tests/'] + +[tool.pylint.main] + fail-under = 8 + ignore-patterns = ["^\\.#"] + jobs = 0 + persistent = true + py-version = "3.8" + recursive = true + suggestion-mode = true + ignore = [".venv"] + disable = ["W0223", "E0401", "R0801"] + +[tool.pylint.format] + ignore-long-lines = "^\\s*(# )?<?https?://\\S+>?$" + indent-after-paren = 4 + indent-string = " " + max-line-length = 79 + max-module-lines = 1000 + +[tool.pylint.imports] + allow-any-import-level = true + allow-reexport-from-package = true + +[tool.pylint.miscellaneous] + notes = ["FIXME", "XXX", "TODO"] + +[tool.pylint.refactoring] + max-nested-blocks = 5 + never-returning-functions = ["sys.exit", "argparse.parse_error"] + +[tool.coverage.run] +omit = [ + "examples/*", + "*test*", + "*__init__*", + ] -- GitLab From 1bb1020e4b528e5835170c3501e6caf7f6821ed1 Mon Sep 17 00:00:00 2001 From: Prasanna Maddila <maddilaprasanna10@gmail.com> Date: Wed, 13 Nov 2024 08:46:07 +0100 Subject: [PATCH 05/13] NFG.expected_utilities using NFG.expected_utilities_of_n + Reformatted with default black --- gtnash/game/abstractgame.py | 4 +- gtnash/game/bayesian_hypergraphicalgame.py | 318 +++++++++-------- gtnash/game/bayesiangame.py | 243 ++++++------- gtnash/game/graphicalgame.py | 80 +++-- gtnash/game/hypergraphicalgame.py | 381 ++++++++++++--------- gtnash/game/normalformgame.py | 32 +- gtnash/game/polymatrixgame.py | 13 +- 7 files changed, 585 insertions(+), 486 deletions(-) diff --git a/gtnash/game/abstractgame.py b/gtnash/game/abstractgame.py index 93bd2ba..76eb5b5 100644 --- a/gtnash/game/abstractgame.py +++ b/gtnash/game/abstractgame.py @@ -2,8 +2,8 @@ from abc import ABC, abstractmethod class AbstractGame(ABC): - """This is the abstract game class from which all other classes derive. - """ + """This is the abstract game class from which all other classes derive.""" + @property def n_players(self): """Number of players of input game (@property). diff --git a/gtnash/game/bayesian_hypergraphicalgame.py b/gtnash/game/bayesian_hypergraphicalgame.py index 6454c24..6fc0089 100644 --- a/gtnash/game/bayesian_hypergraphicalgame.py +++ b/gtnash/game/bayesian_hypergraphicalgame.py @@ -30,8 +30,15 @@ class BHGG(AbstractGame): """ - def __init__(self, players_actions, utilities, hypergraph, - theta, p, index_to_player={}): + def __init__( + self, + players_actions, + utilities, + hypergraph, + theta, + p, + index_to_player={}, + ): """Hypergraphical bayesian game constructor""" self.n_players = len(players_actions) self.players_actions = players_actions @@ -39,8 +46,10 @@ class BHGG(AbstractGame): self.utilities = utilities self.theta = theta self.p_unorm = p - self.p = [[Fraction(p_t, sum(sub_p_unorm)) - for p_t in sub_p_unorm]for sub_p_unorm in p] + self.p = [ + [Fraction(p_t, sum(sub_p_unorm)) for p_t in sub_p_unorm] + for sub_p_unorm in p + ] self.local_bayesiangames = [] for i_e, e in enumerate(hypergraph): self.local_bayesiangames += [self.generate_local_bayesiangame(i_e)] @@ -57,18 +66,21 @@ class BHGG(AbstractGame): :returns: *bayesian_local_game*, the corresponding bayesian local game. :rtype: BG """ - player_action_local = [self.players_actions[ - self.hypergraph[index_game][n]] - for n in - range(len(self.hypergraph[index_game]))] - player_theta_local = [self.theta[self.hypergraph[index_game][n]] - for n in range(len(self.hypergraph[index_game]))] + player_action_local = [ + self.players_actions[self.hypergraph[index_game][n]] + for n in range(len(self.hypergraph[index_game])) + ] + player_theta_local = [ + self.theta[self.hypergraph[index_game][n]] + for n in range(len(self.hypergraph[index_game])) + ] player_p_local = self.p[index_game] bayesian_local_game = BG( player_action_local, self.utilities[index_game], player_theta_local, - player_p_local) + player_p_local, + ) return bayesian_local_game def expected_utilities(self, bayes_mixed_joint_strat): @@ -92,22 +104,21 @@ class BHGG(AbstractGame): for n_local, n in enumerate(hyper_edge): for t_n in local_bayesiangame.theta[n_local]: local_couple_to_global[(n_local, t_n)] = (n, t_n) - local_mixed_strat[(n_local, t_n) - ] = bayes_mixed_joint_strat[(n, t_n)] + local_mixed_strat[(n_local, t_n)] = bayes_mixed_joint_strat[ + (n, t_n) + ] expected_util_local = local_bayesiangame.expected_utilities( - local_mixed_strat) - for (n_local, t_n) in local_couple_to_global.keys(): + local_mixed_strat + ) + for n_local, t_n in local_couple_to_global.keys(): (n_global, t_n) = local_couple_to_global[(n_local, t_n)] if (n_global, t_n) in expect_util: - expect_util[(n_global, t_n) - ] += expected_util_local[(n_local, t_n)] + expect_util[(n_global, t_n)] += expected_util_local[(n_local, t_n)] else: - expect_util[(n_global, t_n) - ] = expected_util_local[(n_local, t_n)] + expect_util[(n_global, t_n)] = expected_util_local[(n_local, t_n)] return expect_util - def expected_utilities_of_n_t(self, current_n, current_t, - bayes_mixed_joint_strat): + def expected_utilities_of_n_t(self, current_n, current_t, bayes_mixed_joint_strat): expect_util = 0 for index_hyper_edge, hyper_edge in enumerate(self.hypergraph): local_mixed_strat = {} @@ -120,11 +131,12 @@ class BHGG(AbstractGame): if n == current_n and t_n == current_t: (curr_n_loc, curr_t_loc) = (n, t_n) local_couple_to_global[(n_local, t_n)] = (n, t_n) - local_mixed_strat[(n_local, t_n)] = \ - bayes_mixed_joint_strat[(n, t_n)] - expected_util_local_of_n_t = \ - loc_bg.expected_utilities_of_n_t(curr_n_loc, curr_t_loc, - local_mixed_strat) + local_mixed_strat[(n_local, t_n)] = bayes_mixed_joint_strat[ + (n, t_n) + ] + expected_util_local_of_n_t = loc_bg.expected_utilities_of_n_t( + curr_n_loc, curr_t_loc, local_mixed_strat + ) expect_util += expected_util_local_of_n_t return expect_util @@ -135,29 +147,38 @@ class BHGG(AbstractGame): label = [] players_id = self.hypergraph[j] for i in range(len(players_id)): - label.append( - 'Ax'.replace( - "x", str( - players_id[i]))) # 'A _i' + label.append("Ax".replace("x", str(players_id[i]))) # 'A _i' for i in range(len(players_id), 2 * (len(players_id))): - label.append('Ux'.replace( - "x", str(players_id[i - len(players_id)]))) - mat_utilities = np.transpose( - self.local_bayesiangames[j].utilities[t]) + label.append( + "Ux".replace("x", str(players_id[i - len(players_id)])) + ) + mat_utilities = np.transpose(self.local_bayesiangames[j].utilities[t]) mat_utilities = mat_utilities.astype(str) - joint_actions = np.copy( - self.local_bayesiangames[j].joint_actions) - joint_actions = \ - self.local_bayesiangames[j].joint_actions.astype(str) + joint_actions = np.copy(self.local_bayesiangames[j].joint_actions) + joint_actions = self.local_bayesiangames[j].joint_actions.astype(str) tableau_final = np.concatenate( - (np.mat(label), np.concatenate( - (joint_actions, mat_utilities), axis=1)), axis=0) - print('Theta', t, '=', - self.local_bayesiangames[j].joint_theta[t], - 'and P(Theta', j, ') =', self.p[j][t], '\n', - tableau_final, '\n') - return '\n Hypergraph: \n' + \ - str(self.hypergraph) + '\n Type: \n' + str(self.theta) + ( + np.mat(label), + np.concatenate((joint_actions, mat_utilities), axis=1), + ), + axis=0, + ) + print( + "Theta", + t, + "=", + self.local_bayesiangames[j].joint_theta[t], + "and P(Theta", + j, + ") =", + self.p[j][t], + "\n", + tableau_final, + "\n", + ) + return ( + "\n Hypergraph: \n" + str(self.hypergraph) + "\n Type: \n" + str(self.theta) + ) def is_equilibrium(self, bayes_mixed_join_strat, gap=0.0001): """Checks whether *bayes_mixed_join_strat* \ @@ -172,19 +193,21 @@ class BHGG(AbstractGame): :rtype: boolean. """ expected_util_of_bayes_joint_strategy = self.expected_utilities( - bayes_mixed_join_strat) + bayes_mixed_join_strat + ) for n in range(self.n_players): for t_n in range(len(self.theta[n])): for a_n in range(len(self.players_actions[n])): other_strategy = bayes_mixed_join_strat.copy() - other_strategy[(n, t_n)] = np.zeros( - len(self.players_actions[n])) + other_strategy[(n, t_n)] = np.zeros(len(self.players_actions[n])) other_strategy[(n, t_n)][a_n] = 1 - expected_util_of_other = \ - self.expected_utilities_of_n_t(n, t_n, other_strategy) - if expected_util_of_other \ - > expected_util_of_bayes_joint_strategy[(n, t_n)] \ - + gap: + expected_util_of_other = self.expected_utilities_of_n_t( + n, t_n, other_strategy + ) + if ( + expected_util_of_other + > expected_util_of_bayes_joint_strategy[(n, t_n)] + gap + ): return False return True @@ -231,17 +254,20 @@ class BHGG(AbstractGame): new_util = tmp_hgg.local_normalformgames[index_e].utilities for e_n in e: (n_local, t_local) = local_index_to_player[e_n] - new_n_index = player_to_new_index[( - bg_hyper[n_local], t_local)] + new_n_index = player_to_new_index[(bg_hyper[n_local], t_local)] new_e += [new_n_index] local_hyper += [new_e] util += [new_util] new_hypergraphe += local_hyper if max([len(e) for e in self.hypergraph]) == 2: - return PMG(new_players_actions, util, - new_hypergraphe), index_to_old_player - return HGG(new_players_actions, util, - new_hypergraphe), index_to_old_player + return ( + PMG(new_players_actions, util, new_hypergraphe), + index_to_old_player, + ) + return ( + HGG(new_players_actions, util, new_hypergraphe), + index_to_old_player, + ) def convert_to_NFG(self): """ @@ -254,8 +280,9 @@ class BHGG(AbstractGame): return hgg.convert_to_NFG() @classmethod - def random_bayesian_hyper(cls, n_players, n_actions, n_type, - size_edges, connect, u_max): + def random_bayesian_hyper( + cls, n_players, n_actions, n_type, size_edges, connect, u_max + ): """ Random bayesian hypergraphical game generation. :param int n_players: Number of players of the BHGG. @@ -272,13 +299,14 @@ class BHGG(AbstractGame): """ # players_actions = [list(range(n_actions)) for n in range(n_players)] # players_theta = [list(range(n_type)) for n in range(n_players)] - nb_edge = int(connect * - (math.factorial(n_players) / - (math.factorial(size_edges) * - math.factorial(n_players - - size_edges)))) - all_poss_edges = list( - map(list, combinations(range(n_players), size_edges))) + nb_edge = int( + connect + * ( + math.factorial(n_players) + / (math.factorial(size_edges) * math.factorial(n_players - size_edges)) + ) + ) + all_poss_edges = list(map(list, combinations(range(n_players), size_edges))) hypergraph = [] np.random.shuffle(all_poss_edges) all_players = range(n_players) @@ -286,8 +314,7 @@ class BHGG(AbstractGame): while players_left or len(hypergraph) < nb_edge: e = all_poss_edges.pop() hypergraph += [e] - players_left = set(all_players).difference( - set().union(*hypergraph)) + players_left = set(all_players).difference(set().union(*hypergraph)) if len(hypergraph) == nb_edge and players_left: np.random.shuffle(hypergraph) e_remove = hypergraph.pop() @@ -312,37 +339,32 @@ class BHGG(AbstractGame): :rtype: BHGG. """ - file_read = open(file_path, 'r') + file_read = open(file_path, "r") content = file_read.read() content_list = content.split('"', 2) - if content_list[0] != 'BHGG 0 R ': - print('Ce fichier n est pas reconnu') + if content_list[0] != "BHGG 0 R ": + print("Ce fichier n est pas reconnu") else: game_info = content_list[2] - game_info_bis = ( - game_info.split( - game_info.split('\n{')[0])[1]).split('\n\n') - list_util_e = [txt_e_util.split('}\n')[-1] - for txt_e_util in game_info_bis] + game_info_bis = (game_info.split(game_info.split("\n{")[0])[1]).split( + "\n\n" + ) + list_util_e = [txt_e_util.split("}\n")[-1] for txt_e_util in game_info_bis] file_read.close() - iterTest = re.finditer('{(.*?)}', game_info) + iterTest = re.finditer("{(.*?)}", game_info) p_actions = [] p_theta = [] e_hyper = [] p_unorm = [] for i, s in enumerate(iterTest): if i == 1: - p_actions = [int(str_int) - for str_int in shlex.split(s.group(1))] + p_actions = [int(str_int) for str_int in shlex.split(s.group(1))] elif i == 2: - p_theta = [int(str_int) - for str_int in shlex.split(s.group(1))] - elif (i >= 3 and not i % 2 == 0): - e_hyper += [[int(str_int) - for str_int in shlex.split(s.group(1))]] + p_theta = [int(str_int) for str_int in shlex.split(s.group(1))] + elif i >= 3 and not i % 2 == 0: + e_hyper += [[int(str_int) for str_int in shlex.split(s.group(1))]] elif i >= 3: - p_unorm += [[int(str_int) - for str_int in shlex.split(s.group(1))]] + p_unorm += [[int(str_int) for str_int in shlex.split(s.group(1))]] util_glob = [] p_unorm_glob = [] for e_i, e in enumerate(e_hyper): @@ -350,52 +372,63 @@ class BHGG(AbstractGame): # p_actions_loc = [p_a for p_ai, # p_a in enumerate(p_actions) if p_ai in e] # n_actions_loc = np.prod(p_actions_loc) - p_theta_loc = [p_t for p_ti, - p_t in enumerate(p_theta) if p_ti in e] + p_theta_loc = [p_t for p_ti, p_t in enumerate(p_theta) if p_ti in e] n_theta_loc = np.prod(p_theta_loc) util_local = [ - [[] for nt_np in range(n_player_loc)] - for nt in range(n_theta_loc)] - tmpg_game_info = list_util_e[e_i].split('\n') - payoff_value = [[int(v_u) for v_u in st_util.split( - " ")[:-1] if v_u] for st_util in tmpg_game_info] + [[] for nt_np in range(n_player_loc)] for nt in range(n_theta_loc) + ] + tmpg_game_info = list_util_e[e_i].split("\n") + payoff_value = [ + [int(v_u) for v_u in st_util.split(" ")[:-1] if v_u] + for st_util in tmpg_game_info + ] for tu_i, tu in enumerate(payoff_value): for i, pay in enumerate(tu): util_local[tu_i][i % n_player_loc] += [pay] for i in range(n_theta_loc): util_local[i].reverse() dico_p = {} - theta_loc = [[j for j in range(p_theta_loc[i])] - for i in range(len(p_theta_loc))] + theta_loc = [ + [j for j in range(p_theta_loc[i])] for i in range(len(p_theta_loc)) + ] tmp_bg = BG([], [], [], []) joint_theta_mat = tmp_bg.generate_joint_matrix(theta_loc) joint_theta = [] for i in range(n_player_loc): - sub_joint_theta = [joint_theta_mat[j, i] - for j in - range(joint_theta_mat.shape[0])] + sub_joint_theta = [ + joint_theta_mat[j, i] for j in range(joint_theta_mat.shape[0]) + ] joint_theta.append(sub_joint_theta) for i in range(n_theta_loc): - dico_p[tuple(joint_theta[j][i] - for j in range(n_player_loc))] \ - = p_unorm[e_i][i] + dico_p[tuple(joint_theta[j][i] for j in range(n_player_loc))] = ( + p_unorm[e_i][i] + ) joint_theta.reverse() - tmp_p = [dico_p[tuple(reversed(np.array(joint_theta)[:, i]))] - for i in range(n_theta_loc)] + tmp_p = [ + dico_p[tuple(reversed(np.array(joint_theta)[:, i]))] + for i in range(n_theta_loc) + ] p_unorm_glob += [tmp_p] util_glob += [util_local] p_actions.reverse() p_theta.reverse() players_actions = [ - [j for j in range(p_actions[i])] for i in range(len(p_actions))] - players_theta = [[j for j in range(p_theta[i])] - for i in range(len(p_theta))] - old_player_to_old = {i: list(reversed(range(len(p_actions))))[i] - for i in range(len(p_actions))} - new_hypergraph = [sorted([old_player_to_old[e_n] - for e_n in e]) for e in e_hyper] - test_bhgg = BHGG(players_actions, util_glob, new_hypergraph, - players_theta, p_unorm_glob) + [j for j in range(p_actions[i])] for i in range(len(p_actions)) + ] + players_theta = [[j for j in range(p_theta[i])] for i in range(len(p_theta))] + old_player_to_old = { + i: list(reversed(range(len(p_actions))))[i] for i in range(len(p_actions)) + } + new_hypergraph = [ + sorted([old_player_to_old[e_n] for e_n in e]) for e in e_hyper + ] + test_bhgg = BHGG( + players_actions, + util_glob, + new_hypergraph, + players_theta, + p_unorm_glob, + ) return test_bhgg def write_GameFile(self, file_path): @@ -411,8 +444,10 @@ class BHGG(AbstractGame): """ p_actions = [len(subl) for subl in self.players_actions] - jact = [self.local_bayesiangames[i].joint_actions for i in range( - len(self.hypergraph))] + jact = [ + self.local_bayesiangames[i].joint_actions + for i in range(len(self.hypergraph)) + ] theta = [len(subl) for subl in self.theta] current_p = self.p_unorm # Get hypergraph @@ -426,20 +461,22 @@ class BHGG(AbstractGame): n_players_involved = len(hyperg[k]) for k_t in range(len(self.utilities[k])): util_list_k.append(self.utilities[k][k_t]) - payoffwrite.append([[util_list[k][k_t][n][i] - for i in range(len(jact[k])) - for n in reversed(range(n_players_involved))] - for k_t in range(len(self.utilities[k]))]) + payoffwrite.append( + [ + [ + util_list[k][k_t][n][i] + for i in range(len(jact[k])) + for n in reversed(range(n_players_involved)) + ] + for k_t in range(len(self.utilities[k])) + ] + ) p_actions.reverse() theta.reverse() old_player_to_old = { - i: list( - reversed( - range( - self.n_players)))[i] for i in range( - self.n_players)} - new_hypergraph = [sorted([old_player_to_old[e_n] - for e_n in e]) for e in hyperg] + i: list(reversed(range(self.n_players)))[i] for i in range(self.n_players) + } + new_hypergraph = [sorted([old_player_to_old[e_n] for e_n in e]) for e in hyperg] gamedescript = "nothing" playernames = "{" nb_actions = "{" @@ -457,22 +494,23 @@ class BHGG(AbstractGame): dico_p = {} joint_theta = [] for i in range(e.n_players): - sub_joint_theta = [e.joint_theta[j, i] - for j in range(e.n_theta)] + sub_joint_theta = [e.joint_theta[j, i] for j in range(e.n_theta)] joint_theta.append(sub_joint_theta) for i in range(e.n_theta): - dico_p[tuple(joint_theta[j][i] - for j in range(e.n_players))] = current_p[e_i][i] + dico_p[tuple(joint_theta[j][i] for j in range(e.n_players))] = ( + current_p[e_i][i] + ) joint_theta.reverse() - tmp_p = [dico_p[tuple(reversed(np.array(joint_theta)[:, i]))] - for i in range(e.n_theta)] + tmp_p = [ + dico_p[tuple(reversed(np.array(joint_theta)[:, i]))] + for i in range(e.n_theta) + ] proba = "{" for i in range(len(tmp_p)): proba += f" {tmp_p[i]}" proba += " }" all_local_p += [proba] - writeligne = \ - f'BHGG 0 R "{gamedescript}" {playernames} {nb_actions} {typ}' + writeligne = f'BHGG 0 R "{gamedescript}" {playernames} {nb_actions} {typ}' if not file_path[-5:] == ".bhgg": file_path += ".bhgg" fileTestwrite = open(file_path, "w+") @@ -480,14 +518,14 @@ class BHGG(AbstractGame): for index_hyper_edge, hyper_edge in enumerate(new_hypergraph): str_hyper_edge = "{" for play in hyper_edge: - str_hyper_edge += f' {play}' - str_hyper_edge += ' }\n' + str_hyper_edge += f" {play}" + str_hyper_edge += " }\n" fileTestwrite.write(str_hyper_edge) fileTestwrite.write(all_local_p[index_hyper_edge] + "\n") str_utilities = "" - for uti in (payoffwrite[index_hyper_edge]): + for uti in payoffwrite[index_hyper_edge]: for uti_t in uti: - str_utilities += f'{int(uti_t)} ' + str_utilities += f"{int(uti_t)} " str_utilities += "\n" fileTestwrite.write(str_utilities + "\n") fileTestwrite.close() diff --git a/gtnash/game/bayesiangame.py b/gtnash/game/bayesiangame.py index 70b4b04..0ac0ce1 100644 --- a/gtnash/game/bayesiangame.py +++ b/gtnash/game/bayesiangame.py @@ -37,15 +37,15 @@ class BG(AbstractGame): self.n_theta = 1 # len(theta[0])*len(theta[1]) for i in range(self.n_players): self.n_theta = self.n_theta * len(theta[i]) - hypergraph_temp = [[j for j in range(self.n_players)] - for i in range(self.n_theta)] + hypergraph_temp = [ + [j for j in range(self.n_players)] for i in range(self.n_theta) + ] self.joint_theta = self.generate_joint_matrix(theta) self.local_normalformgames = [] for index_hyper_edge in range(self.n_theta): self.local_normalformgames.append( - self.generate_local_normalformgame( - hypergraph_temp, - index_hyper_edge)) + self.generate_local_normalformgame(hypergraph_temp, index_hyper_edge) + ) self.joint_actions = self.generate_joint_matrix(players_actions) def generate_joint_matrix(self, into_mat): @@ -69,8 +69,7 @@ class BG(AbstractGame): one_vec = np.ones((matA.shape[0], 1)) mat = np.concatenate((int(p_i[0]) * one_vec, matA), axis=1) for action_i in p_i[1:]: - mati = np.concatenate((int(action_i) * one_vec, matA), - axis=1) + mati = np.concatenate((int(action_i) * one_vec, matA), axis=1) mat = np.concatenate((mat, mati), axis=0) matA = mat return matA.astype(int) @@ -88,12 +87,14 @@ class BG(AbstractGame): if len(self.players_actions) == 0: return NFG([], []) else: - players_action_involved = \ - [self.players_actions[hypergraph_temp[index_hyper_edge][x]] - for x in range(len(hypergraph_temp[index_hyper_edge]))] - normal_forme_game = \ - NFG(players_action_involved, - np.array(self.utilities[index_hyper_edge])) + players_action_involved = [ + self.players_actions[hypergraph_temp[index_hyper_edge][x]] + for x in range(len(hypergraph_temp[index_hyper_edge])) + ] + normal_forme_game = NFG( + players_action_involved, + np.array(self.utilities[index_hyper_edge]), + ) return normal_forme_game def proba_type(self): @@ -118,8 +119,7 @@ class BG(AbstractGame): :returns: The index of the joint type. :rtype: int. """ - return np.where(np.all(type_theta - == np.array(self.joint_theta), axis=1))[0][0] + return np.where(np.all(type_theta == np.array(self.joint_theta), axis=1))[0][0] # return np.where(np.array(type_theta)==np.array(self.joint_theta)) # np.where(action_value == @@ -142,8 +142,11 @@ class BG(AbstractGame): prob_type = 0 # tmp_theta=[t_e for n,t_e in enumerate(self.theta) # if n!=known_player ] - tmp_theta_alt = [t_e for t_e in np.array(self.joint_theta) - if t_e[known_player] == type_known_player] + tmp_theta_alt = [ + t_e + for t_e in np.array(self.joint_theta) + if t_e[known_player] == type_known_player + ] for t_e in tmp_theta_alt: prob_type += dico_p[self.get_index_of_type(t_e)] for t_e in tmp_theta_alt: @@ -186,22 +189,21 @@ class BG(AbstractGame): dico_cond = self.conditional_probabilities(n, t_n) # t_n_mixed = bayes_mixed_joint_strat[(n, t_n)] somme_util_type_n = 0 - for tmp_type in [t_e for t_e in np.array(self.joint_theta) - if t_e[n] == t_n]: + for tmp_type in [ + t_e for t_e in np.array(self.joint_theta) if t_e[n] == t_n + ]: somme_util_type_joint = 0 - proba_cond_type = \ - dico_cond[self.get_index_of_type(tmp_type)] - current_game = \ - dico_of_games[self.get_index_of_type(tmp_type)] - current_strat = \ - [bayes_mixed_joint_strat[(n_p, tmp_type[n_p])] - for n_p in range(self.n_players)] + proba_cond_type = dico_cond[self.get_index_of_type(tmp_type)] + current_game = dico_of_games[self.get_index_of_type(tmp_type)] + current_strat = [ + bayes_mixed_joint_strat[(n_p, tmp_type[n_p])] + for n_p in range(self.n_players) + ] for i_ja, ja in enumerate(np.array(self.joint_actions)): current_proba = 1 for n_a, ja_a in enumerate(list(ja)): current_proba *= current_strat[n_a][ja_a] - somme_util_type_joint += \ - current_game[n][i_ja] * current_proba + somme_util_type_joint += current_game[n][i_ja] * current_proba somme_util_type_joint *= proba_cond_type somme_util_type_n += somme_util_type_joint expected_util[(n, t_n)] = somme_util_type_n @@ -212,22 +214,19 @@ class BG(AbstractGame): dico_cond = self.conditional_probabilities(n, t_n) # t_n_mixed = bayes_mixed_joint_strat[(n, t_n)] somme_util_type_n = 0 - for tmp_type in [t_e for t_e in np.array(self.joint_theta) - if t_e[n] == t_n]: + for tmp_type in [t_e for t_e in np.array(self.joint_theta) if t_e[n] == t_n]: somme_util_type_joint = 0 - proba_cond_type = \ - dico_cond[self.get_index_of_type(tmp_type)] - current_game = \ - dico_of_games[self.get_index_of_type(tmp_type)] - current_strat = \ - [bayes_mixed_joint_strat[(n_p, tmp_type[n_p])] - for n_p in range(self.n_players)] + proba_cond_type = dico_cond[self.get_index_of_type(tmp_type)] + current_game = dico_of_games[self.get_index_of_type(tmp_type)] + current_strat = [ + bayes_mixed_joint_strat[(n_p, tmp_type[n_p])] + for n_p in range(self.n_players) + ] for i_ja, ja in enumerate(np.array(self.joint_actions)): current_proba = 1 for n_a, ja_a in enumerate(list(ja)): current_proba *= current_strat[n_a][ja_a] - somme_util_type_joint += \ - current_game[n][i_ja] * current_proba + somme_util_type_joint += current_game[n][i_ja] * current_proba somme_util_type_joint *= proba_cond_type somme_util_type_n += somme_util_type_joint return somme_util_type_n @@ -250,14 +249,12 @@ class BG(AbstractGame): for type_n in range(len(self.theta[n])): for a_i in range(len(self.players_actions[n])): other_strategy = bayes_mixed_joint_strat.copy() - other_strategy[(n, type_n)] = \ - np.zeros(len(self.players_actions[n])) + other_strategy[(n, type_n)] = np.zeros(len(self.players_actions[n])) other_strategy[(n, type_n)][a_i] = 1 - expected_util_of_other = \ - self.expected_utilities_of_n_t(n, type_n, - other_strategy) - if expected_util_of_other \ - > current_exp_util[(n, type_n)] + gap: + expected_util_of_other = self.expected_utilities_of_n_t( + n, type_n, other_strategy + ) + if expected_util_of_other > current_exp_util[(n, type_n)] + gap: return False return True @@ -292,18 +289,21 @@ class BG(AbstractGame): for n, n_type in enumerate(t_joint): local_player += [player_to_new_index[(n, n_type)]] current_prob = cond_proba[player_to_new_index[(n, n_type)]][ - self.get_index_of_type(list(t_joint))] + self.get_index_of_type(list(t_joint)) + ] local_game += [[current_prob * u for u in tmp_current_util[n]]] hypergraph += [local_player] util += [local_game] if self.n_players == 2: - return PMG(new_players_actions, util, hypergraph), \ - index_to_old_player + return ( + PMG(new_players_actions, util, hypergraph), + index_to_old_player, + ) return HGG(new_players_actions, util, hypergraph), index_to_old_player @classmethod def random_game(cls, n_players, n_actions, n_type, u_max): - """ Random bayesian game generation. + """Random bayesian game generation. .. WARNING:: @@ -318,7 +318,7 @@ class BG(AbstractGame): for t_e in range(n_type_joint): tmp_t_e1 = [] for n in range(n_players): - tmp_t_e1 += [list(np.random.randint(0, u_max, n_actions ** 2))] + tmp_t_e1 += [list(np.random.randint(0, u_max, n_actions**2))] util += [tmp_t_e1] prob_p += [Fraction(1, n_type_joint)] @@ -326,7 +326,7 @@ class BG(AbstractGame): @classmethod def random_bayesian(cls, n_player, n_action, n_type, u_max): - """ Random bayesian game generation. + """Random bayesian game generation. .. WARNING:: @@ -335,11 +335,13 @@ class BG(AbstractGame): """ player_actions = [] player_thetas = [] - nb_theta = n_type ** n_player - nb_actions = n_action ** n_player + nb_theta = n_type**n_player + nb_actions = n_action**n_player theta_p = np.random.dirichlet([1 for i in range(nb_theta)]) - util = [[list(np.random.randint(0, u_max, nb_actions)) - for n in range(n_player)] for j_type in range(nb_theta)] + util = [ + [list(np.random.randint(0, u_max, nb_actions)) for n in range(n_player)] + for j_type in range(nb_theta) + ] for n in range(n_player): player_actions += [[n_a for n_a in range(n_action)]] player_thetas += [[n_t for n_t in range(n_type)]] @@ -361,37 +363,33 @@ class BG(AbstractGame): :rtype: list of lists of lists of integers. """ - file_read = open(file_path, 'r') + file_read = open(file_path, "r") content = file_read.read() content_list = content.split('"', 2) - if content_list[0] != 'BG 0 R ': - print('Ce fichier n est pas reconnu') + if content_list[0] != "BG 0 R ": + print("Ce fichier n est pas reconnu") util_table = None else: game_info = content_list[2] - game_info_bis = game_info.split(game_info.split('}\n')[1])[1] + game_info_bis = game_info.split(game_info.split("}\n")[1])[1] file_read.close() - iterTest = re.finditer('{(.*?)}', game_info) + iterTest = re.finditer("{(.*?)}", game_info) p_actions = [] p_theta = [] p_unorm = [] for i, s in enumerate(iterTest): if i == 1: - p_actions = [int(str_int) - for str_int in shlex.split(s.group(1))] + p_actions = [int(str_int) for str_int in shlex.split(s.group(1))] if i == 2: - p_theta = [int(str_int) - for str_int in shlex.split(s.group(1))] + p_theta = [int(str_int) for str_int in shlex.split(s.group(1))] if i == 3: - p_unorm = [int(str_int) - for str_int in shlex.split(s.group(1))] + p_unorm = [int(str_int) for str_int in shlex.split(s.group(1))] utilities = [] # payoff_value = [] # iterTest = re.finditer('\d(.*?)\n', game_info_bis) payoff_str = game_info_bis.split("\n")[1:-1] for s in payoff_str: - payoff_value = [int(sub_int) for sub_int in s.split(" ") - if sub_int] + payoff_value = [int(sub_int) for sub_int in s.split(" ") if sub_int] n_players = len(p_actions) # Initialize the list of utility sublist_utilites = [[] for i in range(n_players)] @@ -412,23 +410,25 @@ class BG(AbstractGame): p_theta.reverse() # Reverse proba dico_p = {} - theta = [[j for j in range(p_theta[i])] - for i in range(len(p_theta))] + theta = [[j for j in range(p_theta[i])] for i in range(len(p_theta))] tmp_bg = BG([], [], [], []) joint_theta_mat = tmp_bg.generate_joint_matrix(theta) joint_theta = [] for i in range(n_players): - sub_joint_theta = [joint_theta_mat[j, i] - for j in range(joint_theta_mat.shape[0])] + sub_joint_theta = [ + joint_theta_mat[j, i] for j in range(joint_theta_mat.shape[0]) + ] joint_theta.append(sub_joint_theta) for i in range(n_theta): - dico_p[tuple(joint_theta[j][i] - for j in range(n_players))] = p_unorm[i] + dico_p[tuple(joint_theta[j][i] for j in range(n_players))] = p_unorm[i] joint_theta.reverse() - tmp_p = [dico_p[tuple(reversed(np.array(joint_theta)[:, i]))] - for i in range(n_theta)] - players_actions = [[j for j in range(p_actions[i])] - for i in range(len(p_actions))] + tmp_p = [ + dico_p[tuple(reversed(np.array(joint_theta)[:, i]))] + for i in range(n_theta) + ] + players_actions = [ + [j for j in range(p_actions[i])] for i in range(len(p_actions)) + ] util_table = BG(players_actions, utilities, theta, tmp_p) return util_table @@ -451,8 +451,9 @@ class BG(AbstractGame): p_actions = [len(subl) for subl in self.players_actions] # t_type = [len(subl) for subl in self.theta] # Get all the joint actions - jact = [self.local_normalformgames[i].joint_actions - for i in range(self.n_theta)] + jact = [ + self.local_normalformgames[i].joint_actions for i in range(self.n_theta) + ] # Get theta theta = [len(subl) for subl in self.theta] # Get p @@ -463,9 +464,12 @@ class BG(AbstractGame): for k in range(len(self.utilities)): util_list.append(self.utilities[k]) payoffwrite.append( - [util_list[k][n][i] - for i in range(len(jact[k])) - for n in reversed(range(self.n_players))]) + [ + util_list[k][n][i] + for i in range(len(jact[k])) + for n in reversed(range(self.n_players)) + ] + ) # Reverse the order of the actions p_actions.reverse() theta.reverse() @@ -479,7 +483,7 @@ class BG(AbstractGame): playernames += f' "Player {n_p}"' nb_actions += f" {n_act}" typ += f" {theta[n_p]}" - if (n_p == len(p_actions) - 1): + if n_p == len(p_actions) - 1: playernames += " }" nb_actions += " }" typ += " }" @@ -487,32 +491,33 @@ class BG(AbstractGame): dico_p = {} joint_theta = [] for i in range(self.n_players): - sub_joint_theta = [self.joint_theta[j, i] - for j in range(self.n_theta)] + sub_joint_theta = [self.joint_theta[j, i] for j in range(self.n_theta)] joint_theta.append(sub_joint_theta) for i in range(self.n_theta): - dico_p[tuple(joint_theta[j][i] - for j in range(self.n_players))] = current_p[i] + dico_p[tuple(joint_theta[j][i] for j in range(self.n_players))] = current_p[ + i + ] joint_theta.reverse() - tmp_p = [dico_p[tuple(reversed(np.array(joint_theta)[:, i]))] - for i in range(self.n_theta)] + tmp_p = [ + dico_p[tuple(reversed(np.array(joint_theta)[:, i]))] + for i in range(self.n_theta) + ] proba = "{" for i in range(len(tmp_p)): proba += f" {tmp_p[i]}" proba += " }" # Create the prolog of the file - writeligne = \ - f'BG 0 R "{gamedescript}" {playernames} {nb_actions} {typ}' - if not file_path[-3:] == '.bg': - file_path += '.bg' + writeligne = f'BG 0 R "{gamedescript}" {playernames} {nb_actions} {typ}' + if not file_path[-3:] == ".bg": + file_path += ".bg" fileTestwrite = open(file_path, "w+") fileTestwrite.write(writeligne + "\n\n") fileTestwrite.write(proba + "\n") # Create the rest for i in range(len(payoffwrite)): str_utilities = "" - for uti in (payoffwrite[i]): - str_utilities += f'{int(uti)} ' + for uti in payoffwrite[i]: + str_utilities += f"{int(uti)} " fileTestwrite.write(str_utilities + "\n") fileTestwrite.close() @@ -524,23 +529,31 @@ class BG(AbstractGame): label = [] players_id = [i for i in range(self.n_players)] for i in range(len(players_id)): - label.append('Ax'.replace("x", str(players_id[i]))) # 'A _i' + label.append("Ax".replace("x", str(players_id[i]))) # 'A _i' for i in range(len(players_id), 2 * (len(players_id))): - label.append('Ux'.replace( - "x", str(players_id[i - len(players_id)]))) - mat_utilities = \ - np.transpose(self.local_normalformgames[j].utilities) + label.append("Ux".replace("x", str(players_id[i - len(players_id)]))) + mat_utilities = np.transpose(self.local_normalformgames[j].utilities) mat_utilities = mat_utilities.astype(str) - joint_actions = \ - np.copy(self.local_normalformgames[j].joint_actions) - joint_actions = \ - self.local_normalformgames[j].joint_actions.astype(str) - tableau_final = np.concatenate((np.mat(label), - np.concatenate((joint_actions, - mat_utilities), - axis=1)), - axis=0) - print('Theta', j, '=', self.joint_theta[j], - 'and P(Theta', j, ') =', - self.p[j], '\n', tableau_final, '\n') - return '\n Type: \n' + str(self.theta) + joint_actions = np.copy(self.local_normalformgames[j].joint_actions) + joint_actions = self.local_normalformgames[j].joint_actions.astype(str) + tableau_final = np.concatenate( + ( + np.mat(label), + np.concatenate((joint_actions, mat_utilities), axis=1), + ), + axis=0, + ) + print( + "Theta", + j, + "=", + self.joint_theta[j], + "and P(Theta", + j, + ") =", + self.p[j], + "\n", + tableau_final, + "\n", + ) + return "\n Type: \n" + str(self.theta) diff --git a/gtnash/game/graphicalgame.py b/gtnash/game/graphicalgame.py index fa77ce4..c128ec3 100644 --- a/gtnash/game/graphicalgame.py +++ b/gtnash/game/graphicalgame.py @@ -34,7 +34,7 @@ class GG(HGG): if HGG.is_GG(HGG(players_actions, utilities, hypergraph)): super().__init__(players_actions, utilities, hypergraph) else: - print('It is not a graphical game, please used HGG class') + print("It is not a graphical game, please used HGG class") def read_GameFile(self, file_path): """ @@ -56,42 +56,46 @@ class GG(HGG): """ # Read file - file_read = open(file_path, 'r') + file_read = open(file_path, "r") content = file_read.read() content_list = content.split('"', 2) - if content_list[0] != 'GG 0 R ': - print('Ce fichier n est pas reconnu') + if content_list[0] != "GG 0 R ": + print("Ce fichier n est pas reconnu") else: game_info = content_list[2] - game_info_bis = game_info.split(game_info.split('\n{')[0])[1] + game_info_bis = game_info.split(game_info.split("\n{")[0])[1] file_read.close() - iterTest = re.finditer('{(.*?)}', game_info) + iterTest = re.finditer("{(.*?)}", game_info) p_actions = [] # Get the name and actions of the players for i, s in enumerate(iterTest): # Pas très sur du calcul de p_actions if i == 1: - p_actions = [int(str_int) for str_int in - shlex.split(s.group(1))] + p_actions = [int(str_int) for str_int in shlex.split(s.group(1))] # Création de la liste de liste hypergraph - iterTest = re.finditer('\n{1,}{(.*?)}', - (game_info.split("\n{1,}")[0]).replace(',', - '')) + iterTest = re.finditer( + "\n{1,}{(.*?)}", + (game_info.split("\n{1,}")[0]).replace(",", ""), + ) hypergraph = [] for i, s in enumerate(iterTest): - sublist_hypergraph = [int(sub_int) for sub_int in - s.group(1).strip('\n').split(" ") if - sub_int] + sublist_hypergraph = [ + int(sub_int) + for sub_int in s.group(1).strip("\n").split(" ") + if sub_int + ] hypergraph.append(sublist_hypergraph) # Création de la liste de liste de liste des utilités utilities = [] - iterTest = re.finditer('}\n(.*?)\n', game_info_bis) + iterTest = re.finditer("}\n(.*?)\n", game_info_bis) # Get the string of payoff, an iterator is use but there # is only 1 element to iterate on for i, s in enumerate(iterTest): - sublist_utilites = [int(sub_int) for sub_int in - s.group(1).strip('\n').split(" ") if - sub_int] + sublist_utilites = [ + int(sub_int) + for sub_int in s.group(1).strip("\n").split(" ") + if sub_int + ] n_players = len(hypergraph[i]) # Initialize the list of utility subsublist_utilities = [] @@ -100,7 +104,8 @@ class GG(HGG): subsublist_utilities.append(sublist_utilites) else: subsublist_utilities.append( - list(np.zeros(len(sublist_utilites)))) + list(np.zeros(len(sublist_utilites))) + ) # According to the way the utility are written # in the nfg file get for each player their utility utilities.append(subsublist_utilities) @@ -110,13 +115,13 @@ class GG(HGG): p_actions.reverse() # Generate list of actions like [[0,1,2][0,1][0,1,2,4]] # (for 3 player where one they have 3,2 and 4 actions) - players_actions = [[j for j in range(p_actions[i])] for i in - range(len(p_actions))] + players_actions = [ + [j for j in range(p_actions[i])] for i in range(len(p_actions)) + ] self.players_actions = players_actions self.utilities = utilities self.hypergraph = hypergraph - util_table = GG(self.players_actions, self.utilities, - self.hypergraph) + util_table = GG(self.players_actions, self.utilities, self.hypergraph) return util_table def write_GameFile(self, file_path): @@ -132,8 +137,10 @@ class GG(HGG): # n_players = len(self.players_actions) p_actions = [len(subl) for subl in self.players_actions] # Get all the joint actions - jact = [self.local_normalformgames[i].joint_actions for i in - range(len(self.hypergraph))] + jact = [ + self.local_normalformgames[i].joint_actions + for i in range(len(self.hypergraph)) + ] # Get hypergraph hyperg = self.hypergraph # Get the utilities as a list @@ -142,8 +149,13 @@ class GG(HGG): for k in range(len(hyperg)): util_list.append(self.utilities[k]) n_players_involved = len(hyperg[k]) - payoffwrite.append([util_list[k][n][i] for i in range(len(jact[k])) - for n in reversed(range(n_players_involved))]) + payoffwrite.append( + [ + util_list[k][n][i] + for i in range(len(jact[k])) + for n in reversed(range(n_players_involved)) + ] + ) # Reverse the order of the actions p_actions.reverse() # Create a string that correspond to the utility of @@ -159,23 +171,25 @@ class GG(HGG): nb_actions += " }" # Create the prologue of the file writeligne = f'GG 0 R "{gamedescript}" {playernames} {nb_actions}' - fileTestwrite = open(file_path + '.gg', "w+") + fileTestwrite = open(file_path + ".gg", "w+") fileTestwrite.write(writeligne + "\n") # Create the rest for index_hyper_edge, hyper_edge in enumerate(hyperg): str_hyper_edge = "{" for play in hyper_edge: - str_hyper_edge += f' {play}' - str_hyper_edge += ' }\n' + str_hyper_edge += f" {play}" + str_hyper_edge += " }\n" fileTestwrite.write(str_hyper_edge) str_utilities = "" for j in range(len(hyperg[index_hyper_edge])): if hyperg[index_hyper_edge][j] == index_hyper_edge: index_begin = len(hyperg[index_hyper_edge]) - j - 1 for index_uti in range( - len(payoffwrite[index_hyper_edge]) // len(hyper_edge)): + len(payoffwrite[index_hyper_edge]) // len(hyper_edge) + ): uti = payoffwrite[index_hyper_edge][ - index_uti * len(hyper_edge) + index_begin] - str_utilities += f'{int(uti)} ' + index_uti * len(hyper_edge) + index_begin + ] + str_utilities += f"{int(uti)} " fileTestwrite.write(str_utilities + "\n") fileTestwrite.close() diff --git a/gtnash/game/hypergraphicalgame.py b/gtnash/game/hypergraphicalgame.py index f323418..b23a7cd 100644 --- a/gtnash/game/hypergraphicalgame.py +++ b/gtnash/game/hypergraphicalgame.py @@ -1,4 +1,3 @@ - from gtnash.game.abstractgame import AbstractGame from gtnash.game.normalformgame import NFG from itertools import combinations @@ -26,10 +25,8 @@ class HGG(AbstractGame): """ - def __init__(self, players_actions, utilities, hypergraph, - index_to_player={}): - """Hypergraphical game constructor. - """ + def __init__(self, players_actions, utilities, hypergraph, index_to_player={}): + """Hypergraphical game constructor.""" self.n_players = len(players_actions) self.players_actions = players_actions self.hypergraph = hypergraph @@ -37,7 +34,8 @@ class HGG(AbstractGame): self.local_normalformgames = [] for index_hyper_edge, hyper_edge in enumerate(hypergraph): self.local_normalformgames.append( - self.generate_local_normalformgame(index_hyper_edge)) + self.generate_local_normalformgame(index_hyper_edge) + ) if not index_to_player: self.index_to_player = {i: i for i in range(self.n_players)} else: @@ -59,8 +57,7 @@ class HGG(AbstractGame): :rtype: HGG. """ players_actions = [list(range(nactions)) for n in range(nplayers)] - all_poss_edges = list(map(list, combinations(range(nplayers), - size_edges))) + all_poss_edges = list(map(list, combinations(range(nplayers), size_edges))) hypergraph = [] np.random.shuffle(all_poss_edges) players_left = set(range(nplayers)) @@ -72,8 +69,9 @@ class HGG(AbstractGame): for e in hypergraph: local_utility = [] for n in e: - local_utility.append(list(np.random.randint(0, utilmax, - nactions**len(e)))) + local_utility.append( + list(np.random.randint(0, utilmax, nactions ** len(e))) + ) utilities.append(local_utility) shifted_utilities = deepcopy(utilities) for g in range(len(utilities)): @@ -83,15 +81,16 @@ class HGG(AbstractGame): return HGG(players_actions, shifted_utilities, hypergraph) @classmethod - def random_hyperconnect(cls, n_players, n_actions, - size_edges, connect, u_max): + def random_hyperconnect(cls, n_players, n_actions, size_edges, connect, u_max): players_actions = [list(range(n_actions)) for n in range(n_players)] - nb_edge = int(connect * - (math.factorial(n_players) / - (math.factorial(size_edges) * - math.factorial(n_players - size_edges)))) - all_poss_edges = list(map(list, combinations(range(n_players), - size_edges))) + nb_edge = int( + connect + * ( + math.factorial(n_players) + / (math.factorial(size_edges) * math.factorial(n_players - size_edges)) + ) + ) + all_poss_edges = list(map(list, combinations(range(n_players), size_edges))) hypergraph = [] np.random.shuffle(all_poss_edges) all_players = range(n_players) @@ -99,15 +98,16 @@ class HGG(AbstractGame): while players_left or len(hypergraph) < nb_edge: e = all_poss_edges.pop() hypergraph += [e] - players_left = set(all_players).difference( - set().union(*hypergraph)) + players_left = set(all_players).difference(set().union(*hypergraph)) if len(hypergraph) == nb_edge and players_left: np.random.shuffle(hypergraph) e_remove = hypergraph.pop() all_poss_edges.insert(-1, e_remove) np.random.shuffle(all_poss_edges) - utilities = [[list(np.random.randint(0, u_max, n_actions**len(e))) - for n in e]for e in hypergraph] + utilities = [ + [list(np.random.randint(0, u_max, n_actions ** len(e))) for n in e] + for e in hypergraph + ] return HGG(players_actions, utilities, hypergraph) def generate_local_normalformgame(self, index_hyper_edge): @@ -120,12 +120,13 @@ class HGG(AbstractGame): :returns: Normal-form game *normal_forme_game*. :rtype: NFG. """ - players_action_involved = [self.players_actions[ - self.hypergraph[index_hyper_edge][x]] - for x in range(len(self.hypergraph[ - index_hyper_edge]))] - normal_form_game = NFG(players_action_involved, - self.utilities[index_hyper_edge]) + players_action_involved = [ + self.players_actions[self.hypergraph[index_hyper_edge][x]] + for x in range(len(self.hypergraph[index_hyper_edge])) + ] + normal_form_game = NFG( + players_action_involved, self.utilities[index_hyper_edge] + ) return normal_form_game def joint_action_except_i(self, player_ind): @@ -146,8 +147,10 @@ class HGG(AbstractGame): i = i + 1 player_ind_joint = i list_joint_action_except_i.append( - self.local_normalformgames[index_hyper_edge] - .joint_action_except_i(player_ind_joint)) + self.local_normalformgames[index_hyper_edge].joint_action_except_i( + player_ind_joint + ) + ) else: list_joint_action_except_i.append([]) return list_joint_action_except_i @@ -165,20 +168,23 @@ class HGG(AbstractGame): """ somme_expected_util = [0 for i in range(self.n_players)] for index_hyper_edge, hyper_edge in enumerate(self.hypergraph): - mixed_joint_strat_involved = {i: mixed_joint_strat[n] - for i, n in enumerate(hyper_edge)} + mixed_joint_strat_involved = { + i: mixed_joint_strat[n] for i, n in enumerate(hyper_edge) + } local_normalgame = self.local_normalformgames[index_hyper_edge] - expected_util_local = \ - local_normalgame.expected_utilities(mixed_joint_strat_involved) + expected_util_local = local_normalgame.expected_utilities( + mixed_joint_strat_involved + ) compteur = 0 expected_util = [0 for i in range(self.n_players)] for play in range(self.n_players): if play in hyper_edge: expected_util[play] = expected_util_local[compteur] compteur = compteur + 1 - somme_expected_util = \ - [exputil + expected_util[n] - for n, exputil in enumerate(somme_expected_util)] + somme_expected_util = [ + exputil + expected_util[n] + for n, exputil in enumerate(somme_expected_util) + ] return somme_expected_util def expected_utilities_of_n(self, n, mixed_joint_strat): @@ -194,15 +200,17 @@ class HGG(AbstractGame): """ somme_expected_util = 0 for index_hyper_edge, hyper_edge in enumerate(self.hypergraph): - mixed_joint_strat_involved = {i: mixed_joint_strat[n] - for i, n in enumerate(hyper_edge)} + mixed_joint_strat_involved = { + i: mixed_joint_strat[n] for i, n in enumerate(hyper_edge) + } local_normalgame = self.local_normalformgames[index_hyper_edge] # expected_util_local = \ # local_normalgame.expected_utilities(mixed_joint_strat_involved) if n in hyper_edge: n_loc = hyper_edge.index(n) exp_util = local_normalgame.expected_utilities_of_n( - n_loc, mixed_joint_strat_involved) + n_loc, mixed_joint_strat_involved + ) else: exp_util = 0 # compteur = 0 @@ -216,7 +224,7 @@ class HGG(AbstractGame): return somme_expected_util def util_of_joint_action(self, n, jact): - """ Return the utility of the player n for a given joint action + """Return the utility of the player n for a given joint action :param int n: Index of the player whose utility is computed :param list jact: List of the actions played @@ -231,7 +239,8 @@ class HGG(AbstractGame): n_in_local = hyper_edge.index(n) sub_jact = [jact[ne] for ne in hyper_edge] somme_util += local_normalgame.util_of_joint_action( - n_in_local, sub_jact) + n_in_local, sub_jact + ) return somme_util def is_equilibrium(self, mixed_joint_strategy, gap=0.0001): @@ -245,18 +254,21 @@ class HGG(AbstractGame): equilibrium and *False* if not. :rtype: boolean. """ - expected_util_of_mixed_joint_strategy =\ - self.expected_utilities(mixed_joint_strategy) + expected_util_of_mixed_joint_strategy = self.expected_utilities( + mixed_joint_strategy + ) for play in range(self.n_players): for ai in range(len(self.players_actions[play])): other_strategy = mixed_joint_strategy.copy() - other_strategy[play] = np.zeros(len( - mixed_joint_strategy[play])) + other_strategy[play] = np.zeros(len(mixed_joint_strategy[play])) other_strategy[play][ai] = 1 expected_util_of_other = self.expected_utilities_of_n( - play, other_strategy) - if not (expected_util_of_other <= - expected_util_of_mixed_joint_strategy[play] + gap): + play, other_strategy + ) + if not ( + expected_util_of_other + <= expected_util_of_mixed_joint_strategy[play] + gap + ): return False return True @@ -276,8 +288,7 @@ class HGG(AbstractGame): alt_jact = tmp_nfg.all_response_of_player(n, pure_joint_strategy) currentutil = self.util_of_joint_action(n, pure_joint_strategy) for tmp_jact in alt_jact.tolist(): - if not (self.util_of_joint_action(n, tmp_jact) <= - currentutil + gap): + if not (self.util_of_joint_action(n, tmp_jact) <= currentutil + gap): return False return True @@ -293,10 +304,13 @@ class HGG(AbstractGame): all_pne = [] all_pure_strat = list(itertools.product(*self.players_actions)) for pure_strat in all_pure_strat: - tmp_dic_strat = {i: [1 if self.players_actions[i][s_i] == s else 0 - for s_i in - range(len(self.players_actions[i]))] - for i, s in enumerate(pure_strat)} + tmp_dic_strat = { + i: [ + 1 if self.players_actions[i][s_i] == s else 0 + for s_i in range(len(self.players_actions[i])) + ] + for i, s in enumerate(pure_strat) + } if self.is_pure_equilibrium(list(pure_strat)): all_pne += [tmp_dic_strat] return all_pne @@ -326,9 +340,12 @@ class HGG(AbstractGame): all_pure_strat = list(itertools.product(*self.players_actions)) for pure_strat in all_pure_strat: tmp_dic_strat = { - i: [1 if self.players_actions[i][s_i] == s else 0 - for s_i in range(len(self.players_actions[i]))] for - i, s in enumerate(pure_strat)} + i: [ + 1 if self.players_actions[i][s_i] == s else 0 + for s_i in range(len(self.players_actions[i])) + ] + for i, s in enumerate(pure_strat) + } if self.is_pure_equilibrium(list(pure_strat)): return tmp_dic_strat return {} @@ -351,9 +368,9 @@ class HGG(AbstractGame): while player != hyper_edge[i]: i = i + 1 player_ind_joint = i - util[index_hyper_edge] =\ - self.local_normalformgames[ - index_hyper_edge].utilities[player_ind_joint] + util[index_hyper_edge] = self.local_normalformgames[ + index_hyper_edge + ].utilities[player_ind_joint] return util def build_subgame(self, partial_mixed_strategy): @@ -379,8 +396,7 @@ class HGG(AbstractGame): for s in set_s: t = self.index_of_player_in_local(s)[e] local_partial_mixed_strategy[t] = partial_mixed_strategy[s] - localsubgame = localgame.build_subgame( - local_partial_mixed_strategy) + localsubgame = localgame.build_subgame(local_partial_mixed_strategy) utilities[e] = localsubgame.utilities else: utilities[e] = self.utilities[e] @@ -427,16 +443,20 @@ class HGG(AbstractGame): :returns: Reduced hypergraphical game. :rtype: HGG. """ - new_player_actions = [[n_act_a - for n_act_i, n_act_a in enumerate(n_act) - if played_strat[n][n_act_i] == 1] - for n, n_act in enumerate(self.players_actions)] + new_player_actions = [ + [ + n_act_a + for n_act_i, n_act_a in enumerate(n_act) + if played_strat[n][n_act_i] == 1 + ] + for n, n_act in enumerate(self.players_actions) + ] new_util = [] for i_e, e in enumerate(self.hypergraph): - local_played_strat = {n_loc: played_strat[n] - for n_loc, n in enumerate(e)} - local_nfg = self.local_normalformgames[i_e].\ - get_subgame_fixed_strat(local_played_strat) + local_played_strat = {n_loc: played_strat[n] for n_loc, n in enumerate(e)} + local_nfg = self.local_normalformgames[i_e].get_subgame_fixed_strat( + local_played_strat + ) new_util += [local_nfg.utilities] return HGG(new_player_actions, new_util, self.hypergraph) @@ -490,8 +510,9 @@ class HGG(AbstractGame): local_ind = self.local_game_of_player_n(player_ind) index_game_to_local_index_player = {} for ind in local_ind: - index_game_to_local_index_player[ind] = \ - self.hypergraph[ind].index(player_ind) + index_game_to_local_index_player[ind] = self.hypergraph[ind].index( + player_ind + ) return index_game_to_local_index_player def get_subgame_level(self, proba): @@ -509,13 +530,13 @@ class HGG(AbstractGame): new_sub_util = [] for i, subli in enumerate(self.hypergraph): if i in local_ind: - local_prob = [proba[sub_player_ind] - for sub_player_ind in self.hypergraph[i]] + local_prob = [ + proba[sub_player_ind] for sub_player_ind in self.hypergraph[i] + ] local_game = self.local_normalformgames[i] new_g = local_game.get_subgame_level(local_prob) new_sub_util += [new_g.utilities] - new_sub_hyper += [[p for p in subli if p != - self.n_players - 1]] + new_sub_hyper += [[p for p in subli if p != self.n_players - 1]] else: new_sub_util += [self.utilities[i]] new_sub_hyper += [subli] @@ -547,21 +568,24 @@ class HGG(AbstractGame): new_index_to_player_id[p] = p for i, subli in enumerate(self.hypergraph): if i in local_ind: - local_prob = [proba[sub_player_ind] - for sub_player_ind in self.hypergraph[i]] + local_prob = [ + proba[sub_player_ind] for sub_player_ind in self.hypergraph[i] + ] local_game = self.local_normalformgames[i] - new_g = local_game.get_subgame_without_n(local_prob, - ind_in_local[i]) + new_g = local_game.get_subgame_without_n(local_prob, ind_in_local[i]) new_sub_util += [new_g.utilities] - new_sub_hyper += [[old_playerindex_to_new[p] - for p in subli if p != player_ind]] + new_sub_hyper += [ + [old_playerindex_to_new[p] for p in subli if p != player_ind] + ] else: new_sub_util += [self.utilities[i]] new_sub_hyper += [[old_playerindex_to_new[p] for p in subli]] - return HGG([p_act - for i, p_act in enumerate(self.players_actions) - if i != player_ind], - new_sub_util, new_sub_hyper, new_index_to_player_id) + return HGG( + [p_act for i, p_act in enumerate(self.players_actions) if i != player_ind], + new_sub_util, + new_sub_hyper, + new_index_to_player_id, + ) def get_player_interact(self, player_index): """ @@ -628,16 +652,25 @@ class HGG(AbstractGame): return False else: for index_hyper_edge in range(len(self.hypergraph)): - for index_play in range(self.local_normalformgames - [index_hyper_edge].n_players): - if self.hypergraph[index_hyper_edge][index_play] ==\ - index_hyper_edge: - if (self.local_normalformgames[index_hyper_edge]. - utilities[index_play]).any() == 0: + for index_play in range( + self.local_normalformgames[index_hyper_edge].n_players + ): + if ( + self.hypergraph[index_hyper_edge][index_play] + == index_hyper_edge + ): + if ( + self.local_normalformgames[index_hyper_edge].utilities[ + index_play + ] + ).any() == 0: return False else: - if (self.local_normalformgames[index_hyper_edge]. - utilities[index_play]).all() != 0: + if ( + self.local_normalformgames[index_hyper_edge].utilities[ + index_play + ] + ).all() != 0: return False return True @@ -665,8 +698,10 @@ class HGG(AbstractGame): for n in range(self.n_players): nb_actglob *= len(self.players_actions[n]) tmp_util += [[]] - tmp_nfg = NFG(self.players_actions, [[0 for j in range(nb_actglob)] - for n in range(self.n_players)]) + tmp_nfg = NFG( + self.players_actions, + [[0 for j in range(nb_actglob)] for n in range(self.n_players)], + ) for i in range(nb_actglob): jact_i = list(np.array(tmp_nfg.joint_actions[i])[0]) prob_jact_i = {} @@ -697,8 +732,9 @@ class HGG(AbstractGame): """ if isinstance(nfgame, NFG): hypergraph = [[play for play in range(nfgame.n_players)]] - hypergraphical_game = HGG(nfgame.players_actions, - [nfgame.utilities], hypergraph) + hypergraphical_game = HGG( + nfgame.players_actions, [nfgame.utilities], hypergraph + ) else: hypergraphical_game, index_to_old_player = nfgame.convert_to_HGG() @@ -726,16 +762,21 @@ class HGG(AbstractGame): for n_i, n in enumerate(e): u_p = local_util[n_i] player_to_list_denom[n].update( - [f_val.denominator if isinstance(f_val, Fraction) else 1 - for f_val in u_p]) - player_to_lcm = {n: np.lcm.reduce(list(player_to_list_denom[n])) - for n in range(self.n_players)} + [ + f_val.denominator if isinstance(f_val, Fraction) else 1 + for f_val in u_p + ] + ) + player_to_lcm = { + n: np.lcm.reduce(list(player_to_list_denom[n])) + for n in range(self.n_players) + } for e_i, e in enumerate(self.hypergraph): local_util = self.utilities[e_i] empty_local = [] for n_i, n in enumerate(e): util_e_ni = np.array(local_util[n_i]) - u_p0 = (util_e_ni * player_to_lcm[n]).astype('int') + u_p0 = (util_e_ni * player_to_lcm[n]).astype("int") empty_local += [list(u_p0)] util_int += [empty_local] return HGG(self.players_actions, util_int, self.hypergraph) @@ -755,37 +796,36 @@ class HGG(AbstractGame): :rtype: HGG. """ # Read file - file_read = open(file_path, 'r') + file_read = open(file_path, "r") content = file_read.read() # List of content (3 String: NFG, string and rest) content_list = content.split('"', 2) game_info = content_list[2] - game_info_bis = game_info.split(game_info.split('\n{')[0])[1] + game_info_bis = game_info.split(game_info.split("\n{")[0])[1] file_read.close() - iterTest = re.finditer('{(.*?)}', game_info) + iterTest = re.finditer("{(.*?)}", game_info) p_actions = [] # Get the name and actions of the players for i, s in enumerate(iterTest): if i == 1: - p_actions = [int(str_int) - for str_int in shlex.split(s.group(1))] - iterTest = re.finditer('\n{1,}{(.*?)}', - (game_info.split("\n{1,}")[0]).replace(',', '')) + p_actions = [int(str_int) for str_int in shlex.split(s.group(1))] + iterTest = re.finditer( + "\n{1,}{(.*?)}", (game_info.split("\n{1,}")[0]).replace(",", "") + ) hypergraph = [] for i, s in enumerate(iterTest): - sublist_hypergraph = [int(sub_int) - for sub_int in - s.group(1).strip('\n').split(" ") if sub_int] + sublist_hypergraph = [ + int(sub_int) for sub_int in s.group(1).strip("\n").split(" ") if sub_int + ] hypergraph.append(sublist_hypergraph) utilities = [] - iterTest = re.finditer('}\n(.*?)\n', game_info_bis) + iterTest = re.finditer("}\n(.*?)\n", game_info_bis) # Get the string of payoff, an iterator is used # but there is only 1 element to iterate on for i, s in enumerate(iterTest): - sublist_utilites = [int(sub_int) - for sub_int in - s.group(1).strip('\n').split(" ") - if sub_int] + sublist_utilites = [ + int(sub_int) for sub_int in s.group(1).strip("\n").split(" ") if sub_int + ] n_players = len(hypergraph[i]) # Initialize the list of utility subsublist_utilities = [[] for i in range(n_players)] @@ -802,12 +842,15 @@ class HGG(AbstractGame): p_actions.reverse() # Generate list of actions like [[0,1,2][0,1][0,1,2,4]] # (for 3 player where one they have 3,2 and 4 actions) - players_actions = [[j for j in range(p_actions[i])] - for i in range(len(p_actions))] - old_player_to_old = {i: list(reversed(range(len(p_actions))))[i] - for i in range(len(p_actions))} - new_hypergraph = [sorted([old_player_to_old[e_n] for e_n in e]) - for e in hypergraph] + players_actions = [ + [j for j in range(p_actions[i])] for i in range(len(p_actions)) + ] + old_player_to_old = { + i: list(reversed(range(len(p_actions))))[i] for i in range(len(p_actions)) + } + new_hypergraph = [ + sorted([old_player_to_old[e_n] for e_n in e]) for e in hypergraph + ] return HGG(players_actions, utilities, new_hypergraph) def write_GameFile(self, file_path): @@ -826,8 +869,10 @@ class HGG(AbstractGame): n_players = len(self.players_actions) p_actions = [len(subl) for subl in self.players_actions] # Get all the joint actions - jact = [self.local_normalformgames[i].joint_actions - for i in range(len(self.hypergraph))] + jact = [ + self.local_normalformgames[i].joint_actions + for i in range(len(self.hypergraph)) + ] # Get hypergraph hyperg = self.hypergraph # Get the utilities as a list @@ -836,14 +881,19 @@ class HGG(AbstractGame): for k in range(len(hyperg)): util_list.append(self.utilities[k]) n_players_involved = len(hyperg[k]) - payoffwrite.append([util_list[k][n][i] for i in range(len(jact[k])) - for n in reversed(range(n_players_involved))]) + payoffwrite.append( + [ + util_list[k][n][i] + for i in range(len(jact[k])) + for n in reversed(range(n_players_involved)) + ] + ) # Reverse the order of the actions p_actions.reverse() - old_player_to_old = {i: list(reversed(range(n_players)))[i] - for i in range(n_players)} - new_hypergraph = [sorted([old_player_to_old[e_n] for e_n in e]) - for e in hyperg] + old_player_to_old = { + i: list(reversed(range(n_players)))[i] for i in range(n_players) + } + new_hypergraph = [sorted([old_player_to_old[e_n] for e_n in e]) for e in hyperg] # Create a string that correspond to the utility # of the player to write in the hgg file gamedescript = "nothing" @@ -866,12 +916,12 @@ class HGG(AbstractGame): for index_hyper_edge, hyper_edge in enumerate(new_hypergraph): str_hyper_edge = "{" for play in hyper_edge: - str_hyper_edge += f' {play}' - str_hyper_edge += ' }\n' + str_hyper_edge += f" {play}" + str_hyper_edge += " }\n" fileTestwrite.write(str_hyper_edge) str_utilities = "" - for uti in (payoffwrite[index_hyper_edge]): - str_utilities += f'{int(uti)} ' + for uti in payoffwrite[index_hyper_edge]: + str_utilities += f"{int(uti)} " fileTestwrite.write(str_utilities + "\n") fileTestwrite.close() @@ -883,24 +933,22 @@ class HGG(AbstractGame): label = [] players_id = self.hypergraph[j] for i in range(len(players_id)): - label.append('Ax'.replace("x", str(players_id[i]))) + label.append("Ax".replace("x", str(players_id[i]))) for i in range(len(players_id), 2 * (len(players_id))): - label.append('Ux'.replace( - "x", str(players_id[i - len(players_id)]))) - mat_utilities = \ - np.transpose(self.local_normalformgames[j].utilities) + label.append("Ux".replace("x", str(players_id[i - len(players_id)]))) + mat_utilities = np.transpose(self.local_normalformgames[j].utilities) mat_utilities = mat_utilities.astype(str) - joint_actions = \ - np.copy(self.local_normalformgames[j].joint_actions) - joint_actions = \ - self.local_normalformgames[j].joint_actions.astype(str) - tableau_final = \ - np.concatenate( - (np.mat(label), - np.concatenate((joint_actions, mat_utilities), axis=1)), - axis=0) - print('Local game ', j, ': \n', tableau_final) - return '\n Hypergraph: \n' + str(self.hypergraph) + joint_actions = np.copy(self.local_normalformgames[j].joint_actions) + joint_actions = self.local_normalformgames[j].joint_actions.astype(str) + tableau_final = np.concatenate( + ( + np.mat(label), + np.concatenate((joint_actions, mat_utilities), axis=1), + ), + axis=0, + ) + print("Local game ", j, ": \n", tableau_final) + return "\n Hypergraph: \n" + str(self.hypergraph) def normalize_utilities(self): new_util = [] @@ -908,21 +956,28 @@ class HGG(AbstractGame): for i_e, e in enumerate(self.hypergraph): util_e = self.utilities[i_e] for e_n, util_e_n in enumerate(util_e): - player_to_list_denom[e[e_n]].update([ - f_val.denominator if isinstance(f_val, Fraction) - else 1 for f_val in util_e_n]) - player_to_lcm = {n: np.lcm.reduce(list(player_to_list_denom[n])) - for n - in range(self.n_players)} + player_to_list_denom[e[e_n]].update( + [ + f_val.denominator if isinstance(f_val, Fraction) else 1 + for f_val in util_e_n + ] + ) + player_to_lcm = { + n: np.lcm.reduce(list(player_to_list_denom[n])) + for n in range(self.n_players) + } for i_e, e in enumerate(self.hypergraph): util_e = np.array(deepcopy(self.utilities[i_e])) tmp_new_e = [] for n_i, n in enumerate(e): - tmp_new_e_n = list( - (util_e[n_i] * player_to_lcm[n]).astype('int')) + tmp_new_e_n = list((util_e[n_i] * player_to_lcm[n]).astype("int")) player_to_list_denom[n].update( - [f_val.denominator for f_val in tmp_new_e_n if - isinstance(f_val, Fraction)]) + [ + f_val.denominator + for f_val in tmp_new_e_n + if isinstance(f_val, Fraction) + ] + ) tmp_new_e += [tmp_new_e_n] new_util += [tmp_new_e] return HGG(self.players_actions, new_util, self.hypergraph) diff --git a/gtnash/game/normalformgame.py b/gtnash/game/normalformgame.py index 68bb9d9..34f48dc 100644 --- a/gtnash/game/normalformgame.py +++ b/gtnash/game/normalformgame.py @@ -198,33 +198,10 @@ class NFG(AbstractGame): :rtype: list of floats. """ - expected_util = [] - for n in mixed_joint_strat.keys(): - prob_n = mixed_joint_strat[n] - util_of_n = np.copy(self.utilities[n][:]).tolist() - # Use the strategy of the other player to get the - # possible expected utility of every joint action - for nbis in mixed_joint_strat.keys(): - prob_nbis = mixed_joint_strat[nbis] - if not (nbis == n): - for j, prob_nbis_j in enumerate(prob_nbis): - index_nbis_j = self.row_where_p_is_i( - nbis, self.players_actions[nbis][j] - ) - for ind_nbis in index_nbis_j: - util_of_n[ind_nbis] = util_of_n[ind_nbis] * prob_nbis_j - # Get the expected utility of each action - value_all_i = [] - for i in range(len(prob_n)): - value_i = 0 - index_n_i = self.row_where_p_is_i(n, self.players_actions[n][i]) - for ind_n in index_n_i: - value_i += util_of_n[ind_n] - value_all_i += [value_i] - # The expected utility of the strategy - max_proba = np.array(value_all_i).dot(prob_n) - expected_util.append(max_proba) - return expected_util + return [ + self.expected_utilities_of_n(n, mixed_joint_strat) + for n in mixed_joint_strat.keys() + ] def expected_utilities_of_n(self, n, mixed_joint_strat): """Returns the expected utilities of *mixed_joint_strategy* @@ -238,6 +215,7 @@ class NFG(AbstractGame): of *mixed_joint_strategy*. :rtype: list of floats. """ + breakpoint() prob_n = mixed_joint_strat[n] util_of_n = np.copy(self.utilities[n][:]).tolist() # Use the strategy of the other player to get the diff --git a/gtnash/game/polymatrixgame.py b/gtnash/game/polymatrixgame.py index d738486..2fa54a7 100644 --- a/gtnash/game/polymatrixgame.py +++ b/gtnash/game/polymatrixgame.py @@ -17,12 +17,11 @@ class PMG(HGG): """ def __init__(self, players_actions, utilities, hypergraph): - """Polymatrix game constructor. - """ + """Polymatrix game constructor.""" if HGG.is_PMG(HGG(players_actions, utilities, hypergraph)): super().__init__(players_actions, utilities, hypergraph) else: - print('It is not a polymatrix game, please use HGG class') + print("It is not a polymatrix game, please use HGG class") def read_GameFile(self, file_path): """Using a .hgg game file (polymatrix games are specific @@ -40,7 +39,9 @@ class PMG(HGG): :rtype: list of lists of integers. """ util_table_hgg = HGG.read_GameFile(self, file_path) - util_table = PMG(util_table_hgg.players_actions, - util_table_hgg.utilities, - util_table_hgg.hypergraph) + util_table = PMG( + util_table_hgg.players_actions, + util_table_hgg.utilities, + util_table_hgg.hypergraph, + ) return util_table -- GitLab From e9155013b8a565302dc3e16758186d2c123ec135 Mon Sep 17 00:00:00 2001 From: Prasanna Maddila <maddilaprasanna10@gmail.com> Date: Wed, 13 Nov 2024 09:08:18 +0100 Subject: [PATCH 06/13] Refactored NFG.expected_utilities to use numpy operations --- gtnash/game/normalformgame.py | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/gtnash/game/normalformgame.py b/gtnash/game/normalformgame.py index 34f48dc..8cbf0cb 100644 --- a/gtnash/game/normalformgame.py +++ b/gtnash/game/normalformgame.py @@ -215,31 +215,14 @@ class NFG(AbstractGame): of *mixed_joint_strategy*. :rtype: list of floats. """ - breakpoint() - prob_n = mixed_joint_strat[n] - util_of_n = np.copy(self.utilities[n][:]).tolist() - # Use the strategy of the other player to get the - # possible expected utility of every joint action - for nbis in mixed_joint_strat.keys(): - prob_nbis = mixed_joint_strat[nbis] - if not (nbis == n): - for j, prob_nbis_j in enumerate(prob_nbis): - index_nbis_j = self.row_where_p_is_i( - nbis, self.players_actions[nbis][j] - ) - for ind_nbis in index_nbis_j: - util_of_n[ind_nbis] = util_of_n[ind_nbis] * prob_nbis_j - # Get the expected utility of each action - value_all_i = [] - for i in range(len(prob_n)): - value_i = 0 - index_n_i = self.row_where_p_is_i(n, self.players_actions[n][i]) - for ind_n in index_n_i: - value_i += util_of_n[ind_n] - value_all_i += [value_i] - # The expected utility of the strategy - max_proba = np.array(value_all_i).dot(prob_n) - return max_proba + # ravel(outer(a, b)) -> ravel([ a_i b_j ]_{n \times m}) -> [a_i b_j]_{nm \times 1} + joint_prob = None + for strat in mixed_joint_strat.values(): + if joint_prob is None: + joint_prob = np.array(strat) + else: + joint_prob = np.ravel(np.outer(joint_prob, strat)) + return np.dot(joint_prob, self.utilities[n]) # def is_equilibrium(self, mixed_joint_strategy, gap=0.0001): # """Checks whether *mixed_joint_strategy* is a Nash equilibrium. -- GitLab From 661183cf0d5f72039774ca12bc02d5f98821ec62 Mon Sep 17 00:00:00 2001 From: Prasanna Maddila <maddilaprasanna10@gmail.com> Date: Wed, 13 Nov 2024 09:37:12 +0100 Subject: [PATCH 07/13] Cleanup --- docs/source/conf.py | 35 +- gtnash/solver/lemkehowson_polymatrix.py | 115 +- gtnash/solver/pns.py | 46 +- gtnash/solver/wilsonalgorithm.py | 352 +-- gtnash/util/irda.py | 32 +- .../util/polynomial_complementary_problem.py | 117 +- pyproject.toml | 53 +- setup.py | 11 - test/test_bayesian_hypergraphicalgame.py | 768 +++++-- test/test_bayesiangame.py | 575 +++-- test/test_hypergraphicalgame.py | 1892 +++++++++++++---- test/test_irda.py | 285 ++- test/test_lh_polymatrix.py | 215 +- test/test_normalformgame.py | 508 +++-- test/test_pns.py | 524 +++-- test/test_polynomial_complementary_problem.py | 791 ++++--- test/test_wilson_algorithm.py | 222 +- 17 files changed, 4576 insertions(+), 1965 deletions(-) delete mode 100644 setup.py diff --git a/docs/source/conf.py b/docs/source/conf.py index ad753f2..2310215 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -12,22 +12,23 @@ # import os import sys -sys.path.insert(0, os.path.abspath('../../gtnash/game')) -sys.path.insert(0, os.path.abspath('../../gtnash/solver')) -sys.path.insert(0, os.path.abspath('../../gtnash/util')) -sys.path.insert(0, os.path.abspath('../../gtnash/notebook')) -sys.path.insert(0, os.path.abspath('../../gtnash')) -sys.path.insert(0, os.path.abspath('../..')) + +sys.path.insert(0, os.path.abspath("../../gtnash/game")) +sys.path.insert(0, os.path.abspath("../../gtnash/solver")) +sys.path.insert(0, os.path.abspath("../../gtnash/util")) +sys.path.insert(0, os.path.abspath("../../gtnash/notebook")) +sys.path.insert(0, os.path.abspath("../../gtnash")) +sys.path.insert(0, os.path.abspath("../..")) # -- Project information ----------------------------------------------------- -project = 'GTNash' -copyright = '2022, Paul Jourdan, Régis Sabbadin' -author = 'Paul Jourdan, Régis Sabbadin' +project = "GTNash" +copyright = "2022, Paul Jourdan, Régis Sabbadin" +author = "Paul Jourdan, Régis Sabbadin" # The full version, including alpha/beta/rc tags -release = '0.1' +release = "0.1" # -- General configuration --------------------------------------------------- @@ -38,7 +39,7 @@ release = '0.1' extensions = ["sphinx.ext.autodoc", "sphinx_rtd_theme", "sphinx_multiversion"] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. @@ -51,13 +52,13 @@ exclude_patterns = [] # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'sphinx_rtd_theme' +html_theme = "sphinx_rtd_theme" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = ["_static"] autodoc_mock_imports = ["numpy", "sage"] @@ -66,8 +67,8 @@ autodoc_mock_imports = ["numpy", "sage"] # https://github.com/Holzhaus/sphinx-multiversion # https://blog.stephane-robert.info/post/sphinx-documentation-multi-version/ -smv_tag_whitelist = r'^v\d+\.\d+.*$|latest' # tags of form v*.*.x and latest +smv_tag_whitelist = r"^v\d+\.\d+.*$|latest" # tags of form v*.*.x and latest # Whitelist pattern for branches (set to '' to ignore all branches) -smv_branch_whitelist = 'main' -smv_released_pattern = r'^tags/.*$' -smv_remote_whitelist = r'^.*$' +smv_branch_whitelist = "main" +smv_released_pattern = r"^tags/.*$" +smv_remote_whitelist = r"^.*$" diff --git a/gtnash/solver/lemkehowson_polymatrix.py b/gtnash/solver/lemkehowson_polymatrix.py index 8652fb7..2df44cd 100644 --- a/gtnash/solver/lemkehowson_polymatrix.py +++ b/gtnash/solver/lemkehowson_polymatrix.py @@ -19,7 +19,6 @@ import numpy as np import math - class LHpolymatrix: """ Polymatrix game solver using Howson algorithm @@ -54,6 +53,7 @@ class LHpolymatrix: Tucker scheme of the current game. """ + def __init__(self, game): self.n_players = game.n_players self.players_actions = game.players_actions @@ -70,16 +70,24 @@ class LHpolymatrix: # player_to_list_denom[e[0]].update([f_val.denominator # for f_val in u_p0 if type(f_val) == Fraction]) player_to_list_denom[e[0]].update( - [f_val.denominator if isinstance(f_val, Fraction) - else 1 for f_val in u_p0]) + [ + f_val.denominator if isinstance(f_val, Fraction) else 1 + for f_val in u_p0 + ] + ) u_p1 = util_e[1] # player_to_list_denom[e[1]].update([f_val.denominator # for f_val in u_p1 if type(f_val) == Fraction]) player_to_list_denom[e[1]].update( - [f_val.denominator if isinstance(f_val, Fraction) - else 1 for f_val in u_p1]) - player_to_lcm = {n: np.lcm.reduce(list(player_to_list_denom[n])) for n - in range(self.n_players)} + [ + f_val.denominator if isinstance(f_val, Fraction) else 1 + for f_val in u_p1 + ] + ) + player_to_lcm = { + n: np.lcm.reduce(list(player_to_list_denom[n])) + for n in range(self.n_players) + } # player_to_lcm = {n: np.lcm.reduce(np.array(list(player_to_list_denom[n]), dtype=np.int64)) for n # in range(self.n_players)} for i_e, e in enumerate(game.hypergraph): @@ -89,13 +97,16 @@ class LHpolymatrix: u_p0 = (util_e[0] * player_to_lcm[e[0]]).astype(np.int64) self.maxu_of_p[e[0]] = max(self.maxu_of_p[e[0]], max(u_p0)) player_to_list_denom[e[0]].update( - [f_val.denominator for f_val in u_p0 if - isinstance(f_val, Fraction)]) + [f_val.denominator for f_val in u_p0 if isinstance(f_val, Fraction)] + ) u_p1 = (util_e[1] * player_to_lcm[e[1]]).astype(np.int64) self.maxu_of_p[e[1]] = max(self.maxu_of_p[e[1]], max(u_p1)) player_to_list_denom[e[1]].update( - [f_val.denominator if isinstance(f_val, Fraction) - else 1 for f_val in u_p1]) + [ + f_val.denominator if isinstance(f_val, Fraction) else 1 + for f_val in u_p1 + ] + ) # nb_p0 = len(game.players_actions[e[0]]) nb_p1 = len(game.players_actions[e[1]]) new_util_p0 = [] @@ -116,8 +127,9 @@ class LHpolymatrix: # self.var_of_p = {} self.col_var_by_index = {} self.row_var_by_index = {} - self.tucker = np.zeros((self.m_action + self.n_players, - 1 + self.m_action + self.n_players)) + self.tucker = np.zeros( + (self.m_action + self.n_players, 1 + self.m_action + self.n_players) + ) def inverse_utilities(self): """ @@ -152,7 +164,8 @@ it is involved in. mj = len(util_of_n_e[0]) matrixE = np.ones((len(util_of_n_e), mj)).astype(np.int64).astype(object) newMatrix = util_of_n_e - ( - (self.maxu_of_p[current_n] + Fraction(1, 1)) * matrixE) + (self.maxu_of_p[current_n] + Fraction(1, 1)) * matrixE + ) newMatrix = -newMatrix return newMatrix @@ -181,29 +194,28 @@ it is involved in. actions_nbis = len(self.players_actions[nbis]) if n == nbis: schema[ - current_i:current_i + actions_n, - current_j:current_j + actions_n] =\ - np.zeros((actions_n, actions_n)) + current_i : current_i + actions_n, + current_j : current_j + actions_n, + ] = np.zeros((actions_n, actions_n)) for k in range(current_j, current_j + actions_n): # self.var_of_p[n] += # [nonbasic_str + str(k - current_j)] self.col_var[nonbasic_str + str(k - current_j)] = k + 1 - matrixu[n, current_j:current_j + actions_n] = np.ones( - actions_n) + matrixu[n, current_j : current_j + actions_n] = np.ones(actions_n) self.col_var["v" + str(n)] = self.m_action + n + 1 # self.var_of_p[n] += ["v" + str(n)] current_j = current_j + actions_n else: if nbis in list(util_of_n.keys()): schema[ - current_i:current_i + actions_n, - current_j:current_j + actions_nbis] =\ - util_of_n[nbis] + current_i : current_i + actions_n, + current_j : current_j + actions_nbis, + ] = util_of_n[nbis] current_j = current_j + actions_nbis for r in range(current_i, current_i + actions_n): self.row_var[basic_str + str(r - current_i)] = r # self.var_of_p[n] += [basic_str + str(r - current_i)] - matrixv[current_i:current_i + actions_n, n] = -np.ones(actions_n) + matrixv[current_i : current_i + actions_n, n] = -np.ones(actions_n) self.row_var["u" + str(n)] = self.m_action + n # self.var_of_p[n] += ["u" + str(n)] current_i = current_i + actions_n @@ -231,26 +243,32 @@ Lemke-Howson's algorithm. self.block_pivot(list_action) # Need to adjust value according to variable number epsilon = Fraction(1, 1000) - column_epsilon = (np.ones((self.m_action + self.n_players, 1)).astype( - np.int64).astype(object)) * epsilon + column_epsilon = ( + np.ones((self.m_action + self.n_players, 1)).astype(np.int64).astype(object) + ) * epsilon for i in range(self.m_action + self.n_players): column_epsilon[i] = column_epsilon[i] ** (i + 1) self.tucker = np.block([self.tucker, column_epsilon]) p = 0 while True: # Until a solution is returned - index_col_v = self.col_var[ - "v" + str(p)] # Step 2: Get the current v^p + index_col_v = self.col_var["v" + str(p)] # Step 2: Get the current v^p outbase = self.enter_in_base(index_col_v) # Step3: Pivot until while not self.complementary_of_p(p, list_action[p]): outvar_str = outbase[1:] - next_var_in = [s for s in list(self.col_var.keys()) if - s[1:] == outvar_str and s != outbase] - outbase = self.enter_in_base(self.col_var[next_var_in[0]],p) + next_var_in = [ + s + for s in list(self.col_var.keys()) + if s[1:] == outvar_str and s != outbase + ] + outbase = self.enter_in_base(self.col_var[next_var_in[0]], p) while outbase[0] == "v": # Step 5: Decrement p and p = p - 1 - var_of_p = [s for s in list(self.col_var.keys()) if - s[1:] == str(p) + "_" + str(list_action[p])][0] + var_of_p = [ + s + for s in list(self.col_var.keys()) + if s[1:] == str(p) + "_" + str(list_action[p]) + ][0] outbase = self.enter_in_base(self.col_var[var_of_p]) # Step 4: If p== number of players then the solution is # found otherwise increment p and go back to step 2 @@ -272,7 +290,7 @@ Lemke-Howson's algorithm. for i in range(self.n_players): x_of_i = "x" + str(i) var_base = list(self.row_var.keys()) - strat_used = [s for s in var_base if s[:1 + len(str(i))] == x_of_i] + strat_used = [s for s in var_base if s[: 1 + len(str(i))] == x_of_i] strat_i = [] for j in range(len(self.players_actions[i])): xij = x_of_i + "_" + str(j) @@ -299,7 +317,7 @@ complementary. for s in var_base: s_size = len(s) n_size = len(str(n)) - tmp_split = s[1:].split('_') + tmp_split = s[1:].split("_") # if s_size == 2+n_size+act_size and # int(s[1:s_size - act_size-1]) == n: if np.int64(tmp_split[0]) == n and s_size > (1 + n_size): @@ -327,10 +345,12 @@ this variable with the correct row. for i in range(self.n_players): varx = "x" + str(i) + "_" + str(col[i]) index_piv_col += [self.col_var[varx]] - index_nopiv_col = [x for x in self.col_var_by_index.keys() if - x not in index_piv_col] - index_nopiv_row = [x for x in self.row_var_by_index.keys() if - x not in index_piv_row] + index_nopiv_col = [ + x for x in self.col_var_by_index.keys() if x not in index_piv_col + ] + index_nopiv_row = [ + x for x in self.row_var_by_index.keys() if x not in index_piv_row + ] # Init position of the var before the pivot allcol = index_piv_col + index_nopiv_col allrow = index_piv_row + index_nopiv_row @@ -345,15 +365,18 @@ this variable with the correct row. m22 = self.tucker[np.ix_(index_nopiv_row, index_nopiv_col)] # Block Pivot invm11 = np.linalg.inv(m11) - blockPiv = np.block([[invm11, -invm11.dot(m12)], [m21.dot(invm11), - m22 - (m21.dot( - invm11.dot( - m12)))]]) + blockPiv = np.block( + [ + [invm11, -invm11.dot(m12)], + [m21.dot(invm11), m22 - (m21.dot(invm11.dot(m12)))], + ] + ) # Updating the variable position to keep track of the index self.update_var_position(new_col_var_by_index, new_row_var_by_index) self.tucker = blockPiv self.tucker = self.tucker.astype( - np.int64) # mauvaise valeur lorsque float/fraction + np.int64 + ) # mauvaise valeur lorsque float/fraction self.tucker = self.tucker.astype(object) def update_var_position(self, new_col_var_by_index, new_row_var_by_index): @@ -377,7 +400,7 @@ this variable with the correct row. self.col_var = new_col_var self.row_var = new_row_var - def enter_in_base(self, index_col,p=math.inf): + def enter_in_base(self, index_col, p=math.inf): """ Given a column index, returns the variable corresponding to the \ row that allows to pivot while respecting the positivity constraint \ @@ -392,7 +415,9 @@ and does this operation. # Get all possible pivot S={j,a_j<0} index_value_col = [] for j in range(len(col_enter)): - if col_enter[j] != 0 : # and int(self.row_var_by_index[j][1])<=p : can pivot for variable above current level Do more test for validation + if ( + col_enter[j] != 0 + ): # and int(self.row_var_by_index[j][1])<=p : can pivot for variable above current level Do more test for validation index_value_col += [j] # Get max ratio (q+epsilon)/a_j max_row_index = self.max_coefEpsilon(col_q, col_enter, index_value_col) diff --git a/gtnash/solver/pns.py b/gtnash/solver/pns.py index 86ff016..d6d8c16 100644 --- a/gtnash/solver/pns.py +++ b/gtnash/solver/pns.py @@ -38,8 +38,10 @@ Detailed description of classes and methods: """ from gtnash.util.irda import irda -from gtnash.util.polynomial_complementary_problem import\ - PolynomialComplementaryProblem, Subsystem +from gtnash.util.polynomial_complementary_problem import ( + PolynomialComplementaryProblem, + Subsystem, +) from sage.all import Subsets, OrderedPartitions, QQbar from gtnash.game.normalformgame import NFG from gtnash.game.hypergraphicalgame import HGG @@ -83,8 +85,7 @@ class PNS_solver: for support_i, current_support in enumerate(self.all_ordered_support): self.nb_of_support_enumerated += 1 support_strat = self.support_to_strategy(current_support) - support_size = sum( - [sum(support_strat[n]) for n in range(self.n_players)]) + support_size = sum([sum(support_strat[n]) for n in range(self.n_players)]) if support_size == self.n_players: supportaslist = [list(k)[0] for k in current_support] if self.game_hgg.is_pure_equilibrium(supportaslist): @@ -96,8 +97,9 @@ class PNS_solver: if not z_excluded: set_w = self.create_W_from_support_strat(support_strat) set_wb = self.create_Wb_from_support_strat(support_strat) - sub_sys = Subsystem(self.game_pcp, set_wb, set_w, - self.n_players - 1, {}) + sub_sys = Subsystem( + self.game_pcp, set_wb, set_w, self.n_players - 1, {} + ) self.nb_of_subsys_computed += 1 if len(sub_sys.solutions) > 0: self.found_support_size = support_size @@ -137,9 +139,12 @@ class PNS_solver: :returns: List of pairs *(n,n_a)* belonging to *W*. :rtype: List of tuples. """ - return [(n, n_a) for n in range(self.n_players) - for n_i, n_a in enumerate(self.players_actions[n]) - if support_strat[n][n_i] == 1] + return [ + (n, n_a) + for n in range(self.n_players) + for n_i, n_a in enumerate(self.players_actions[n]) + if support_strat[n][n_i] == 1 + ] def create_Wb_from_support_strat(self, support_strat): """Given the support of a strategy, returns the list of pairs \ @@ -151,9 +156,12 @@ class PNS_solver: :returns: List of pairs *(n,n_a)* belonging to *Z*=*Wbar*. :rtype: List of tuples. """ - return [(n, n_a) for n in range(self.n_players) - for n_i, n_a in enumerate(self.players_actions[n]) - if support_strat[n][n_i] == 0] + return [ + (n, n_a) + for n in range(self.n_players) + for n_i, n_a in enumerate(self.players_actions[n]) + if support_strat[n][n_i] == 0 + ] def support_to_strategy(self, support): """Changes the representation of the support of a strategy. @@ -164,8 +172,10 @@ support of player *n*. :returns: Dictionary of lists of 0 and 1 (1 iff action in the support). :rtype: dict. """ - return {n: [1 if n_act_i in support[n] else 0 for n_act_i in n_act] - for n, n_act in enumerate(self.players_actions)} + return { + n: [1 if n_act_i in support[n] else 0 for n_act_i in n_act] + for n, n_act in enumerate(self.players_actions) + } def balancedpartitions(n, total): @@ -179,8 +189,7 @@ def balancedpartitions(n, total): k_1+...+k_n=total and [k_i-k_j]<=1, for all i,j. :rtype: List of lists of integers. """ - return [part for part in OrderedPartitions(total, n) - if max(part) - min(part) <= 1] + return [part for part in OrderedPartitions(total, n) if max(part) - min(part) <= 1] def unbalance_partitions(n, total, m): @@ -195,8 +204,7 @@ def unbalance_partitions(n, total, m): k_1+...+k_n=total and [k_i-k_j]=m, for all i,j. :rtype: List of lists of integers. """ - return [part for part in OrderedPartitions(total, n) - if max(part) - min(part) == m] + return [part for part in OrderedPartitions(total, n) if max(part) - min(part) == m] def allbalancedpartitions(n, total): @@ -217,7 +225,7 @@ def allbalancedpartitions(n, total): def supports(domains, sizes): - """ Computes all supports of given sizes of a list of domains. + """Computes all supports of given sizes of a list of domains. :param list of lists domains: the list of full supports of all strategies. :param list of int sizes: the sizes of the partial supports. diff --git a/gtnash/solver/wilsonalgorithm.py b/gtnash/solver/wilsonalgorithm.py index 7e09206..ad604b8 100644 --- a/gtnash/solver/wilsonalgorithm.py +++ b/gtnash/solver/wilsonalgorithm.py @@ -41,8 +41,10 @@ Detailed description of classes and methods from gtnash.game.hypergraphicalgame import HGG from gtnash.game.normalformgame import NFG from gtnash.game.bayesiangame import BG -from gtnash.util.polynomial_complementary_problem import \ - PolynomialComplementaryProblem, Subsystem +from gtnash.util.polynomial_complementary_problem import ( + PolynomialComplementaryProblem, + Subsystem, +) from gtnash.util.irda import irda from sage.all import QQbar from copy import deepcopy @@ -54,6 +56,7 @@ class WilsonError(Exception): Error ``WilsonError`` is returned when the program fails for an unknown \ reason. """ + pass @@ -71,13 +74,18 @@ of xni. :rtype: list of ``Node``. """ - x_values_level_0 = {pcp.couple_to_x[(n, i)]: xpairs_val[(n, i)] for (n, i) - in pcp.couple_to_x.keys() if n > 0} + x_values_level_0 = { + pcp.couple_to_x[(n, i)]: xpairs_val[(n, i)] + for (n, i) in pcp.couple_to_x.keys() + if n > 0 + } subpcp = pcp.substitute(x_values_level_0, 0) - minval = min( - [sum(v.coefficients()) for v in subpcp.couple_to_poly.values()]) - set_w = [(n, i) for (n, i) in subpcp.couple_to_poly.keys() if - sum(subpcp.couple_to_poly[(n, i)].coefficients()) == minval] + minval = min([sum(v.coefficients()) for v in subpcp.couple_to_poly.values()]) + set_w = [ + (n, i) + for (n, i) in subpcp.couple_to_poly.keys() + if sum(subpcp.couple_to_poly[(n, i)].coefficients()) == minval + ] level = 0 sys_s = [] nextnodeslist = [] @@ -86,14 +94,16 @@ of xni. print("Several pairs can be added to W: ", set_w) if len(set_w) == 0: raise WilsonError( - "Ouch! No almost complementary point at level 0, that's strange!") - for (m, j) in set_w: + "Ouch! No almost complementary point at level 0, that's strange!" + ) + for m, j in set_w: # if (len(set_w)==1): - set_z = [(n, i) for (n, i) in subpcp.couple_to_poly.keys() if - (n, i) != (m, j)] # not in set_w] + set_z = [ + (n, i) for (n, i) in subpcp.couple_to_poly.keys() if (n, i) != (m, j) + ] # not in set_w] sols = {} sols[pcp.ring(pcp.couple_to_x[(m, j)])] = 1 - for (n, i) in set_z: + for n, i in set_z: sols[pcp.ring(pcp.couple_to_x[(n, i)])] = 0 node0 = Node(subpcp, set_z, [(m, j)], level, xpairs_val, sys_s, sols) node0.check_complementarity() @@ -196,10 +206,12 @@ def gen_only_omega_to_used(game): """ print(game.players_actions) - all_joint_actions = list(itertools.product( - *[[game.players_actions[0][0]]] + [pact for n, pact in - enumerate(game.players_actions) if - not n == 0])) + all_joint_actions = list( + itertools.product( + *[[game.players_actions[0][0]]] + + [pact for n, pact in enumerate(game.players_actions) if not n == 0] + ) + ) all_dict_joint_actions = [] for ja in all_joint_actions: joint_act_dic = {} @@ -219,7 +231,7 @@ def wilson_loop(pcpglobal): """ xpairs_val = {} - for (n, i) in pcpglobal.couple_to_x.keys(): + for n, i in pcpglobal.couple_to_x.keys(): if pcpglobal.omega0[n] == i: xpairs_val[(n, i)] = 1 else: @@ -243,29 +255,32 @@ def wilson_loop(pcpglobal): nextnode = opennodes.pop(last_var) currentnode = nextnode visitednodes.append(currentnode) - if currentnode.is_complementary and \ - currentnode.level == pcpglobal.game.n_players - 1: + if ( + currentnode.is_complementary + and currentnode.level == pcpglobal.game.n_players - 1 + ): break # we are done if currentnode.is_complementary and ( - currentnode.level == 0 or - currentnode.level >= currentnode.prev_node.level): + currentnode.level == 0 or currentnode.level >= currentnode.prev_node.level + ): nextnodeslist = currentnode.lift(pcpglobal, xpairs_val) - elif currentnode.is_initial and \ - currentnode.level <= currentnode.prev_node.level: + elif ( + currentnode.is_initial and currentnode.level <= currentnode.prev_node.level + ): nextnodeslist = currentnode.descend(currentnode.pcp, xpairs_val) # Update xpairs_val level = currentnode.level - xpairs_val[ - (level, pcpglobal.omega0[level])] = currentnode.coordinates[ - pcpglobal.couple_to_x[(level, pcpglobal.omega0[level])]] + xpairs_val[(level, pcpglobal.omega0[level])] = currentnode.coordinates[ + pcpglobal.couple_to_x[(level, pcpglobal.omega0[level])] + ] else: - nextnodeslist = currentnode.traverse(currentnode.prev_node, - xpairs_val) + nextnodeslist = currentnode.traverse(currentnode.prev_node, xpairs_val) # Deal with degeneracy, cycles or impossible pivots. if len(nextnodeslist) == 0: print( "Current path in Wilson's algorithm leads nowhere." - " We have to backtrack.") + " We have to backtrack." + ) else: if len(nextnodeslist) > 1: print("Current node is degenerate.") @@ -298,8 +313,7 @@ algorithm, as well as some statistics about this path. """ def __init__(self, n_player): - """Node path data constructor. - """ + """Node path data constructor.""" self.listZW = [] self.level_to_number_of_node = {n: 0 for n in range(n_player)} self.level_to_number_of_comp = {n: 0 for n in range(n_player)} @@ -379,13 +393,14 @@ algorithm, as well as some statistics about this path. def __str__(self): res_str = "PathData\n" res_str += f"Number of node by level: {self.level_to_number_of_node}\n" - res_str += \ - f"Number of complementary node by level:" \ + res_str += ( + f"Number of complementary node by level:" f" {self.level_to_number_of_comp}\n" - res_str += f"Number of initial node by level:" \ - f" {self.level_to_number_of_init}\n" - res_str += f"Max number of polynomials in the system:" \ - f" {self.max_size_W}\n" + ) + res_str += ( + f"Number of initial node by level:" f" {self.level_to_number_of_init}\n" + ) + res_str += f"Max number of polynomials in the system:" f" {self.max_size_W}\n" res_str += f"Is degenerate: {self.degen_encount}" return res_str @@ -425,8 +440,7 @@ class Node: """ - def __init__(self, pcp, set_z, set_w, level, xpairs_val, sys_S, - coordinates): + def __init__(self, pcp, set_z, set_w, level, xpairs_val, sys_S, coordinates): """ Creates a complementary node at level 0, from an input PCP. @@ -455,8 +469,9 @@ class Node: strnode += "\n" for n in range(self.level + 1, self.pcp.game.n_players): for i in self.pcp.game.players_actions[n]: - strnode += "xpairs_val[({0},{1})] = {2}\n".\ - format(n, i, self.xpairs_val[(n, i)]) + strnode += "xpairs_val[({0},{1})] = {2}\n".format( + n, i, self.xpairs_val[(n, i)] + ) strnode += "set_z: {0}\n".format(self.set_z) strnode += "set_w:{0}\n".format(self.set_w) strnode += "System defining the node:\n" @@ -475,7 +490,8 @@ or initial. set_z = set(self.set_z) set_w = set(self.set_w) all_couples = set( - [(n, i) for (n, i) in self.pcp.couple_to_x.keys() if n <= level]) + [(n, i) for (n, i) in self.pcp.couple_to_x.keys() if n <= level] + ) z_union_w = set_z.union(set_w) card = len(set_z) + len(set_w) is_initial = False @@ -485,12 +501,13 @@ or initial. if z_union_w == all_couples: is_complementary = True if all_couples.difference(z_union_w).issubset( - set([(level, self.pcp.omega0[level])])): + set([(level, self.pcp.omega0[level])]) + ): is_almost_complementary = True if is_complementary or is_almost_complementary: if (level, omega0level) not in set_z: is_initial = True - for (n, i) in all_couples: + for n, i in all_couples: if n == level and i != omega0level: if (n, i) not in set_z: is_initial = False @@ -518,22 +535,27 @@ or [] if it was a z that entered. """ # Try pairs to enter z: new_binding_z = entering_z - possible_z = [(n, i) for (n, i) in self.pcp.couple_to_x.keys() - if n <= self.level and (n, i) not in set( - self.set_z).difference(set(entering_z))] - for (n, i) in possible_z: + possible_z = [ + (n, i) + for (n, i) in self.pcp.couple_to_x.keys() + if n <= self.level + and (n, i) not in set(self.set_z).difference(set(entering_z)) + ] + for n, i in possible_z: if (n, i) not in new_binding_z: if self.coordinates[self.pcp.couple_to_x[(n, i)]] == 0: new_binding_z.append((n, i)) # Try pairs to enter w: new_binding_w = entering_w - possible_w = [(n, i) for (n, i) in self.pcp.couple_to_poly.keys() - if n <= self.level and (n, i) not in set( - self.set_w).difference(set(entering_w))] - for (n, i) in possible_w: + possible_w = [ + (n, i) + for (n, i) in self.pcp.couple_to_poly.keys() + if n <= self.level + and (n, i) not in set(self.set_w).difference(set(entering_w)) + ] + for n, i in possible_w: if (n, i) not in new_binding_w: - pol = self.pcp.couple_to_poly[(n, i)].substitute( - self.coordinates) + pol = self.pcp.couple_to_poly[(n, i)].substitute(self.coordinates) if pol == 0: new_binding_w.append((n, i)) if len(new_binding_z) + len(new_binding_w) > 1: @@ -591,17 +613,22 @@ at the above level (singleton except in case of degeneracy). if not self.is_complementary: raise WilsonError("Can only lift a complementary node.") level = self.level + 1 - x_values_level = {pcp.couple_to_x[(n, i)]: xpairs_val[(n, i)] for - (n, i) in pcp.couple_to_x.keys() if n > level} + x_values_level = { + pcp.couple_to_x[(n, i)]: xpairs_val[(n, i)] + for (n, i) in pcp.couple_to_x.keys() + if n > level + } subpcp = pcp.substitute(x_values_level, level) set_w = deepcopy(self.set_w) set_z = deepcopy(self.set_z) - set_z += [(n, i) for (n, i) in subpcp.couple_to_x.keys() if - (n == level) and (i != subpcp.omega0[n])] + set_z += [ + (n, i) + for (n, i) in subpcp.couple_to_x.keys() + if (n == level) and (i != subpcp.omega0[n]) + ] # Try to find w entering set_w # Change lift to skip couple of previous level - possible_next_w = [(n, i) for (n, i) in subpcp.couple_to_x.keys() if - n == level] + possible_next_w = [(n, i) for (n, i) in subpcp.couple_to_x.keys() if n == level] no_sol_found = True while len(possible_next_w) > 0 and no_sol_found: w = possible_next_w.pop(0) @@ -609,11 +636,17 @@ at the above level (singleton except in case of degeneracy). subsys = Subsystem(subpcp, set_z, loc_set_w, level, xpairs_val) if len(subsys.solutions) > 0: no_sol_found = False - tentativenode = Node(subpcp, set_z, loc_set_w, level, - xpairs_val, subsys, subsys.solutions[0]) + tentativenode = Node( + subpcp, + set_z, + loc_set_w, + level, + xpairs_val, + subsys, + subsys.solutions[0], + ) tentativenode.prev_node = self - list_added_z, list_added_w = \ - tentativenode.check_degeneracy([], [w]) + list_added_z, list_added_w = tentativenode.check_degeneracy([], [w]) # Compute next nodes' list if no_sol_found: # No node found after lifting nextnodeslist = [] @@ -624,15 +657,29 @@ at the above level (singleton except in case of degeneracy). degenerated = True for z in list_added_z: loc_set_z = set_z + [z] - tentativenode = Node(subpcp, loc_set_z, set_w, level, - xpairs_val, subsys, subsys.solutions[0]) + tentativenode = Node( + subpcp, + loc_set_z, + set_w, + level, + xpairs_val, + subsys, + subsys.solutions[0], + ) tentativenode.prev_node = self tentativenode.is_degenerate = degenerated nextnodeslist += [tentativenode] for w in list_added_w: loc_set_w = set_w + [w] - tentativenode = Node(subpcp, set_z, loc_set_w, level, - xpairs_val, subsys, subsys.solutions[0]) + tentativenode = Node( + subpcp, + set_z, + loc_set_w, + level, + xpairs_val, + subsys, + subsys.solutions[0], + ) tentativenode.prev_node = self tentativenode.is_degenerate = degenerated nextnodeslist += [tentativenode] @@ -652,21 +699,29 @@ nodes at the level below (singleton except in case of degeneracy). """ if not self.is_initial: raise WilsonError("Can only descend from an initial node.") - x_values_level = {pcp.couple_to_x[(n, i)]: xpairs_val[(n, i)] for - (n, i) in pcp.couple_to_x.keys() - if n >= self.level} + x_values_level = { + pcp.couple_to_x[(n, i)]: xpairs_val[(n, i)] + for (n, i) in pcp.couple_to_x.keys() + if n >= self.level + } subpcp = pcp.substitute(x_values_level, self.level) new_set_z = [(n, i) for (n, i) in self.set_z if n < self.level] new_set_w = [(n, i) for (n, i) in self.set_w if n < self.level] level = self.level - 1 - if not set(new_set_z).intersection( - set(new_set_w)): # Empty intersection + if not set(new_set_z).intersection(set(new_set_w)): # Empty intersection subsys = Subsystem(subpcp, new_set_z, new_set_w, level, xpairs_val) if not subsys.solutions: tentativenode = None else: - tentativenode = Node(subpcp, new_set_z, new_set_w, level, - xpairs_val, subsys, subsys.solutions[0]) + tentativenode = Node( + subpcp, + new_set_z, + new_set_w, + level, + xpairs_val, + subsys, + subsys.solutions[0], + ) tentativenode.prev_node = self else: # Singleton intersection m_j = set(new_set_z).intersection(set(new_set_w)) @@ -675,24 +730,35 @@ nodes at the level below (singleton except in case of degeneracy). (m, j) = m_j.pop() local_set_z = deepcopy(new_set_z) local_set_z.remove((m, j)) - subsys = Subsystem(subpcp, local_set_z, new_set_w, level, - xpairs_val) + subsys = Subsystem(subpcp, local_set_z, new_set_w, level, xpairs_val) # (m,j) should be removed from new_set_w, instead. if not subsys.solutions: local_set_w = deepcopy(new_set_w) local_set_w.remove((m, j)) - subsys = Subsystem(subpcp, new_set_z, local_set_w, level, - xpairs_val) + subsys = Subsystem(subpcp, new_set_z, local_set_w, level, xpairs_val) if not subsys.solutions: tentativenode = None else: - tentativenode = Node(subpcp, new_set_z, local_set_w, level, - xpairs_val, subsys, - subsys.solutions[0]) + tentativenode = Node( + subpcp, + new_set_z, + local_set_w, + level, + xpairs_val, + subsys, + subsys.solutions[0], + ) tentativenode.prev_node = self else: - tentativenode = Node(subpcp, local_set_z, new_set_w, level, - xpairs_val, subsys, subsys.solutions[0]) + tentativenode = Node( + subpcp, + local_set_z, + new_set_w, + level, + xpairs_val, + subsys, + subsys.solutions[0], + ) tentativenode.prev_node = self # Check degeneracy of node after descent if tentativenode is None: @@ -716,18 +782,21 @@ nodes at the level below (singleton except in case of degeneracy). if prev_node.is_complementary: # Current node results from lift(). # If almost complementary, Z was unchanged. - arc_set_z = [(n, i) for (n, i) in self.set_z if - not (n, i) in self.set_w] + arc_set_z = [ + (n, i) for (n, i) in self.set_z if not (n, i) in self.set_w + ] arc_set_w = deepcopy(self.set_w) else: raise WilsonError( "Should not try to traverse an initial" - " node reached from the same level!") + " node reached from the same level!" + ) elif self.is_complementary: if not prev_node.level > self.level: raise WilsonError( "Normally, a complementary node should" - " not be traversed in any directions.") + " not be traversed in any directions." + ) # We have to find the unique bounded # arc leaving current complementary node: else: @@ -747,24 +816,27 @@ nodes at the level below (singleton except in case of degeneracy). (m, j) = z_inter_w.pop() if len(z_inter_w) > 0: raise WilsonError( - "This should not happen with " - "an almost-complementary node.") + "This should not happen with " "an almost-complementary node." + ) if (m, j) in prev_node.set_w: arc_set_z = deepcopy(self.set_z) - arc_set_w = [(n, i) for (n, i) in self.set_w if - not (n, i) in self.set_z] + arc_set_w = [ + (n, i) for (n, i) in self.set_w if not (n, i) in self.set_z + ] elif (m, j) in prev_node.set_z: - arc_set_z = [(n, i) for (n, i) in self.set_z if - not (n, i) in self.set_w] + arc_set_z = [ + (n, i) for (n, i) in self.set_z if not (n, i) in self.set_w + ] arc_set_w = deepcopy(self.set_w) else: raise WilsonError( - "Two consecutive nodes should" - " have identical z or identical w ") + "Two consecutive nodes should" " have identical z or identical w " + ) else: raise WilsonError( "If the node is not almost-complementary," - " we should not encounter it!") + " we should not encounter it!" + ) if arc_set_z is None: arc_set_z = [] if arc_set_w is None: @@ -786,13 +858,12 @@ nodes at the same level (singleton except in case of degeneracy). nodepcp = self.pcp level = self.level all_couples = set( - [(n, i) for (n, i) in nodepcp.couple_to_x.keys() if n <= level]) + [(n, i) for (n, i) in nodepcp.couple_to_x.keys() if n <= level] + ) # Compute the next arc: (arc_set_z, arc_set_w) = self.compute_arc(prev_node) - poss_new_z = [(m, j) for (m, j) in - all_couples.difference(set(self.set_z))] - poss_new_w = [(m, j) for (m, j) in - all_couples.difference(set(self.set_w))] + poss_new_z = [(m, j) for (m, j) in all_couples.difference(set(self.set_z))] + poss_new_w = [(m, j) for (m, j) in all_couples.difference(set(self.set_w))] nextnodeslist = [] no_sol_found = True @@ -800,11 +871,17 @@ nodes at the same level (singleton except in case of degeneracy). z = poss_new_z.pop(0) loc_set_z = arc_set_z + [z] loc_set_w = arc_set_w - subsys = Subsystem(nodepcp, loc_set_z, loc_set_w, level, - xpairs_val) + subsys = Subsystem(nodepcp, loc_set_z, loc_set_w, level, xpairs_val) if len(subsys.solutions) > 0: - tentativenode = Node(nodepcp, loc_set_z, loc_set_w, level, - xpairs_val, subsys, subsys.solutions[0]) + tentativenode = Node( + nodepcp, + loc_set_z, + loc_set_w, + level, + xpairs_val, + subsys, + subsys.solutions[0], + ) tentativenode.prev_node = self nextnodeslist += [tentativenode] no_sol_found = False @@ -812,11 +889,17 @@ nodes at the same level (singleton except in case of degeneracy). w = poss_new_w.pop(0) loc_set_z = arc_set_z loc_set_w = arc_set_w + [w] - subsys = Subsystem(nodepcp, loc_set_z, loc_set_w, level, - xpairs_val) + subsys = Subsystem(nodepcp, loc_set_z, loc_set_w, level, xpairs_val) if len(subsys.solutions) > 0: - tentativenode = Node(nodepcp, loc_set_z, loc_set_w, level, - xpairs_val, subsys, subsys.solutions[0]) + tentativenode = Node( + nodepcp, + loc_set_z, + loc_set_w, + level, + xpairs_val, + subsys, + subsys.solutions[0], + ) tentativenode.prev_node = self nextnodeslist += [tentativenode] no_sol_found = False @@ -833,15 +916,29 @@ nodes at the same level (singleton except in case of degeneracy). degenerated = True for z in list_added_z: loc_set_z = arc_set_z + [z] - tentativenode = Node(nodepcp, loc_set_z, arc_set_w, level, - xpairs_val, subsys, subsys.solutions[0]) + tentativenode = Node( + nodepcp, + loc_set_z, + arc_set_w, + level, + xpairs_val, + subsys, + subsys.solutions[0], + ) tentativenode.prev_node = self tentativenode.is_degenerate = degenerated nextnodeslist += [tentativenode] for w in list_added_w: loc_set_w = arc_set_w + [w] - tentativenode = Node(nodepcp, arc_set_z, loc_set_w, level, - xpairs_val, subsys, subsys.solutions[0]) + tentativenode = Node( + nodepcp, + arc_set_z, + loc_set_w, + level, + xpairs_val, + subsys, + subsys.solutions[0], + ) tentativenode.prev_node = self tentativenode.is_degenerate = degenerated nextnodeslist += [tentativenode] @@ -862,18 +959,19 @@ nodes at the same level (singleton except in case of degeneracy). # if not (set(self.set_z).difference(node.set_z)) # and not (set(self.set_w).difference(node.set_w)): # return True - if len(self.set_z) == len(node.set_z) and\ - len(self.set_w) == len(node.set_w): - if not (set(self.set_z).difference(node.set_z)) and\ - not (set(self.set_w).difference(node.set_w)): - if len(self.prev_node.set_z) ==\ - len(node.prev_node.set_z) and\ - len(self.prev_node.set_w) ==\ - len(node.prev_node.set_w): + if len(self.set_z) == len(node.set_z) and len(self.set_w) == len( + node.set_w + ): + if not (set(self.set_z).difference(node.set_z)) and not ( + set(self.set_w).difference(node.set_w) + ): + if len(self.prev_node.set_z) == len(node.prev_node.set_z) and len( + self.prev_node.set_w + ) == len(node.prev_node.set_w): if not ( - set(self.prev_node.set_z).difference( - node.prev_node.set_z)) and \ - not (set(self.prev_node.set_w).difference( - node.prev_node.set_w)): + set(self.prev_node.set_z).difference(node.prev_node.set_z) + ) and not ( + set(self.prev_node.set_w).difference(node.prev_node.set_w) + ): return True return False diff --git a/gtnash/util/irda.py b/gtnash/util/irda.py index b777219..9eea63e 100644 --- a/gtnash/util/irda.py +++ b/gtnash/util/irda.py @@ -28,9 +28,11 @@ Detailed description of methods ------------------------------- """ + from sage.all import MixedIntegerLinearProgram, QQ, QQbar # noqa from gtnash.game.hypergraphicalgame import HGG import numpy as np + # from copy import * from copy import deepcopy @@ -51,9 +53,12 @@ in 'subgame'. """ player_in_subgame = hgg.hypergraph[subgame].index(player) utility_of_player_in_subgame = hgg.utilities[subgame][player_in_subgame] - return [utility_of_player_in_subgame[i] for i in - hgg.local_normalformgames[subgame].row_where_p_is_i( - player_in_subgame, action)] + return [ + utility_of_player_in_subgame[i] + for i in hgg.local_normalformgames[subgame].row_where_p_is_i( + player_in_subgame, action + ) + ] def local_difference(hgg, player, action1, action2, subgame): @@ -72,15 +77,16 @@ def local_difference(hgg, player, action1, action2, subgame): :rtype: Numpy array. """ - return np.array( - subutilities_player(hgg, player, action1, subgame)) - np.array( - subutilities_player(hgg, player, action2, subgame)) + return np.array(subutilities_player(hgg, player, action1, subgame)) - np.array( + subutilities_player(hgg, player, action2, subgame) + ) ############################################################################ # Functions to compute a BILP to determine whether a strategy is dominated. ############################################################################ + def nondominated(hgg, player, action1, action2): """ Determines whether action1 of player is nondominated by action2 in hgg. @@ -109,7 +115,8 @@ def nondominated(hgg, player, action1, action2): # print(a_e_i) number_of_k = np.size(a_e_i, 0) # Number of rows in a_e_i bilp.add_constraint( - bilp.sum(b[player, e, k] for k in range(number_of_k)) == 1) + bilp.sum(b[player, e, k] for k in range(number_of_k)) == 1 + ) # Second set of constraints: for e1 in range(len(hypergraph)): @@ -133,7 +140,8 @@ def nondominated(hgg, player, action1, action2): break if add_c: bilp.add_constraint( - b[player, e1, k1] + b[player, e2, k2] <= 1) + b[player, e1, k1] + b[player, e2, k2] <= 1 + ) # Linear utility function: temp_list = [] @@ -144,8 +152,7 @@ def nondominated(hgg, player, action1, action2): for k in range(len(ld[e])): temp_list.append((e, k)) - bilp.set_objective(sum(b[player, e, k] * QQ(ld[e][k]) - for e, k in temp_list)) + bilp.set_objective(sum(b[player, e, k] * QQ(ld[e][k]) for e, k in temp_list)) # bilp.show() # print("Solution value: ",bilp.solve()) return bilp.solve() >= 0 @@ -217,8 +224,9 @@ of player j has been removed. joint_acts = subgame.joint_actions # Index of player j in subgame e idx = hypergraph[e].index(j) - to_remove = [il for il in range(joint_acts.shape[0]) if - joint_acts[il, idx] == aj] + to_remove = [ + il for il in range(joint_acts.shape[0]) if joint_acts[il, idx] == aj + ] for r in sorted(to_remove, reverse=True): for i in range(len(hypergraph[e])): del utilities[e][i][r] diff --git a/gtnash/util/polynomial_complementary_problem.py b/gtnash/util/polynomial_complementary_problem.py index a44ac64..ac76c73 100644 --- a/gtnash/util/polynomial_complementary_problem.py +++ b/gtnash/util/polynomial_complementary_problem.py @@ -17,6 +17,7 @@ Detailed description of the classes ----------------------------------- """ + import numpy as np from sage.all import QQ, QQbar, PolynomialRing, ideal, prod from gtnash.game.hypergraphicalgame import HGG @@ -69,7 +70,7 @@ x_omega0[(n,i)]=0 if i!=omega0[n], for all players n. self.gen_var_y() # Ring: var_xy = self.set_x + self.set_y - self.ring = PolynomialRing(QQbar, var_xy, order='lex') + self.ring = PolynomialRing(QQbar, var_xy, order="lex") self.couple_to_poly = {} self.generate_poly(fact_y) self.couple_to_poly_y = {} @@ -78,8 +79,7 @@ x_omega0[(n,i)]=0 if i!=omega0[n], for all players n. if not omega0: # self.gen_omega0() self.omega0 = {} - for n in range(self.game.n_players - 1, -1, - -1): # players in reverse order + for n in range(self.game.n_players - 1, -1, -1): # players in reverse order self.omega0[n] = min([i for i in self.game.players_actions[n]]) else: self.omega0 = omega0 @@ -160,7 +160,7 @@ and updates ``self`` attribute ``couple_to_x``. # Generate all the variable x used in the pcp for n in range(self.game.n_players): for j in self.game.players_actions[n]: - var_x = f'x{n}_{j}' + var_x = f"x{n}_{j}" self.set_x += [var_x] self.couple_to_x[(n, j)] = var_x @@ -176,7 +176,7 @@ and updates ``self`` attribute ``couple_to_y``. for n in range(self.game.n_players): for g in range(len(hypergraph)): # if n not in hypergraph[g]: - var_y = f'y{n}_{g}' + var_y = f"y{n}_{g}" self.set_y += [var_y] self.couple_to_y[(n, g)] = var_y @@ -195,10 +195,10 @@ and updates ``self`` attribute ``couple_to_y``. # To improve, by using a reduced_dico n<level # an poly.subs(reduced_dico) sub_pcp = deepcopy(self) - for (n, i) in self.couple_to_poly.keys(): + for n, i in self.couple_to_poly.keys(): poly = self.couple_to_poly[(n, i)] for variab, valu in x_values.items(): - poly = eval('poly.subs(' + str(variab) + '=valu)') + poly = eval("poly.subs(" + str(variab) + "=valu)") if n <= level: sub_pcp.couple_to_poly[(n, i)] = poly else: @@ -222,9 +222,9 @@ and updates ``self`` attribute ``couple_to_y``. if max_of_n >= 0: e_to_index = self.game.index_of_player_in_local(n) for e_i in e_to_index.keys(): - copy_util[e_i][e_to_index[e_i]] = [val - (max_of_n + 1) for - val in copy_util[e_i][ - e_to_index[e_i]]] + copy_util[e_i][e_to_index[e_i]] = [ + val - (max_of_n + 1) for val in copy_util[e_i][e_to_index[e_i]] + ] # copy_util[e_i, e_to_index[e_i]]=[val -(max_of_n+1) # for val in copy_util[e_i,e_to_index[e_i]]] # copy_util[e_i,e_to_index[e_i]]-=(max_of_n+1) @@ -265,9 +265,12 @@ and creates Q[g] = y^N_g. New version (correct). sys_S = [] for n in range(nplayers): if n not in self.game.hypergraph[g]: - sys_S.append(sum( - self.ring(self.couple_to_x[(n, i)]) for i in - self.game.players_actions[n])) + sys_S.append( + sum( + self.ring(self.couple_to_x[(n, i)]) + for i in self.game.players_actions[n] + ) + ) poly_Q[g] = prod(sys_S) return poly_Q @@ -292,24 +295,31 @@ any local game g involving player n and action i of n (see documentation). for g in range(nlocgames): if n in hypergraph[g]: index_n = hypergraph[g].index(n) - locgame_players_actions = \ - self.game.local_normalformgames[g].joint_actions + locgame_players_actions = self.game.local_normalformgames[ + g + ].joint_actions locgame_utilities = negative_util[g] sys_s = [] for index_w in range(locgame_players_actions.shape[0]): - w = [locgame_players_actions[index_w, k] for k in - range(locgame_players_actions.shape[1])] + w = [ + locgame_players_actions[index_w, k] + for k in range(locgame_players_actions.shape[1]) + ] if w[index_n] == i: pw = QQ(locgame_utilities[index_n][index_w]) for index_nu in range(len(hypergraph[g])): if index_nu != index_n: nu = hypergraph[g][index_nu] - pw *= \ - self.ring( - self.couple_to_x[( + pw *= self.ring( + self.couple_to_x[ + ( nu, locgame_players_actions[ - index_w, index_nu])]) + index_w, index_nu + ], + ) + ] + ) sys_s.append(pw) poly_r[(n, i, g)] = sum(sys_s) return poly_r @@ -337,8 +347,7 @@ any local game g involving player n and action i of n (see documentation). couple_to_poly[(n, i)] = 0 for g in range(nlocgames): if n in hypergraph[g]: - couple_to_poly[(n, i)] -=\ - poly_q[g] * poly_r[(n, i, g)] + couple_to_poly[(n, i)] -= poly_q[g] * poly_r[(n, i, g)] couple_to_poly[(n, i)] -= 1 else: poly_q = self.generate_poly_fact() @@ -347,8 +356,7 @@ any local game g involving player n and action i of n (see documentation). couple_to_poly[(n, i)] = 0 for g in range(nlocgames): if n in hypergraph[g]: - couple_to_poly[(n, i)] -=\ - (poly_q[g]) * poly_r[(n, i, g)] + couple_to_poly[(n, i)] -= (poly_q[g]) * poly_r[(n, i, g)] couple_to_poly[(n, i)] -= 1 self.couple_to_poly = couple_to_poly @@ -375,16 +383,20 @@ Useful only for hypergraphical games. else: couple_to_poly_y[(n, g)] = polyloc - sum( self.ring(self.couple_to_x[(n, i)]) - for i in self.game.players_actions[n]) + for i in self.game.players_actions[n] + ) else: if n in hypergraph[g]: couple_to_poly_y[(n, g)] = polyloc - self.ring( - self.couple_to_y[(n - 1, g)]) + self.couple_to_y[(n - 1, g)] + ) else: couple_to_poly_y[(n, g)] = polyloc - self.ring( - self.couple_to_y[(n - 1, g)]) * sum( - self.ring(self.couple_to_x[(n, i)]) for i in - self.game.players_actions[n]) + self.couple_to_y[(n - 1, g)] + ) * sum( + self.ring(self.couple_to_x[(n, i)]) + for i in self.game.players_actions[n] + ) self.couple_to_poly_y = couple_to_poly_y def generate_poly_fact(self): @@ -419,7 +431,8 @@ Useful only for hypergraphical games. else: couple_to_poly_fact[g] = couple_to_poly_fact[g] * sum( self.ring(self.couple_to_x[(n, i)]) - for i in self.game.players_actions[n]) + for i in self.game.players_actions[n] + ) return couple_to_poly_fact @@ -453,8 +466,7 @@ if of dimension 0. Else, empty. # Equations: self.equations = self.generate_equations(pcp, z, w, level, xpairs_val) # Inequations: - self.inequations = self.generate_inequations(pcp, z, w, level, - xpairs_val) + self.inequations = self.generate_inequations(pcp, z, w, level, xpairs_val) # Ideal of the equations self.ideal = self.compute_ideal() self.idealdimension = self.ideal.dimension() @@ -480,12 +492,11 @@ if of dimension 0. Else, empty. niceprint += "Inequations:\n" for e in range(len(self.inequations)): niceprint += str(self.inequations[e]) + " >=0\n" - niceprint += "Dimension of the ideal: " + str( - self.idealdimension) + "\n" + niceprint += "Dimension of the ideal: " + str(self.idealdimension) + "\n" niceprint += "Variety: " + str(self.variety) + "\n" niceprint += "Number of solutions: " + str(self.nbsols) + "\n" niceprint += "Solutions: " + str(self.solutions) + "\n" - return (niceprint) + return niceprint def generate_equations(self, pcp, z, w, level, xpairs_val): """ @@ -503,21 +514,23 @@ variables set to 0) that are in the subsystem. :rtype: list. """ - equations = [pcp.ring(pcp.couple_to_x[(n, i)]) for (n, i) in - z] # was self.ring + equations = [pcp.ring(pcp.couple_to_x[(n, i)]) for (n, i) in z] # was self.ring dico = {} for e in range(len(equations)): dico[equations[e]] = 0 subpcp = pcp.substitute(dico, level) # Zero polynomials equation: - equations += [subpcp.couple_to_poly[(n, i)] for (n, i) in w if - n <= level] + equations += [subpcp.couple_to_poly[(n, i)] for (n, i) in w if n <= level] # Add equations defining the y - equations += [pcp.couple_to_poly_y[(n, g)] for (n, g) in - pcp.couple_to_poly_y.keys()] + equations += [ + pcp.couple_to_poly_y[(n, g)] for (n, g) in pcp.couple_to_poly_y.keys() + ] # Add fixed variables values for n>level - equations += [pcp.ring(pcp.couple_to_x[(n, i)]) - xpairs_val[(n, i)] - for (n, i) in pcp.couple_to_x.keys() if n > level] + equations += [ + pcp.ring(pcp.couple_to_x[(n, i)]) - xpairs_val[(n, i)] + for (n, i) in pcp.couple_to_x.keys() + if n > level + ] # That's it for equations return equations @@ -538,17 +551,19 @@ variables >= 0) that are in the subsystem. """ x_values = {} - for (n, i) in pcp.couple_to_x.keys(): + for n, i in pcp.couple_to_x.keys(): if (n, i) in z: - x_values[ - self.ring(pcp.couple_to_x[(n, i)])] = 0 # was pcp.ring + x_values[self.ring(pcp.couple_to_x[(n, i)])] = 0 # was pcp.ring # if n>level: # x_values[pcp.ring(pcp.couple_to_x[(n,i)])] = xpairs_val[(n,i)] subpcp = pcp.substitute(x_values, level) - inequations = [subpcp.couple_to_poly[(n, i)] for (n, i) in - set(pcp.couple_to_x.keys()).intersection( - set(subpcp.couple_to_poly.keys())) if - (n, i) not in w] + inequations = [ + subpcp.couple_to_poly[(n, i)] + for (n, i) in set(pcp.couple_to_x.keys()).intersection( + set(subpcp.couple_to_poly.keys()) + ) + if (n, i) not in w + ] return inequations def compute_ideal(self): diff --git a/pyproject.toml b/pyproject.toml index 40013a7..db50e2e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,59 +12,14 @@ build-backend = "setuptools.build_meta" readme = 'README.md' dependencies = ['numpy'] -[tool.setuptools] - packages = ['gtnash'] - [project.urls] Documentation = "https://game-theory-tools-group.pages.mia.inra.fr/gtnash/main" Repository = "https://forgemia.inra.fr/game-theory-tools-group/gtnash/" Issues = "https://forgemia.inra.fr/game-theory-tools-group/gtnash/-/issues" +[tool.setuptools] + packages = ['gtnash'] + [project.optional-dependencies] - code = ['pylint', 'black', 'pytest', 'coverage', 'pre-commit'] + code = ['pylint', 'black', 'pytest'] docs=['sphinx','sphinx-rtd-theme','gitpython','myst_parser'] - -[tool.black] - line-length = 79 - target-version = ['py38'] - -[tool.pytest.ini_options] - minversion = '6.0' - addopts = '-ra -q -W ignore::DeprecationWarning' - testpaths = ['tests/'] - -[tool.pylint.main] - fail-under = 8 - ignore-patterns = ["^\\.#"] - jobs = 0 - persistent = true - py-version = "3.8" - recursive = true - suggestion-mode = true - ignore = [".venv"] - disable = ["W0223", "E0401", "R0801"] - -[tool.pylint.format] - ignore-long-lines = "^\\s*(# )?<?https?://\\S+>?$" - indent-after-paren = 4 - indent-string = " " - max-line-length = 79 - max-module-lines = 1000 - -[tool.pylint.imports] - allow-any-import-level = true - allow-reexport-from-package = true - -[tool.pylint.miscellaneous] - notes = ["FIXME", "XXX", "TODO"] - -[tool.pylint.refactoring] - max-nested-blocks = 5 - never-returning-functions = ["sys.exit", "argparse.parse_error"] - -[tool.coverage.run] -omit = [ - "examples/*", - "*test*", - "*__init__*", - ] diff --git a/setup.py b/setup.py deleted file mode 100644 index 071aa0f..0000000 --- a/setup.py +++ /dev/null @@ -1,11 +0,0 @@ -import setuptools - -setuptools.setup( - name="gtnash", - description="Python Nash Equilibrium Computation Utilities", - version="1.0.0", - author="Régis Sabbadin", - author_email="regis.sabbadin@inrae.fr", - url="https://forgemia.inra.fr/game-theory-tools-group/gtnash/", - packages=setuptools.find_packages() -) diff --git a/test/test_bayesian_hypergraphicalgame.py b/test/test_bayesian_hypergraphicalgame.py index 79b3cae..dd72787 100644 --- a/test/test_bayesian_hypergraphicalgame.py +++ b/test/test_bayesian_hypergraphicalgame.py @@ -9,301 +9,552 @@ from fractions import Fraction def bayesian_polymatrix(): players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] theta = [[0, 1], [0, 1], [0, 1], [0, 1]] - same_game = [[[3, 0, 0, 2], [3, 0, 0, 2]], [[3, 0, 0, 2], [1, 0, 0, 2]], - [[1, 0, 0, 2], [3, 0, 0, 2]], [[1, 0, 0, 2], [1, 0, 0, 2]]] + same_game = [ + [[3, 0, 0, 2], [3, 0, 0, 2]], + [[3, 0, 0, 2], [1, 0, 0, 2]], + [[1, 0, 0, 2], [3, 0, 0, 2]], + [[1, 0, 0, 2], [1, 0, 0, 2]], + ] same_p = [4, 1, 1, 4] hypergr = [[0, 1], [1, 2], [2, 3], [0, 3]] - return BHGG(players_actions, [same_game, same_game, same_game, same_game], - hypergr, theta, [same_p, same_p, same_p, same_p]) + return BHGG( + players_actions, + [same_game, same_game, same_game, same_game], + hypergr, + theta, + [same_p, same_p, same_p, same_p], + ) # ADD a 4 player hypergraphe with edge size 3 + @pytest.fixture def bayesian_hgg1(): players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] theta = [[0, 1], [0, 1], [0, 1], [0, 1]] - utilities = [[[[39, 19, 95, 0, 32, 97, 65, 69], - [22, 40, 67, 14, 100, 60, 5, 34], - [46, 27, 72, 45, 18, 84, 100, 33]], - [[61, 96, 22, 34, 34, 35, 39, 54], - [39, 42, 77, 76, 27, 45, 56, 0], - [21, 94, 80, 74, 100, 20, 55, 65]], - [[34, 47, 56, 73, 55, 59, 31, 17], - [57, 43, 0, 23, 41, 100, 73, 86], - [24, 53, 95, 45, 38, 17, 28, 76]], - [[47, 37, 100, 6, 20, 16, 17, 59], - [40, 44, 64, 13, 0, 73, 76, 71], - [23, 52, 19, 70, 41, 43, 30, 28]], - [[53, 38, 44, 33, 9, 71, 31, 82], - [62, 100, 70, 65, 74, 22, 47, 59], - [66, 82, 20, 0, 15, 3, 57, 60]], - [[46, 33, 0, 31, 50, 50, 35, 50], - [26, 77, 56, 47, 37, 51, 56, 57], - [28, 27, 100, 21, 29, 26, 83, 25]], - [[70, 88, 0, 15, 7, 34, 100, 58], - [53, 68, 17, 17, 16, 26, 84, 61], - [63, 80, 10, 15, 11, 43, 84, 50]], - [[91, 49, 99, 85, 62, 38, 21, 87], - [18, 36, 74, 84, 40, 45, 39, 88], - [63, 54, 57, 100, 45, 20, 0, 76]]], - [[[72, 67, 47, 94, 73, 92, 80, 81], - [55, 66, 45, 62, 78, 91, 55, 53], - [54, 75, 47, 42, 0, 52, 47, 100]], - [[64, 79, 39, 7, 43, 22, 68, 26], - [48, 67, 62, 5, 74, 82, 77, 65], - [40, 65, 38, 0, 59, 69, 100, 86]], - [[44, 53, 46, 82, 44, 89, 69, 97], - [61, 96, 88, 93, 70, 20, 100, 46], - [31, 89, 0, 61, 48, 77, 84, 46]], - [[59, 74, 63, 100, 34, 31, 38, 45], - [55, 52, 83, 74, 10, 65, 5, 50], - [74, 64, 65, 96, 19, 70, 0, 38]], - [[32, 100, 0, 54, 5, 37, 45, 66], - [2, 23, 49, 3, 62, 21, 23, 44], - [11, 54, 67, 8, 37, 69, 83, 27]], - [[41, 67, 72, 12, 65, 74, 65, 53], - [68, 68, 57, 49, 0, 91, 80, 61], - [97, 78, 86, 100, 34, 62, 57, 87]], - [[52, 54, 63, 18, 37, 67, 75, 73], - [47, 65, 93, 91, 59, 60, 0, 43], - [82, 76, 49, 91, 100, 82, 95, 50]], - [[39, 19, 95, 0, 32, 97, 65, 69], - [22, 40, 67, 14, 100, 60, 5, 34], - [46, 27, 72, 45, 18, 84, 100, 33]]]] + utilities = [ + [ + [ + [39, 19, 95, 0, 32, 97, 65, 69], + [22, 40, 67, 14, 100, 60, 5, 34], + [46, 27, 72, 45, 18, 84, 100, 33], + ], + [ + [61, 96, 22, 34, 34, 35, 39, 54], + [39, 42, 77, 76, 27, 45, 56, 0], + [21, 94, 80, 74, 100, 20, 55, 65], + ], + [ + [34, 47, 56, 73, 55, 59, 31, 17], + [57, 43, 0, 23, 41, 100, 73, 86], + [24, 53, 95, 45, 38, 17, 28, 76], + ], + [ + [47, 37, 100, 6, 20, 16, 17, 59], + [40, 44, 64, 13, 0, 73, 76, 71], + [23, 52, 19, 70, 41, 43, 30, 28], + ], + [ + [53, 38, 44, 33, 9, 71, 31, 82], + [62, 100, 70, 65, 74, 22, 47, 59], + [66, 82, 20, 0, 15, 3, 57, 60], + ], + [ + [46, 33, 0, 31, 50, 50, 35, 50], + [26, 77, 56, 47, 37, 51, 56, 57], + [28, 27, 100, 21, 29, 26, 83, 25], + ], + [ + [70, 88, 0, 15, 7, 34, 100, 58], + [53, 68, 17, 17, 16, 26, 84, 61], + [63, 80, 10, 15, 11, 43, 84, 50], + ], + [ + [91, 49, 99, 85, 62, 38, 21, 87], + [18, 36, 74, 84, 40, 45, 39, 88], + [63, 54, 57, 100, 45, 20, 0, 76], + ], + ], + [ + [ + [72, 67, 47, 94, 73, 92, 80, 81], + [55, 66, 45, 62, 78, 91, 55, 53], + [54, 75, 47, 42, 0, 52, 47, 100], + ], + [ + [64, 79, 39, 7, 43, 22, 68, 26], + [48, 67, 62, 5, 74, 82, 77, 65], + [40, 65, 38, 0, 59, 69, 100, 86], + ], + [ + [44, 53, 46, 82, 44, 89, 69, 97], + [61, 96, 88, 93, 70, 20, 100, 46], + [31, 89, 0, 61, 48, 77, 84, 46], + ], + [ + [59, 74, 63, 100, 34, 31, 38, 45], + [55, 52, 83, 74, 10, 65, 5, 50], + [74, 64, 65, 96, 19, 70, 0, 38], + ], + [ + [32, 100, 0, 54, 5, 37, 45, 66], + [2, 23, 49, 3, 62, 21, 23, 44], + [11, 54, 67, 8, 37, 69, 83, 27], + ], + [ + [41, 67, 72, 12, 65, 74, 65, 53], + [68, 68, 57, 49, 0, 91, 80, 61], + [97, 78, 86, 100, 34, 62, 57, 87], + ], + [ + [52, 54, 63, 18, 37, 67, 75, 73], + [47, 65, 93, 91, 59, 60, 0, 43], + [82, 76, 49, 91, 100, 82, 95, 50], + ], + [ + [39, 19, 95, 0, 32, 97, 65, 69], + [22, 40, 67, 14, 100, 60, 5, 34], + [46, 27, 72, 45, 18, 84, 100, 33], + ], + ], + ] p = [[6, 9, 8, 6, 6, 4, 3, 3], [1, 7, 9, 1, 7, 3, 6, 9]] hypergraph = [[0, 1, 2], [0, 2, 3]] return BHGG(players_actions, utilities, hypergraph, theta, p) def test_joint_actions1(bayesian_polymatrix): - assert (bayesian_polymatrix.local_bayesiangames[0].joint_actions == np.mat( - [[0, 0], [0, 1], [1, 0], [1, 1]])).all() + assert ( + bayesian_polymatrix.local_bayesiangames[0].joint_actions + == np.mat([[0, 0], [0, 1], [1, 0], [1, 1]]) + ).all() def test_joint_actions2(bayesian_polymatrix): - assert (bayesian_polymatrix.local_bayesiangames[1].joint_actions == np.mat( - [[0, 0], [0, 1], [1, 0], [1, 1]])).all() + assert ( + bayesian_polymatrix.local_bayesiangames[1].joint_actions + == np.mat([[0, 0], [0, 1], [1, 0], [1, 1]]) + ).all() def test_joint_actions3(bayesian_polymatrix): - assert (bayesian_polymatrix.local_bayesiangames[2].joint_actions == np.mat( - [[0, 0], [0, 1], [1, 0], [1, 1]])).all() + assert ( + bayesian_polymatrix.local_bayesiangames[2].joint_actions + == np.mat([[0, 0], [0, 1], [1, 0], [1, 1]]) + ).all() def test_joint_actions4(bayesian_polymatrix): - assert (bayesian_polymatrix.local_bayesiangames[3].joint_actions == np.mat( - [[0, 0], [0, 1], [1, 0], [1, 1]])).all() + assert ( + bayesian_polymatrix.local_bayesiangames[3].joint_actions + == np.mat([[0, 0], [0, 1], [1, 0], [1, 1]]) + ).all() def test_joint_actions5(bayesian_hgg1): - assert (bayesian_hgg1.local_bayesiangames[0].joint_actions == np.mat( - [[0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1], - [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]])).all() + assert ( + bayesian_hgg1.local_bayesiangames[0].joint_actions + == np.mat( + [ + [0, 0, 0], + [0, 0, 1], + [0, 1, 0], + [0, 1, 1], + [1, 0, 0], + [1, 0, 1], + [1, 1, 0], + [1, 1, 1], + ] + ) + ).all() def test_joint_actions6(bayesian_hgg1): - assert (bayesian_hgg1.local_bayesiangames[1].joint_actions == np.mat( - [[0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1], - [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]])).all() + assert ( + bayesian_hgg1.local_bayesiangames[1].joint_actions + == np.mat( + [ + [0, 0, 0], + [0, 0, 1], + [0, 1, 0], + [0, 1, 1], + [1, 0, 0], + [1, 0, 1], + [1, 1, 0], + [1, 1, 1], + ] + ) + ).all() def test_joint_type1(bayesian_polymatrix): - assert (bayesian_polymatrix.local_bayesiangames[0].joint_theta == np.mat( - [[0, 0], [0, 1], [1, 0], [1, 1]])).all() + assert ( + bayesian_polymatrix.local_bayesiangames[0].joint_theta + == np.mat([[0, 0], [0, 1], [1, 0], [1, 1]]) + ).all() def test_joint_type2(bayesian_polymatrix): - assert (bayesian_polymatrix.local_bayesiangames[1].joint_theta == np.mat( - [[0, 0], [0, 1], [1, 0], [1, 1]])).all() + assert ( + bayesian_polymatrix.local_bayesiangames[1].joint_theta + == np.mat([[0, 0], [0, 1], [1, 0], [1, 1]]) + ).all() def test_joint_type3(bayesian_polymatrix): - assert (bayesian_polymatrix.local_bayesiangames[2].joint_theta == np.mat( - [[0, 0], [0, 1], [1, 0], [1, 1]])).all() + assert ( + bayesian_polymatrix.local_bayesiangames[2].joint_theta + == np.mat([[0, 0], [0, 1], [1, 0], [1, 1]]) + ).all() def test_joint_type4(bayesian_polymatrix): - assert (bayesian_polymatrix.local_bayesiangames[3].joint_theta == np.mat( - [[0, 0], [0, 1], [1, 0], [1, 1]])).all() + assert ( + bayesian_polymatrix.local_bayesiangames[3].joint_theta + == np.mat([[0, 0], [0, 1], [1, 0], [1, 1]]) + ).all() def test_joint_type5(bayesian_hgg1): - assert (bayesian_hgg1.local_bayesiangames[0].joint_theta == np.mat( - [[0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1], - [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]])).all() + assert ( + bayesian_hgg1.local_bayesiangames[0].joint_theta + == np.mat( + [ + [0, 0, 0], + [0, 0, 1], + [0, 1, 0], + [0, 1, 1], + [1, 0, 0], + [1, 0, 1], + [1, 1, 0], + [1, 1, 1], + ] + ) + ).all() def test_joint_type6(bayesian_hgg1): - assert (bayesian_hgg1.local_bayesiangames[1].joint_theta == np.mat( - [[0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1], - [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]])).all() + assert ( + bayesian_hgg1.local_bayesiangames[1].joint_theta + == np.mat( + [ + [0, 0, 0], + [0, 0, 1], + [0, 1, 0], + [0, 1, 1], + [1, 0, 0], + [1, 0, 1], + [1, 1, 0], + [1, 1, 1], + ] + ) + ).all() def test_local_utilities1(bayesian_polymatrix): assert bayesian_polymatrix.local_bayesiangames[0].utilities == [ - [[3, 0, 0, 2], [3, 0, 0, 2]], [[3, 0, 0, 2], [1, 0, 0, 2]], - [[1, 0, 0, 2], [3, 0, 0, 2]], [[1, 0, 0, 2], [1, 0, 0, 2]]] + [[3, 0, 0, 2], [3, 0, 0, 2]], + [[3, 0, 0, 2], [1, 0, 0, 2]], + [[1, 0, 0, 2], [3, 0, 0, 2]], + [[1, 0, 0, 2], [1, 0, 0, 2]], + ] def test_local_utilities2(bayesian_polymatrix): assert bayesian_polymatrix.local_bayesiangames[1].utilities == [ - [[3, 0, 0, 2], [3, 0, 0, 2]], [[3, 0, 0, 2], [1, 0, 0, 2]], - [[1, 0, 0, 2], [3, 0, 0, 2]], [[1, 0, 0, 2], [1, 0, 0, 2]]] + [[3, 0, 0, 2], [3, 0, 0, 2]], + [[3, 0, 0, 2], [1, 0, 0, 2]], + [[1, 0, 0, 2], [3, 0, 0, 2]], + [[1, 0, 0, 2], [1, 0, 0, 2]], + ] def test_local_utilities3(bayesian_polymatrix): assert bayesian_polymatrix.local_bayesiangames[2].utilities == [ - [[3, 0, 0, 2], [3, 0, 0, 2]], [[3, 0, 0, 2], [1, 0, 0, 2]], - [[1, 0, 0, 2], [3, 0, 0, 2]], [[1, 0, 0, 2], [1, 0, 0, 2]]] + [[3, 0, 0, 2], [3, 0, 0, 2]], + [[3, 0, 0, 2], [1, 0, 0, 2]], + [[1, 0, 0, 2], [3, 0, 0, 2]], + [[1, 0, 0, 2], [1, 0, 0, 2]], + ] def test_local_utilities4(bayesian_polymatrix): assert bayesian_polymatrix.local_bayesiangames[3].utilities == [ - [[3, 0, 0, 2], [3, 0, 0, 2]], [[3, 0, 0, 2], [1, 0, 0, 2]], - [[1, 0, 0, 2], [3, 0, 0, 2]], [[1, 0, 0, 2], [1, 0, 0, 2]]] + [[3, 0, 0, 2], [3, 0, 0, 2]], + [[3, 0, 0, 2], [1, 0, 0, 2]], + [[1, 0, 0, 2], [3, 0, 0, 2]], + [[1, 0, 0, 2], [1, 0, 0, 2]], + ] def test_local_utilities5(bayesian_hgg1): assert bayesian_hgg1.local_bayesiangames[0].utilities == [ - [[39, 19, 95, 0, 32, 97, 65, 69], [22, 40, 67, 14, 100, 60, 5, 34], - [46, 27, 72, 45, 18, 84, 100, 33]], - [[61, 96, 22, 34, 34, 35, 39, 54], [39, 42, 77, 76, 27, 45, 56, 0], - [21, 94, 80, 74, 100, 20, 55, 65]], - [[34, 47, 56, 73, 55, 59, 31, 17], [57, 43, 0, 23, 41, 100, 73, 86], - [24, 53, 95, 45, 38, 17, 28, 76]], - [[47, 37, 100, 6, 20, 16, 17, 59], [40, 44, 64, 13, 0, 73, 76, 71], - [23, 52, 19, 70, 41, 43, 30, 28]], - [[53, 38, 44, 33, 9, 71, 31, 82], [62, 100, 70, 65, 74, 22, 47, 59], - [66, 82, 20, 0, 15, 3, 57, 60]], - [[46, 33, 0, 31, 50, 50, 35, 50], [26, 77, 56, 47, 37, 51, 56, 57], - [28, 27, 100, 21, 29, 26, 83, 25]], - [[70, 88, 0, 15, 7, 34, 100, 58], [53, 68, 17, 17, 16, 26, 84, 61], - [63, 80, 10, 15, 11, 43, 84, 50]], - [[91, 49, 99, 85, 62, 38, 21, 87], [18, 36, 74, 84, 40, 45, 39, 88], - [63, 54, 57, 100, 45, 20, 0, 76]]] + [ + [39, 19, 95, 0, 32, 97, 65, 69], + [22, 40, 67, 14, 100, 60, 5, 34], + [46, 27, 72, 45, 18, 84, 100, 33], + ], + [ + [61, 96, 22, 34, 34, 35, 39, 54], + [39, 42, 77, 76, 27, 45, 56, 0], + [21, 94, 80, 74, 100, 20, 55, 65], + ], + [ + [34, 47, 56, 73, 55, 59, 31, 17], + [57, 43, 0, 23, 41, 100, 73, 86], + [24, 53, 95, 45, 38, 17, 28, 76], + ], + [ + [47, 37, 100, 6, 20, 16, 17, 59], + [40, 44, 64, 13, 0, 73, 76, 71], + [23, 52, 19, 70, 41, 43, 30, 28], + ], + [ + [53, 38, 44, 33, 9, 71, 31, 82], + [62, 100, 70, 65, 74, 22, 47, 59], + [66, 82, 20, 0, 15, 3, 57, 60], + ], + [ + [46, 33, 0, 31, 50, 50, 35, 50], + [26, 77, 56, 47, 37, 51, 56, 57], + [28, 27, 100, 21, 29, 26, 83, 25], + ], + [ + [70, 88, 0, 15, 7, 34, 100, 58], + [53, 68, 17, 17, 16, 26, 84, 61], + [63, 80, 10, 15, 11, 43, 84, 50], + ], + [ + [91, 49, 99, 85, 62, 38, 21, 87], + [18, 36, 74, 84, 40, 45, 39, 88], + [63, 54, 57, 100, 45, 20, 0, 76], + ], + ] def test_local_utilities6(bayesian_hgg1): assert bayesian_hgg1.local_bayesiangames[1].utilities == [ - [[72, 67, 47, 94, 73, 92, 80, 81], [55, 66, 45, 62, 78, 91, 55, 53], - [54, 75, 47, 42, 0, 52, 47, 100]], - [[64, 79, 39, 7, 43, 22, 68, 26], [48, 67, 62, 5, 74, 82, 77, 65], - [40, 65, 38, 0, 59, 69, 100, 86]], - [[44, 53, 46, 82, 44, 89, 69, 97], [61, 96, 88, 93, 70, 20, 100, 46], - [31, 89, 0, 61, 48, 77, 84, 46]], - [[59, 74, 63, 100, 34, 31, 38, 45], [55, 52, 83, 74, 10, 65, 5, 50], - [74, 64, 65, 96, 19, 70, 0, 38]], - [[32, 100, 0, 54, 5, 37, 45, 66], [2, 23, 49, 3, 62, 21, 23, 44], - [11, 54, 67, 8, 37, 69, 83, 27]], - [[41, 67, 72, 12, 65, 74, 65, 53], [68, 68, 57, 49, 0, 91, 80, 61], - [97, 78, 86, 100, 34, 62, 57, 87]], - [[52, 54, 63, 18, 37, 67, 75, 73], [47, 65, 93, 91, 59, 60, 0, 43], - [82, 76, 49, 91, 100, 82, 95, 50]], - [[39, 19, 95, 0, 32, 97, 65, 69], [22, 40, 67, 14, 100, 60, 5, 34], - [46, 27, 72, 45, 18, 84, 100, 33]]] + [ + [72, 67, 47, 94, 73, 92, 80, 81], + [55, 66, 45, 62, 78, 91, 55, 53], + [54, 75, 47, 42, 0, 52, 47, 100], + ], + [ + [64, 79, 39, 7, 43, 22, 68, 26], + [48, 67, 62, 5, 74, 82, 77, 65], + [40, 65, 38, 0, 59, 69, 100, 86], + ], + [ + [44, 53, 46, 82, 44, 89, 69, 97], + [61, 96, 88, 93, 70, 20, 100, 46], + [31, 89, 0, 61, 48, 77, 84, 46], + ], + [ + [59, 74, 63, 100, 34, 31, 38, 45], + [55, 52, 83, 74, 10, 65, 5, 50], + [74, 64, 65, 96, 19, 70, 0, 38], + ], + [ + [32, 100, 0, 54, 5, 37, 45, 66], + [2, 23, 49, 3, 62, 21, 23, 44], + [11, 54, 67, 8, 37, 69, 83, 27], + ], + [ + [41, 67, 72, 12, 65, 74, 65, 53], + [68, 68, 57, 49, 0, 91, 80, 61], + [97, 78, 86, 100, 34, 62, 57, 87], + ], + [ + [52, 54, 63, 18, 37, 67, 75, 73], + [47, 65, 93, 91, 59, 60, 0, 43], + [82, 76, 49, 91, 100, 82, 95, 50], + ], + [ + [39, 19, 95, 0, 32, 97, 65, 69], + [22, 40, 67, 14, 100, 60, 5, 34], + [46, 27, 72, 45, 18, 84, 100, 33], + ], + ] def test_local_proba1(bayesian_polymatrix): - assert bayesian_polymatrix.local_bayesiangames[0].p == [Fraction(4, 10), - Fraction(1, 10), - Fraction(1, 10), - Fraction(4, 10)] + assert bayesian_polymatrix.local_bayesiangames[0].p == [ + Fraction(4, 10), + Fraction(1, 10), + Fraction(1, 10), + Fraction(4, 10), + ] def test_local_proba2(bayesian_polymatrix): - assert bayesian_polymatrix.local_bayesiangames[1].p == [Fraction(4, 10), - Fraction(1, 10), - Fraction(1, 10), - Fraction(4, 10)] + assert bayesian_polymatrix.local_bayesiangames[1].p == [ + Fraction(4, 10), + Fraction(1, 10), + Fraction(1, 10), + Fraction(4, 10), + ] def test_local_proba3(bayesian_polymatrix): - assert bayesian_polymatrix.local_bayesiangames[2].p == [Fraction(4, 10), - Fraction(1, 10), - Fraction(1, 10), - Fraction(4, 10)] + assert bayesian_polymatrix.local_bayesiangames[2].p == [ + Fraction(4, 10), + Fraction(1, 10), + Fraction(1, 10), + Fraction(4, 10), + ] def test_local_proba4(bayesian_polymatrix): - assert bayesian_polymatrix.local_bayesiangames[3].p == [Fraction(4, 10), - Fraction(1, 10), - Fraction(1, 10), - Fraction(4, 10)] + assert bayesian_polymatrix.local_bayesiangames[3].p == [ + Fraction(4, 10), + Fraction(1, 10), + Fraction(1, 10), + Fraction(4, 10), + ] def test_local_proba5(bayesian_hgg1): - assert bayesian_hgg1.local_bayesiangames[0].p == [Fraction(6, 45), - Fraction(1, 5), - Fraction(8, 45), - Fraction(6, 45), - Fraction(6, 45), - Fraction(4, 45), - Fraction(1, 15), - Fraction(1, 15)] + assert bayesian_hgg1.local_bayesiangames[0].p == [ + Fraction(6, 45), + Fraction(1, 5), + Fraction(8, 45), + Fraction(6, 45), + Fraction(6, 45), + Fraction(4, 45), + Fraction(1, 15), + Fraction(1, 15), + ] def test_local_proba6(bayesian_hgg1): - assert bayesian_hgg1.local_bayesiangames[1].p == [Fraction(1, 43), - Fraction(7, 43), - Fraction(9, 43), - Fraction(1, 43), - Fraction(7, 43), - Fraction(3, 43), - Fraction(6, 43), - Fraction(9, 43)] + assert bayesian_hgg1.local_bayesiangames[1].p == [ + Fraction(1, 43), + Fraction(7, 43), + Fraction(9, 43), + Fraction(1, 43), + Fraction(7, 43), + Fraction(3, 43), + Fraction(6, 43), + Fraction(9, 43), + ] def test_expected_utilities1(bayesian_polymatrix): assert bayesian_polymatrix.expected_utilities( - {(0, 0): [1, 0], (0, 1): [1, 0], (1, 0): [1, 0], (1, 1): [1, 0], - (2, 0): [1, 0], (2, 1): [1, 0], (3, 0): [1, 0], (3, 1): [1, 0]}) == { - (0, 0): Fraction(6, 1), (0, 1): Fraction(2, 1), - (1, 0): Fraction(6, 1), (1, 1): Fraction(2, 1), - (2, 0): Fraction(6, 1), (2, 1): Fraction(2, 1), - (3, 0): Fraction(6, 1), (3, 1): Fraction(2, 1)} + { + (0, 0): [1, 0], + (0, 1): [1, 0], + (1, 0): [1, 0], + (1, 1): [1, 0], + (2, 0): [1, 0], + (2, 1): [1, 0], + (3, 0): [1, 0], + (3, 1): [1, 0], + } + ) == { + (0, 0): Fraction(6, 1), + (0, 1): Fraction(2, 1), + (1, 0): Fraction(6, 1), + (1, 1): Fraction(2, 1), + (2, 0): Fraction(6, 1), + (2, 1): Fraction(2, 1), + (3, 0): Fraction(6, 1), + (3, 1): Fraction(2, 1), + } def test_expected_utilities2(bayesian_polymatrix): assert bayesian_polymatrix.expected_utilities( - {(0, 0): [0, 1], (0, 1): [0, 1], (1, 0): [0, 1], (1, 1): [0, 1], - (2, 0): [0, 1], (2, 1): [0, 1], (3, 0): [0, 1], - (3, 1): [0, 1]}) == {(0, 0): Fraction(4, 1), (0, 1): Fraction(4, 1), - (1, 0): Fraction(4, 1), (1, 1): Fraction(4, 1), - (2, 0): Fraction(4, 1), (2, 1): Fraction(4, 1), - (3, 0): Fraction(4, 1), - (3, 1): Fraction(4, 1)} + { + (0, 0): [0, 1], + (0, 1): [0, 1], + (1, 0): [0, 1], + (1, 1): [0, 1], + (2, 0): [0, 1], + (2, 1): [0, 1], + (3, 0): [0, 1], + (3, 1): [0, 1], + } + ) == { + (0, 0): Fraction(4, 1), + (0, 1): Fraction(4, 1), + (1, 0): Fraction(4, 1), + (1, 1): Fraction(4, 1), + (2, 0): Fraction(4, 1), + (2, 1): Fraction(4, 1), + (3, 0): Fraction(4, 1), + (3, 1): Fraction(4, 1), + } def test_expected_utilities3(bayesian_hgg1): - assert bayesian_hgg1.expected_utilities({(0, 0): [1, 0], (0, 1): [1, 0], - (1, 0): [1, 0], (1, 1): [1, 0], - (2, 0): [1, 0], (2, 1): [1, 0], - (3, 0): [1, 0], - (3, 1): [1, 0]}) == { - (0, 0): Fraction(17447, 174), (0, 1): Fraction(8157, 80), - (1, 0): Fraction(959, 25), (1, 1): Fraction(909, 20), - (2, 0): Fraction(10987, 138), (2, 1): Fraction(19774, 275), - (3, 0): Fraction(902, 23), (3, 1): Fraction(1059, 20)} + assert bayesian_hgg1.expected_utilities( + { + (0, 0): [1, 0], + (0, 1): [1, 0], + (1, 0): [1, 0], + (1, 1): [1, 0], + (2, 0): [1, 0], + (2, 1): [1, 0], + (3, 0): [1, 0], + (3, 1): [1, 0], + } + ) == { + (0, 0): Fraction(17447, 174), + (0, 1): Fraction(8157, 80), + (1, 0): Fraction(959, 25), + (1, 1): Fraction(909, 20), + (2, 0): Fraction(10987, 138), + (2, 1): Fraction(19774, 275), + (3, 0): Fraction(902, 23), + (3, 1): Fraction(1059, 20), + } def test_is_equilibrium1(bayesian_polymatrix): assert bayesian_polymatrix.is_equilibrium( - {(0, 0): [0, 1], (0, 1): [0, 1], (1, 0): [0, 1], (1, 1): [0, 1], - (2, 0): [0, 1], (2, 1): [0, 1], (3, 0): [0, 1], - (3, 1): [0, 1]}) + { + (0, 0): [0, 1], + (0, 1): [0, 1], + (1, 0): [0, 1], + (1, 1): [0, 1], + (2, 0): [0, 1], + (2, 1): [0, 1], + (3, 0): [0, 1], + (3, 1): [0, 1], + } + ) def test_is_equilibrium2(bayesian_polymatrix): assert bayesian_polymatrix.is_equilibrium( - {(0, 0): [1, 0], (0, 1): [1, 0], (1, 0): [1, 0], (1, 1): [1, 0], - (2, 0): [1, 0], (2, 1): [1, 0], (3, 0): [1, 0], (3, 1): [1, 0]}) + { + (0, 0): [1, 0], + (0, 1): [1, 0], + (1, 0): [1, 0], + (1, 1): [1, 0], + (2, 0): [1, 0], + (2, 1): [1, 0], + (3, 0): [1, 0], + (3, 1): [1, 0], + } + ) def test_is_equilibrium3(bayesian_polymatrix): assert bayesian_polymatrix.is_equilibrium( - {(0, 0): [1, 0], (0, 1): [0, 1], (1, 0): [1, 0], (1, 1): [0, 1], - (2, 0): [1, 0], (2, 1): [0, 1], (3, 0): [1, 0], (3, 1): [0, 1]}) + { + (0, 0): [1, 0], + (0, 1): [0, 1], + (1, 0): [1, 0], + (1, 1): [0, 1], + (2, 0): [1, 0], + (2, 1): [0, 1], + (3, 0): [1, 0], + (3, 1): [0, 1], + } + ) def test_read_GameFile(): @@ -313,15 +564,22 @@ def test_read_GameFile(): assert read_bhgg.hypergraph == [[1, 2], [0, 1]] assert read_bhgg.p == [ [Fraction(7, 19), Fraction(1, 19), Fraction(2, 19), Fraction(9, 19)], - [Fraction(1, 17), Fraction(4, 17), Fraction(5, 17), Fraction(7, 17)]] - assert read_bhgg.utilities == [[[[15, 41, 0, 7], [14, 23, 65, 100]], - [[0, 41, 58, 92], [100, 51, 72, 93]], - [[56, 38, 0, 14], [100, 95, 43, 0]], - [[53, 69, 17, 15], [98, 12, 100, 0]]], - [[[39, 12, 42, 50], [0, 78, 38, 100]], - [[0, 7, 100, 58], [15, 10, 66, 78]], - [[74, 100, 96, 76], [0, 29, 98, 35]], - [[52, 21, 10, 100], [0, 43, 81, 56]]]] + [Fraction(1, 17), Fraction(4, 17), Fraction(5, 17), Fraction(7, 17)], + ] + assert read_bhgg.utilities == [ + [ + [[15, 41, 0, 7], [14, 23, 65, 100]], + [[0, 41, 58, 92], [100, 51, 72, 93]], + [[56, 38, 0, 14], [100, 95, 43, 0]], + [[53, 69, 17, 15], [98, 12, 100, 0]], + ], + [ + [[39, 12, 42, 50], [0, 78, 38, 100]], + [[0, 7, 100, 58], [15, 10, 66, 78]], + [[74, 100, 96, 76], [0, 29, 98, 35]], + [[52, 21, 10, 100], [0, 43, 81, 56]], + ], + ] def test_read_GameFile2(bayesian_hgg1): @@ -380,43 +638,99 @@ def test_write_GameFile2(bayesian_hgg1): def test_convert_to_HGG(bayesian_polymatrix): pmg, index_old = bayesian_polymatrix.convert_to_HGG() - assert pmg.players_actions == [[0, 1], [0, 1], [0, 1], [0, 1], - [0, 1], [0, 1], [0, 1], [0, 1]] + assert pmg.players_actions == [ + [0, 1], + [0, 1], + [0, 1], + [0, 1], + [0, 1], + [0, 1], + [0, 1], + [0, 1], + ] for couple in pmg.hypergraph: - assert couple in [[0, 2], [0, 3], [1, 2], [1, 3], [2, 4], [2, 5], - [3, 4], [3, 5], [4, 6], [4, 7], [5, 6], [5, 7], - [0, 6], [0, 7], [1, 6], [1, 7]] + assert couple in [ + [0, 2], + [0, 3], + [1, 2], + [1, 3], + [2, 4], + [2, 5], + [3, 4], + [3, 5], + [4, 6], + [4, 7], + [5, 6], + [5, 7], + [0, 6], + [0, 7], + [1, 6], + [1, 7], + ] # assert pmg.utilities ==[] assert pmg.utilities == [ - [[Fraction(12, 5), 0, 0, Fraction(8, 5)], - [Fraction(12, 5), 0, 0, Fraction(8, 5)]], - [[Fraction(3, 5), 0, 0, Fraction(2, 5)], - [Fraction(1, 5), 0, 0, Fraction(2, 5)]], - [[Fraction(1, 5), 0, 0, Fraction(2, 5)], - [Fraction(3, 5), 0, 0, Fraction(2, 5)]], - [[Fraction(4, 5), 0, 0, Fraction(8, 5)], - [Fraction(4, 5), 0, 0, Fraction(8, 5)]], - [[Fraction(12, 5), 0, 0, Fraction(8, 5)], - [Fraction(12, 5), 0, 0, Fraction(8, 5)]], - [[Fraction(3, 5), 0, 0, Fraction(2, 5)], - [Fraction(1, 5), 0, 0, Fraction(2, 5)]], - [[Fraction(1, 5), 0, 0, Fraction(2, 5)], - [Fraction(3, 5), 0, 0, Fraction(2, 5)]], - [[Fraction(4, 5), 0, 0, Fraction(8, 5)], - [Fraction(4, 5), 0, 0, Fraction(8, 5)]], - [[Fraction(12, 5), 0, 0, Fraction(8, 5)], - [Fraction(12, 5), 0, 0, Fraction(8, 5)]], - [[Fraction(3, 5), 0, 0, Fraction(2, 5)], - [Fraction(1, 5), 0, 0, Fraction(2, 5)]], - [[Fraction(1, 5), 0, 0, Fraction(2, 5)], - [Fraction(3, 5), 0, 0, Fraction(2, 5)]], - [[Fraction(4, 5), 0, 0, Fraction(8, 5)], - [Fraction(4, 5), 0, 0, Fraction(8, 5)]], - [[Fraction(12, 5), 0, 0, Fraction(8, 5)], - [Fraction(12, 5), 0, 0, Fraction(8, 5)]], - [[Fraction(3, 5), 0, 0, Fraction(2, 5)], - [Fraction(1, 5), 0, 0, Fraction(2, 5)]], - [[Fraction(1, 5), 0, 0, Fraction(2, 5)], - [Fraction(3, 5), 0, 0, Fraction(2, 5)]], - [[Fraction(4, 5), 0, 0, Fraction(8, 5)], - [Fraction(4, 5), 0, 0, Fraction(8, 5)]]] + [ + [Fraction(12, 5), 0, 0, Fraction(8, 5)], + [Fraction(12, 5), 0, 0, Fraction(8, 5)], + ], + [ + [Fraction(3, 5), 0, 0, Fraction(2, 5)], + [Fraction(1, 5), 0, 0, Fraction(2, 5)], + ], + [ + [Fraction(1, 5), 0, 0, Fraction(2, 5)], + [Fraction(3, 5), 0, 0, Fraction(2, 5)], + ], + [ + [Fraction(4, 5), 0, 0, Fraction(8, 5)], + [Fraction(4, 5), 0, 0, Fraction(8, 5)], + ], + [ + [Fraction(12, 5), 0, 0, Fraction(8, 5)], + [Fraction(12, 5), 0, 0, Fraction(8, 5)], + ], + [ + [Fraction(3, 5), 0, 0, Fraction(2, 5)], + [Fraction(1, 5), 0, 0, Fraction(2, 5)], + ], + [ + [Fraction(1, 5), 0, 0, Fraction(2, 5)], + [Fraction(3, 5), 0, 0, Fraction(2, 5)], + ], + [ + [Fraction(4, 5), 0, 0, Fraction(8, 5)], + [Fraction(4, 5), 0, 0, Fraction(8, 5)], + ], + [ + [Fraction(12, 5), 0, 0, Fraction(8, 5)], + [Fraction(12, 5), 0, 0, Fraction(8, 5)], + ], + [ + [Fraction(3, 5), 0, 0, Fraction(2, 5)], + [Fraction(1, 5), 0, 0, Fraction(2, 5)], + ], + [ + [Fraction(1, 5), 0, 0, Fraction(2, 5)], + [Fraction(3, 5), 0, 0, Fraction(2, 5)], + ], + [ + [Fraction(4, 5), 0, 0, Fraction(8, 5)], + [Fraction(4, 5), 0, 0, Fraction(8, 5)], + ], + [ + [Fraction(12, 5), 0, 0, Fraction(8, 5)], + [Fraction(12, 5), 0, 0, Fraction(8, 5)], + ], + [ + [Fraction(3, 5), 0, 0, Fraction(2, 5)], + [Fraction(1, 5), 0, 0, Fraction(2, 5)], + ], + [ + [Fraction(1, 5), 0, 0, Fraction(2, 5)], + [Fraction(3, 5), 0, 0, Fraction(2, 5)], + ], + [ + [Fraction(4, 5), 0, 0, Fraction(8, 5)], + [Fraction(4, 5), 0, 0, Fraction(8, 5)], + ], + ] diff --git a/test/test_bayesiangame.py b/test/test_bayesiangame.py index 6f9973f..54bfc7d 100644 --- a/test/test_bayesiangame.py +++ b/test/test_bayesiangame.py @@ -8,12 +8,14 @@ from fractions import Fraction @pytest.fixture def bimat_bg(): players_actions = [[0, 1, 2], [0, 1]] - utilities = [[[-3, -7, -10, -1, -5, -9], [-3, -7, -1, -5, -10, -9]], - [[-2, -6, -9, -1, -4, -8], [-2, -6, -1, -4, -9, -8]], - [[-2, -5, -8, -1, -3, -7], [-2, -5, -1, -3, -8, -7]], - [[-2, -4, -7, -1, -3, -6], [-2, -4, -1, -3, -7, -6]], - [[-2, -4, -6, -1, -3, -5], [-2, -4, -1, -3, -6, -5]], - [[-3, -7, -1, -5, -10, -9], [-3, -7, -10, -1, -5, -9]]] + utilities = [ + [[-3, -7, -10, -1, -5, -9], [-3, -7, -1, -5, -10, -9]], + [[-2, -6, -9, -1, -4, -8], [-2, -6, -1, -4, -9, -8]], + [[-2, -5, -8, -1, -3, -7], [-2, -5, -1, -3, -8, -7]], + [[-2, -4, -7, -1, -3, -6], [-2, -4, -1, -3, -7, -6]], + [[-2, -4, -6, -1, -3, -5], [-2, -4, -1, -3, -6, -5]], + [[-3, -7, -1, -5, -10, -9], [-3, -7, -10, -1, -5, -9]], + ] theta = [[0, 1], [0, 1, 2]] p = [2, 4, 4, 4, 2, 4] return BG(players_actions, utilities, theta, p) @@ -22,8 +24,7 @@ def bimat_bg(): @pytest.fixture def sherif_bg1(): players_actions = [[0, 1], [0, 1]] - utilities = [[[-1, -1, -2, 0], [-3, -2, -1, 0]], - [[0, -1, -2, 1], [0, -2, 2, -1]]] + utilities = [[[-1, -1, -2, 0], [-3, -2, -1, 0]], [[0, -1, -2, 1], [0, -2, 2, -1]]] theta = [[0], [0, 1]] p = [1, 2] return BG(players_actions, utilities, theta, p) @@ -32,8 +33,7 @@ def sherif_bg1(): @pytest.fixture def sherif_bg2(): players_actions = [[0, 1], [0, 1]] - utilities = [[[-1, -1, -2, 0], [-3, -2, -1, 0]], - [[0, -1, -2, 1], [0, -2, 2, -1]]] + utilities = [[[-1, -1, -2, 0], [-3, -2, -1, 0]], [[0, -1, -2, 1], [0, -2, 2, -1]]] theta = [[0], [0, 1]] p = [2, 1] return BG(players_actions, utilities, theta, p) @@ -42,8 +42,7 @@ def sherif_bg2(): @pytest.fixture def sherif_bg3(): players_actions = [[0, 1], [0, 1]] - utilities = [[[-1, -1, -2, 0], [-3, -2, -1, 0]], - [[0, -1, -2, 1], [0, -2, 2, -1]]] + utilities = [[[-1, -1, -2, 0], [-3, -2, -1, 0]], [[0, -1, -2, 1], [0, -2, 2, -1]]] theta = [[0], [0, 1]] p = [3, 1] return BG(players_actions, utilities, theta, p) @@ -55,22 +54,47 @@ def three_bg(): theta = [[0, 1], [0, 1], [0, 1]] all_p = [1, 2, 1, 4, 2, 2, 2, 6] utilities = [ - [[87, 56, 33, 21, 88, 77, 79, 69], [39, 52, 4, 92, 1, 78, 60, 69], - [2, 28, 92, 11, 16, 63, 21, 22]], - [[97, 12, 13, 92, 38, 2, 91, 62], [32, 40, 10, 57, 19, 18, 19, 15], - [35, 12, 0, 56, 93, 22, 52, 35]], - [[67, 0, 13, 87, 83, 6, 1, 80], [27, 63, 31, 22, 18, 8, 46, 81], - [88, 28, 35, 5, 52, 67, 21, 12]], - [[76, 13, 70, 36, 8, 39, 22, 42], [43, 82, 81, 37, 70, 58, 28, 91], - [13, 25, 6, 96, 31, 27, 5, 37]], - [[42, 62, 83, 91, 62, 11, 19, 0], [33, 88, 78, 14, 90, 27, 40, 86], - [29, 91, 63, 65, 78, 36, 3, 35]], - [[78, 51, 25, 64, 84, 53, 19, 30], [94, 8, 47, 52, 17, 89, 21, 54], - [39, 13, 7, 46, 4, 14, 46, 3]], - [[21, 33, 41, 4, 40, 5, 47, 13], [72, 6, 92, 29, 73, 54, 22, 30], - [23, 86, 14, 46, 99, 34, 62, 97]], - [[69, 11, 25, 65, 82, 52, 68, 56], [33, 12, 39, 98, 41, 63, 99, 10], - [18, 62, 99, 58, 62, 25, 55, 7]]] + [ + [87, 56, 33, 21, 88, 77, 79, 69], + [39, 52, 4, 92, 1, 78, 60, 69], + [2, 28, 92, 11, 16, 63, 21, 22], + ], + [ + [97, 12, 13, 92, 38, 2, 91, 62], + [32, 40, 10, 57, 19, 18, 19, 15], + [35, 12, 0, 56, 93, 22, 52, 35], + ], + [ + [67, 0, 13, 87, 83, 6, 1, 80], + [27, 63, 31, 22, 18, 8, 46, 81], + [88, 28, 35, 5, 52, 67, 21, 12], + ], + [ + [76, 13, 70, 36, 8, 39, 22, 42], + [43, 82, 81, 37, 70, 58, 28, 91], + [13, 25, 6, 96, 31, 27, 5, 37], + ], + [ + [42, 62, 83, 91, 62, 11, 19, 0], + [33, 88, 78, 14, 90, 27, 40, 86], + [29, 91, 63, 65, 78, 36, 3, 35], + ], + [ + [78, 51, 25, 64, 84, 53, 19, 30], + [94, 8, 47, 52, 17, 89, 21, 54], + [39, 13, 7, 46, 4, 14, 46, 3], + ], + [ + [21, 33, 41, 4, 40, 5, 47, 13], + [72, 6, 92, 29, 73, 54, 22, 30], + [23, 86, 14, 46, 99, 34, 62, 97], + ], + [ + [69, 11, 25, 65, 82, 52, 68, 56], + [33, 12, 39, 98, 41, 63, 99, 10], + [18, 62, 99, 58, 62, 25, 55, 7], + ], + ] return BG(players_actions, utilities, theta, all_p) @@ -79,48 +103,80 @@ def three_bg(): def test_joint_actions1(bimat_bg): - assert (bimat_bg.joint_actions == np.mat( - [[0., 0.], [0., 1.], [1., 0.], [1., 1.], [2., 0.], [2., 1.]])).all() + assert ( + bimat_bg.joint_actions + == np.mat( + [[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0], [2.0, 0.0], [2.0, 1.0]] + ) + ).all() def test_joint_actions2(sherif_bg1): - assert (sherif_bg1.joint_actions == np.mat( - [[0., 0.], [0., 1.], [1., 0.], [1., 1.]])).all() + assert ( + sherif_bg1.joint_actions + == np.mat([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]]) + ).all() def test_joint_actions3(three_bg): - assert (three_bg.joint_actions == np.mat( - [[0., 0., 0.], [0., 0., 1.], [0., 1., 0.], [0., 1., 1.], [1., 0., 0.], - [1., 0., 1.], [1., 1., 0.], - [1., 1., 1.]])).all() + assert ( + three_bg.joint_actions + == np.mat( + [ + [0.0, 0.0, 0.0], + [0.0, 0.0, 1.0], + [0.0, 1.0, 0.0], + [0.0, 1.0, 1.0], + [1.0, 0.0, 0.0], + [1.0, 0.0, 1.0], + [1.0, 1.0, 0.0], + [1.0, 1.0, 1.0], + ] + ) + ).all() def test_joint_type1(bimat_bg): - assert (bimat_bg.joint_theta == np.mat( - [[0., 0.], [0., 1.], [0., 2.], [1., 0.], [1., 1.], [1., 2.]])).all() + assert ( + bimat_bg.joint_theta + == np.mat( + [[0.0, 0.0], [0.0, 1.0], [0.0, 2.0], [1.0, 0.0], [1.0, 1.0], [1.0, 2.0]] + ) + ).all() def test_joint_type2(sherif_bg1): - assert (sherif_bg1.joint_theta == np.mat([[0., 0.], [0., 1.]])).all() + assert (sherif_bg1.joint_theta == np.mat([[0.0, 0.0], [0.0, 1.0]])).all() def test_joint_type3(three_bg): - assert (three_bg.joint_theta == np.mat( - [[0., 0., 0.], [0., 0., 1.], [0., 1., 0.], [0., 1., 1.], [1., 0., 0.], - [1., 0., 1.], [1., 1., 0.], - [1., 1., 1.]])).all() + assert ( + three_bg.joint_theta + == np.mat( + [ + [0.0, 0.0, 0.0], + [0.0, 0.0, 1.0], + [0.0, 1.0, 0.0], + [0.0, 1.0, 1.0], + [1.0, 0.0, 0.0], + [1.0, 0.0, 1.0], + [1.0, 1.0, 0.0], + [1.0, 1.0, 1.0], + ] + ) + ).all() def test_proba_norm1(bimat_bg): - assert (sum(bimat_bg.p) == 1) + assert sum(bimat_bg.p) == 1 def test_proba_norm2(sherif_bg1): - assert (sum(sherif_bg1.p) == 1) + assert sum(sherif_bg1.p) == 1 def test_proba_norm3(three_bg): - assert (sum(three_bg.p) == 1) + assert sum(three_bg.p) == 1 """ @@ -133,9 +189,14 @@ generate_joint_matrix(into_mat) def test_proba_type1(bimat_bg): - assert bimat_bg.proba_type() == {0: Fraction(1, 10), 1: Fraction(2, 10), - 2: Fraction(2, 10), 3: Fraction(2, 10), - 4: Fraction(1, 10), 5: Fraction(2, 10)} + assert bimat_bg.proba_type() == { + 0: Fraction(1, 10), + 1: Fraction(2, 10), + 2: Fraction(2, 10), + 3: Fraction(2, 10), + 4: Fraction(1, 10), + 5: Fraction(2, 10), + } def test_proba_type2(sherif_bg1): @@ -143,10 +204,16 @@ def test_proba_type2(sherif_bg1): def test_proba_type3(three_bg): - assert three_bg.proba_type() == {0: Fraction(1, 20), 1: Fraction(2, 20), - 2: Fraction(1, 20), 3: Fraction(4, 20), - 4: Fraction(2, 20), 5: Fraction(2, 20), - 6: Fraction(2, 20), 7: Fraction(6, 20)} + assert three_bg.proba_type() == { + 0: Fraction(1, 20), + 1: Fraction(2, 20), + 2: Fraction(1, 20), + 3: Fraction(4, 20), + 4: Fraction(2, 20), + 5: Fraction(2, 20), + 6: Fraction(2, 20), + 7: Fraction(6, 20), + } def test_get_index_of_type1(bimat_bg): @@ -214,35 +281,47 @@ def test_get_index_of_type16(three_bg): def test_conditional_probabilities1(bimat_bg): - assert bimat_bg.conditional_probabilities(0, 0) == {0: Fraction(1, 5), - 1: Fraction(2, 5), - 2: Fraction(2, 5)} + assert bimat_bg.conditional_probabilities(0, 0) == { + 0: Fraction(1, 5), + 1: Fraction(2, 5), + 2: Fraction(2, 5), + } def test_conditional_probabilities2(bimat_bg): - assert bimat_bg.conditional_probabilities(0, 1) == {3: Fraction(2, 5), - 4: Fraction(1, 5), - 5: Fraction(2, 5)} + assert bimat_bg.conditional_probabilities(0, 1) == { + 3: Fraction(2, 5), + 4: Fraction(1, 5), + 5: Fraction(2, 5), + } def test_conditional_probabilities3(bimat_bg): - assert bimat_bg.conditional_probabilities(1, 0) == {0: Fraction(1, 3), - 3: Fraction(2, 3)} + assert bimat_bg.conditional_probabilities(1, 0) == { + 0: Fraction(1, 3), + 3: Fraction(2, 3), + } def test_conditional_probabilities4(bimat_bg): - assert bimat_bg.conditional_probabilities(1, 1) == {1: Fraction(2, 3), - 4: Fraction(1, 3)} + assert bimat_bg.conditional_probabilities(1, 1) == { + 1: Fraction(2, 3), + 4: Fraction(1, 3), + } def test_conditional_probabilities5(bimat_bg): - assert bimat_bg.conditional_probabilities(1, 2) == {2: Fraction(1, 2), - 5: Fraction(1, 2)} + assert bimat_bg.conditional_probabilities(1, 2) == { + 2: Fraction(1, 2), + 5: Fraction(1, 2), + } def test_conditional_probabilities6(sherif_bg1): - assert sherif_bg1.conditional_probabilities(0, 0) == {0: Fraction(1, 3), - 1: Fraction(2, 3)} + assert sherif_bg1.conditional_probabilities(0, 0) == { + 0: Fraction(1, 3), + 1: Fraction(2, 3), + } def test_conditional_probabilities7(sherif_bg1): @@ -254,50 +333,64 @@ def test_conditional_probabilities8(sherif_bg1): def test_conditional_probabilities9(sherif_bg2): - assert sherif_bg2.conditional_probabilities(0, 0) == {1: Fraction(1, 3), - 0: Fraction(2, 3)} + assert sherif_bg2.conditional_probabilities(0, 0) == { + 1: Fraction(1, 3), + 0: Fraction(2, 3), + } def test_conditional_probabilities10(three_bg): - assert three_bg.conditional_probabilities(0, 0) == {0: Fraction(1, 8), - 1: Fraction(1, 4), - 2: Fraction(1, 8), - 3: Fraction(1, 2)} + assert three_bg.conditional_probabilities(0, 0) == { + 0: Fraction(1, 8), + 1: Fraction(1, 4), + 2: Fraction(1, 8), + 3: Fraction(1, 2), + } def test_conditional_probabilities11(three_bg): - assert three_bg.conditional_probabilities(0, 1) == {4: Fraction(1, 6), - 5: Fraction(1, 6), - 6: Fraction(1, 6), - 7: Fraction(1, 2)} + assert three_bg.conditional_probabilities(0, 1) == { + 4: Fraction(1, 6), + 5: Fraction(1, 6), + 6: Fraction(1, 6), + 7: Fraction(1, 2), + } def test_conditional_probabilities12(three_bg): - assert three_bg.conditional_probabilities(1, 0) == {0: Fraction(1, 7), - 1: Fraction(2, 7), - 4: Fraction(2, 7), - 5: Fraction(2, 7)} + assert three_bg.conditional_probabilities(1, 0) == { + 0: Fraction(1, 7), + 1: Fraction(2, 7), + 4: Fraction(2, 7), + 5: Fraction(2, 7), + } def test_conditional_probabilities13(three_bg): - assert three_bg.conditional_probabilities(1, 1) == {2: Fraction(1, 13), - 3: Fraction(4, 13), - 6: Fraction(2, 13), - 7: Fraction(6, 13)} + assert three_bg.conditional_probabilities(1, 1) == { + 2: Fraction(1, 13), + 3: Fraction(4, 13), + 6: Fraction(2, 13), + 7: Fraction(6, 13), + } def test_conditional_probabilities14(three_bg): - assert three_bg.conditional_probabilities(2, 0) == {0: Fraction(1, 6), - 2: Fraction(1, 6), - 4: Fraction(1, 3), - 6: Fraction(1, 3)} + assert three_bg.conditional_probabilities(2, 0) == { + 0: Fraction(1, 6), + 2: Fraction(1, 6), + 4: Fraction(1, 3), + 6: Fraction(1, 3), + } def test_conditional_probabilities15(three_bg): - assert three_bg.conditional_probabilities(2, 1) == {1: Fraction(1, 7), - 3: Fraction(2, 7), - 5: Fraction(1, 7), - 7: Fraction(3, 7)} + assert three_bg.conditional_probabilities(2, 1) == { + 1: Fraction(1, 7), + 3: Fraction(2, 7), + 5: Fraction(1, 7), + 7: Fraction(3, 7), + } def test_dico_utilities1(bimat_bg): @@ -307,81 +400,128 @@ def test_dico_utilities1(bimat_bg): 2: [[-2, -5, -8, -1, -3, -7], [-2, -5, -1, -3, -8, -7]], 3: [[-2, -4, -7, -1, -3, -6], [-2, -4, -1, -3, -7, -6]], 4: [[-2, -4, -6, -1, -3, -5], [-2, -4, -1, -3, -6, -5]], - 5: [[-3, -7, -1, -5, -10, -9], [-3, -7, -10, -1, -5, -9]]} + 5: [[-3, -7, -1, -5, -10, -9], [-3, -7, -10, -1, -5, -9]], + } def test_dico_utilities2(sherif_bg1): assert sherif_bg1.dico_utilities() == { 0: [[-1, -1, -2, 0], [-3, -2, -1, 0]], - 1: [[0, -1, -2, 1], [0, -2, 2, -1]]} + 1: [[0, -1, -2, 1], [0, -2, 2, -1]], + } def test_dico_utilities3(three_bg): assert three_bg.dico_utilities() == { - 0: [[87, 56, 33, 21, 88, 77, 79, 69], [39, 52, 4, 92, 1, 78, 60, 69], - [2, 28, 92, 11, 16, 63, 21, 22]], - 1: [[97, 12, 13, 92, 38, 2, 91, 62], [32, 40, 10, 57, 19, 18, 19, 15], - [35, 12, 0, 56, 93, 22, 52, 35]], - 2: [[67, 0, 13, 87, 83, 6, 1, 80], [27, 63, 31, 22, 18, 8, 46, 81], - [88, 28, 35, 5, 52, 67, 21, 12]], - 3: [[76, 13, 70, 36, 8, 39, 22, 42], [43, 82, 81, 37, 70, 58, 28, 91], - [13, 25, 6, 96, 31, 27, 5, 37]], - 4: [[42, 62, 83, 91, 62, 11, 19, 0], [33, 88, 78, 14, 90, 27, 40, 86], - [29, 91, 63, 65, 78, 36, 3, 35]], - 5: [[78, 51, 25, 64, 84, 53, 19, 30], [94, 8, 47, 52, 17, 89, 21, 54], - [39, 13, 7, 46, 4, 14, 46, 3]], - 6: [[21, 33, 41, 4, 40, 5, 47, 13], [72, 6, 92, 29, 73, 54, 22, 30], - [23, 86, 14, 46, 99, 34, 62, 97]], - 7: [[69, 11, 25, 65, 82, 52, 68, 56], [33, 12, 39, 98, 41, 63, 99, 10], - [18, 62, 99, 58, 62, 25, 55, 7]]} + 0: [ + [87, 56, 33, 21, 88, 77, 79, 69], + [39, 52, 4, 92, 1, 78, 60, 69], + [2, 28, 92, 11, 16, 63, 21, 22], + ], + 1: [ + [97, 12, 13, 92, 38, 2, 91, 62], + [32, 40, 10, 57, 19, 18, 19, 15], + [35, 12, 0, 56, 93, 22, 52, 35], + ], + 2: [ + [67, 0, 13, 87, 83, 6, 1, 80], + [27, 63, 31, 22, 18, 8, 46, 81], + [88, 28, 35, 5, 52, 67, 21, 12], + ], + 3: [ + [76, 13, 70, 36, 8, 39, 22, 42], + [43, 82, 81, 37, 70, 58, 28, 91], + [13, 25, 6, 96, 31, 27, 5, 37], + ], + 4: [ + [42, 62, 83, 91, 62, 11, 19, 0], + [33, 88, 78, 14, 90, 27, 40, 86], + [29, 91, 63, 65, 78, 36, 3, 35], + ], + 5: [ + [78, 51, 25, 64, 84, 53, 19, 30], + [94, 8, 47, 52, 17, 89, 21, 54], + [39, 13, 7, 46, 4, 14, 46, 3], + ], + 6: [ + [21, 33, 41, 4, 40, 5, 47, 13], + [72, 6, 92, 29, 73, 54, 22, 30], + [23, 86, 14, 46, 99, 34, 62, 97], + ], + 7: [ + [69, 11, 25, 65, 82, 52, 68, 56], + [33, 12, 39, 98, 41, 63, 99, 10], + [18, 62, 99, 58, 62, 25, 55, 7], + ], + } def test_expected_utilities1(bimat_bg): assert bimat_bg.expected_utilities( - {(0, 0): [1, 0, 0], (0, 1): [1, 0, 0], (1, 0): [1, 0], (1, 1): [1, 0], - (1, 2): [1, 0]}) == \ - {(0, 0): Fraction(-11, 5), - (0, 1): Fraction(-12, 5), - (1, 0): Fraction(-7, 3), - (1, 1): Fraction(-2, 1), - (1, 2): Fraction(-5, 2)} + { + (0, 0): [1, 0, 0], + (0, 1): [1, 0, 0], + (1, 0): [1, 0], + (1, 1): [1, 0], + (1, 2): [1, 0], + } + ) == { + (0, 0): Fraction(-11, 5), + (0, 1): Fraction(-12, 5), + (1, 0): Fraction(-7, 3), + (1, 1): Fraction(-2, 1), + (1, 2): Fraction(-5, 2), + } def test_expected_utilities2(bimat_bg): assert bimat_bg.expected_utilities( - {(0, 0): [1, 0, 0], (0, 1): [1, 0, 0], (1, 0): [0, 1], (1, 1): [0, 1], - (1, 2): [0, 1]}) == \ - {(0, 0): Fraction(-29, 5), - (0, 1): Fraction(-26, 5), - (1, 0): Fraction(-5, 1), - (1, 1): Fraction(-16, 3), - (1, 2): Fraction(-6, 1)} + { + (0, 0): [1, 0, 0], + (0, 1): [1, 0, 0], + (1, 0): [0, 1], + (1, 1): [0, 1], + (1, 2): [0, 1], + } + ) == { + (0, 0): Fraction(-29, 5), + (0, 1): Fraction(-26, 5), + (1, 0): Fraction(-5, 1), + (1, 1): Fraction(-16, 3), + (1, 2): Fraction(-6, 1), + } def test_expected_utilities3(sherif_bg1): assert sherif_bg1.expected_utilities( - {(0, 0): [1, 0], (1, 0): [1, 0], (1, 1): [0, 1]}) == { - (0, 0): Fraction(-1, 1), (1, 0): Fraction(-3, 1), - (1, 1): Fraction(-2, 1)} + {(0, 0): [1, 0], (1, 0): [1, 0], (1, 1): [0, 1]} + ) == {(0, 0): Fraction(-1, 1), (1, 0): Fraction(-3, 1), (1, 1): Fraction(-2, 1)} def test_expected_utilities4(sherif_bg1): assert sherif_bg1.expected_utilities( - {(0, 0): [0, 1], (1, 0): [0, 1], (1, 1): [1, 0]}) == { - (0, 0): Fraction(-4, 3), (1, 0): Fraction(0, 1), - (1, 1): Fraction(2, 1)} + {(0, 0): [0, 1], (1, 0): [0, 1], (1, 1): [1, 0]} + ) == {(0, 0): Fraction(-4, 3), (1, 0): Fraction(0, 1), (1, 1): Fraction(2, 1)} def test_expected_utilities5(three_bg): assert three_bg.expected_utilities( - {(0, 0): [1, 0], (0, 1): [1, 0], (1, 0): [1, 0], (1, 1): [1, 0], - (2, 0): [1, 0], (2, 1): [1, 0]}) == {(0, 0): Fraction(163, 2), - (0, 1): Fraction(58, 1), - (1, 0): Fraction(51, 1), - (1, 1): Fraction(541, 13), - (2, 0): Fraction(97, 3), - (2, 1): Fraction(22, 1) - } + { + (0, 0): [1, 0], + (0, 1): [1, 0], + (1, 0): [1, 0], + (1, 1): [1, 0], + (2, 0): [1, 0], + (2, 1): [1, 0], + } + ) == { + (0, 0): Fraction(163, 2), + (0, 1): Fraction(58, 1), + (1, 0): Fraction(51, 1), + (1, 1): Fraction(541, 13), + (2, 0): Fraction(97, 3), + (2, 1): Fraction(22, 1), + } """ @@ -400,101 +540,174 @@ convert_to_HGG() def test_is_equilibrium1(bimat_bg): assert bimat_bg.is_equilibrium( - {(0, 0): [1, 0, 0], (0, 1): [1, 0, 0], (1, 0): [1, 0], (1, 1): [1, 0], - (1, 2): [1, 0]}, 0.0001) + { + (0, 0): [1, 0, 0], + (0, 1): [1, 0, 0], + (1, 0): [1, 0], + (1, 1): [1, 0], + (1, 2): [1, 0], + }, + 0.0001, + ) def test_is_equilibrium2(bimat_bg): assert not bimat_bg.is_equilibrium( - {(0, 0): [1, 0, 0], (0, 1): [1, 0, 0], (1, 0): [1, 0], (1, 1): [1, 0], - (1, 2): [0, 1]}, 0.0001) + { + (0, 0): [1, 0, 0], + (0, 1): [1, 0, 0], + (1, 0): [1, 0], + (1, 1): [1, 0], + (1, 2): [0, 1], + }, + 0.0001, + ) def test_is_equilibrium3(bimat_bg): assert not bimat_bg.is_equilibrium( - {(0, 0): [0, 1, 0], (0, 1): [1, 0, 0], (1, 0): [1, 0], (1, 1): [1, 0], - (1, 2): [1, 0]}, 0.0001) + { + (0, 0): [0, 1, 0], + (0, 1): [1, 0, 0], + (1, 0): [1, 0], + (1, 1): [1, 0], + (1, 2): [1, 0], + }, + 0.0001, + ) def test_is_equilibrium4(bimat_bg): assert not bimat_bg.is_equilibrium( - {(0, 0): [1, 0, 0], (0, 1): [1, 0, 0], (1, 0): [0, 1], (1, 1): [0, 1], - (1, 2): [0, 1]}, 0.0001) + { + (0, 0): [1, 0, 0], + (0, 1): [1, 0, 0], + (1, 0): [0, 1], + (1, 1): [0, 1], + (1, 2): [0, 1], + }, + 0.0001, + ) def test_is_equilibrium5(sherif_bg1): assert sherif_bg1.is_equilibrium( - {(0, 0): [1, 0], (1, 0): [0, 1], (1, 1): [1, 0]}, 0.0001) + {(0, 0): [1, 0], (1, 0): [0, 1], (1, 1): [1, 0]}, 0.0001 + ) def test_is_equilibrium6(sherif_bg1): assert not sherif_bg1.is_equilibrium( - {(0, 0): [0, 1], (1, 0): [0, 1], (1, 1): [1, 0]}, 0.0001) + {(0, 0): [0, 1], (1, 0): [0, 1], (1, 1): [1, 0]}, 0.0001 + ) def test_is_equilibrium7(sherif_bg2): assert sherif_bg2.is_equilibrium( - {(0, 0): [Fraction(1, 2), Fraction(1, 2)], (1, 0): [0, 1], - (1, 1): [1, 0]}, 0.0001) + {(0, 0): [Fraction(1, 2), Fraction(1, 2)], (1, 0): [0, 1], (1, 1): [1, 0]}, + 0.0001, + ) def test_is_equilibrium8(sherif_bg2): assert sherif_bg2.is_equilibrium( - {(0, 0): [Fraction(1, 3), Fraction(2, 3)], (1, 0): [0, 1], - (1, 1): [1, 0]}, 0.0001) + {(0, 0): [Fraction(1, 3), Fraction(2, 3)], (1, 0): [0, 1], (1, 1): [1, 0]}, + 0.0001, + ) def test_is_equilibrium9(sherif_bg2): assert sherif_bg2.is_equilibrium( - {(0, 0): [0, 1], (1, 0): [0, 1], (1, 1): [1, 0]}, 0.0001) + {(0, 0): [0, 1], (1, 0): [0, 1], (1, 1): [1, 0]}, 0.0001 + ) def test_is_equilibrium10(sherif_bg3): assert sherif_bg3.is_equilibrium( - {(0, 0): [0, 1], (1, 0): [0, 1], (1, 1): [1, 0]}, 0.0001) + {(0, 0): [0, 1], (1, 0): [0, 1], (1, 1): [1, 0]}, 0.0001 + ) def test_is_equilibrium11(sherif_bg3): assert not sherif_bg3.is_equilibrium( - {(0, 0): [1, 0], (1, 0): [0, 1], (1, 1): [1, 0]}, 0.0001) + {(0, 0): [1, 0], (1, 0): [0, 1], (1, 1): [1, 0]}, 0.0001 + ) def test_read_GameFile1(): read_bg = BG.read_GameFile("filestest/internet.bg") assert read_bg.players_actions == [[0, 1], [0, 1]] assert read_bg.theta == [[0, 1], [0, 1]] - assert read_bg.p == [Fraction(4, 10), Fraction(1, 10), Fraction(1, 10), - Fraction(4, 10)] - assert read_bg.utilities == [[[3, 0, 0, 2], [3, 0, 0, 2]], - [[1, 0, 0, 2], [3, 0, 0, 2]], - [[3, 0, 0, 2], [1, 0, 0, 2]], - [[1, 0, 0, 2], [1, 0, 0, 2]]] + assert read_bg.p == [ + Fraction(4, 10), + Fraction(1, 10), + Fraction(1, 10), + Fraction(4, 10), + ] + assert read_bg.utilities == [ + [[3, 0, 0, 2], [3, 0, 0, 2]], + [[1, 0, 0, 2], [3, 0, 0, 2]], + [[3, 0, 0, 2], [1, 0, 0, 2]], + [[1, 0, 0, 2], [1, 0, 0, 2]], + ] def test_read_GameFile2(): read_bg = BG.read_GameFile("filestest/test.bg") assert read_bg.players_actions == [[0, 1], [0, 1], [0, 1]] assert read_bg.theta == [[0, 1], [0, 1], [0, 1]] - assert read_bg.p == [Fraction(1, 15), Fraction(2, 15), Fraction(1, 30), - Fraction(1, 6), Fraction(1, 15), Fraction(1, 5), - Fraction(1, 10), Fraction(7, 30)] + assert read_bg.p == [ + Fraction(1, 15), + Fraction(2, 15), + Fraction(1, 30), + Fraction(1, 6), + Fraction(1, 15), + Fraction(1, 5), + Fraction(1, 10), + Fraction(7, 30), + ] assert read_bg.utilities == [ - [[-3, -10, -1, 4, -7, -9, -5, 5], [-3, -10, -1, 4, -7, -9, -5, 5], - [-3, -5, -10, 8, -7, -9, -1, 5]], - [[-2, -9, -1, 5, -6, -8, -4, 5], [-2, -9, -1, 5, -6, -8, -4, 5], - [-2, -4, -9, 2, -6, -8, -1, 5]], - [[-2, -8, -1, 8, -5, -7, -4, 4], [-2, -8, -1, 8, -5, -7, -4, 5], - [-2, -3, -8, 5, -5, -7, -1, 4]], - [[-2, -7, -1, 7, -4, -6, -4, 1], [-2, -7, -1, 8, -4, -6, -4, 2], - [-2, -3, -7, 5, -4, -6, -1, 5]], - [[-3, -10, -1, 4, -7, -9, -5, 5], [-3, -10, -1, 4, -7, -9, -5, 5], - [-3, -5, -10, 8, -7, -9, -1, 5]], - [[-2, -9, -1, 5, -6, -8, -4, 5], [-2, -9, -1, 5, -6, -8, -4, 5], - [-2, -4, -9, 2, -6, -8, -1, 5]], - [[-2, -8, -1, 8, -5, -7, -4, 4], [-2, -8, -1, 8, -5, -7, -4, 5], - [-2, -3, -8, 5, -5, -7, -1, 4]], - [[-2, -7, -1, 7, -4, -6, -4, 1], [-2, -7, -1, 8, -4, -6, -4, 2], - [-2, -3, -7, 5, -4, -6, -1, 5]]] + [ + [-3, -10, -1, 4, -7, -9, -5, 5], + [-3, -10, -1, 4, -7, -9, -5, 5], + [-3, -5, -10, 8, -7, -9, -1, 5], + ], + [ + [-2, -9, -1, 5, -6, -8, -4, 5], + [-2, -9, -1, 5, -6, -8, -4, 5], + [-2, -4, -9, 2, -6, -8, -1, 5], + ], + [ + [-2, -8, -1, 8, -5, -7, -4, 4], + [-2, -8, -1, 8, -5, -7, -4, 5], + [-2, -3, -8, 5, -5, -7, -1, 4], + ], + [ + [-2, -7, -1, 7, -4, -6, -4, 1], + [-2, -7, -1, 8, -4, -6, -4, 2], + [-2, -3, -7, 5, -4, -6, -1, 5], + ], + [ + [-3, -10, -1, 4, -7, -9, -5, 5], + [-3, -10, -1, 4, -7, -9, -5, 5], + [-3, -5, -10, 8, -7, -9, -1, 5], + ], + [ + [-2, -9, -1, 5, -6, -8, -4, 5], + [-2, -9, -1, 5, -6, -8, -4, 5], + [-2, -4, -9, 2, -6, -8, -1, 5], + ], + [ + [-2, -8, -1, 8, -5, -7, -4, 4], + [-2, -8, -1, 8, -5, -7, -4, 5], + [-2, -3, -8, 5, -5, -7, -1, 4], + ], + [ + [-2, -7, -1, 7, -4, -6, -4, 1], + [-2, -7, -1, 8, -4, -6, -4, 2], + [-2, -3, -7, 5, -4, -6, -1, 5], + ], + ] def test_write_GameFile1(bimat_bg): diff --git a/test/test_hypergraphicalgame.py b/test/test_hypergraphicalgame.py index a017b04..cadce72 100644 --- a/test/test_hypergraphicalgame.py +++ b/test/test_hypergraphicalgame.py @@ -14,9 +14,14 @@ Separate assert in multiple fucntion def first_hgg(): players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] utilities = [ - [[-3, -7, -7, -10, -1, -5, -5, -9], [-3, -7, -1, -5, -7, -10, -5, -9], - [-3, -1, -7, -5, -7, -5, -10, -9]], - [[-1, -5, 0, -3], [-1, 0, -5, -3]], [[-1, -5, 0, -3], [-1, 0, -5, -3]]] + [ + [-3, -7, -7, -10, -1, -5, -5, -9], + [-3, -7, -1, -5, -7, -10, -5, -9], + [-3, -1, -7, -5, -7, -5, -10, -9], + ], + [[-1, -5, 0, -3], [-1, 0, -5, -3]], + [[-1, -5, 0, -3], [-1, 0, -5, -3]], + ] hypergraph = [[0, 1, 2], [1, 3], [2, 3]] return HGG(players_actions, utilities, hypergraph) @@ -25,10 +30,14 @@ def first_hgg(): @pytest.fixture def second_hgg(): utilities = [ - [[-3, -1, -3, -2, -2, -3, -2, -1], [-1, -3, -5, -1, -1, -6, -3, -4], - [-2, -3, -6, -4, -3, -1, -3, -4]], + [ + [-3, -1, -3, -2, -2, -3, -2, -1], + [-1, -3, -5, -1, -1, -6, -3, -4], + [-2, -3, -6, -4, -3, -1, -3, -4], + ], [[-1, -3, -2, -2], [-1, -2, -2, -1]], - [[-3, -1, -4, -5], [-1, -3, -1, -5]]] + [[-3, -1, -4, -5], [-1, -3, -1, -5]], + ] # Error up level impossible, 2->3, [[0,1],[0,1],[0,1],[0,1]] hypergraph = [[0, 1, 2], [1, 3], [2, 3]] players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] @@ -38,10 +47,17 @@ def second_hgg(): @pytest.fixture def third_hgg(): utilities = [ - [[74, 6, 9, 60, 77, 30, 47, 0], [51, 97, 98, 83, 90, 1, 2, 47], - [18, 16, 29, 86, 100, 96, 93, 64]], - [[84, 48, 27, 5, 100, 62, 16, 62], [10, 88, 72, 47, 13, 24, 42, 72], - [1, 36, 68, 0, 53, 5, 61, 97]]] + [ + [74, 6, 9, 60, 77, 30, 47, 0], + [51, 97, 98, 83, 90, 1, 2, 47], + [18, 16, 29, 86, 100, 96, 93, 64], + ], + [ + [84, 48, 27, 5, 100, 62, 16, 62], + [10, 88, 72, 47, 13, 24, 42, 72], + [1, 36, 68, 0, 53, 5, 61, 97], + ], + ] hypergraph = [[0, 1, 3], [0, 2, 3]] players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] return HGG(players_actions, utilities, hypergraph) @@ -51,41 +67,311 @@ def third_hgg(): def degen_hgg(): players_actions = [[0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]] hypergraph = [[1, 2, 3], [0, 1, 3], [0, 1, 2]] - utilities = [[[-6, -3, -3, -1, -4, -10, -7, -5, -5, -10, -2, -1, -1, -3, - -7, -6, -1, -2, -6, -3, -3, -4, -8, -3, -7, -8, -8], - [-9, -1, -8, -2, -7, -6, -7, -6, -9, -2, -4, -2, -5, -2, -3, - -7, -3, -7, -7, -5, -3, -5, -10, -5, -8, -9, -9], - [-3, -1, -2, -4, -1, -4, -8, -7, -3, -6, -9, -1, -1, -3, -7, - -3, -7, -2, -1, -4, -10, -4, -9, -4, -3, -6, -3]], - [[-7, -3, -5, -9, -9, -5, -6, -5, -2, -8, -7, -10, -2, -10, - -6, -10, -5, -8, -6, -1, -7, -6, -3, -5, -3, -6, -6], - [-3, -6, -3, -2, -9, -3, -1, -3, -6, -10, -5, -4, -9, -2, - -10, -7, -10, -10, -6, -8, -6, -4, -4, -1, -3, -5, -8], - [-9, -9, -5, -9, -6, -3, -6, -2, -7, -2, -5, -10, -3, -5, -3, - -4, -9, -8, -3, -1, -6, -2, -2, -7, -10, -10, -3]], - [[-1, -8, -5, -4, -2, -5, -1, -10, -5, -2, -1, -3, -7, -3, -5, - -1, -7, -9, -9, -4, -5, -5, -10, -3, -6, -2, -6], - [-5, -7, -1, -9, -3, -7, -6, -10, -8, -9, -4, -1, -8, -5, -1, - -10, -6, -4, -4, -7, -6, -10, -5, -8, -7, -3, -2], - [-6, -8, -6, -3, -1, -6, -7, -2, -9, -7, -9, -10, -4, -3, -6, - -5, -5, -10, -4, -4, -5, -4, -10, -3, -4, -5, -3]]] + utilities = [ + [ + [ + -6, + -3, + -3, + -1, + -4, + -10, + -7, + -5, + -5, + -10, + -2, + -1, + -1, + -3, + -7, + -6, + -1, + -2, + -6, + -3, + -3, + -4, + -8, + -3, + -7, + -8, + -8, + ], + [ + -9, + -1, + -8, + -2, + -7, + -6, + -7, + -6, + -9, + -2, + -4, + -2, + -5, + -2, + -3, + -7, + -3, + -7, + -7, + -5, + -3, + -5, + -10, + -5, + -8, + -9, + -9, + ], + [ + -3, + -1, + -2, + -4, + -1, + -4, + -8, + -7, + -3, + -6, + -9, + -1, + -1, + -3, + -7, + -3, + -7, + -2, + -1, + -4, + -10, + -4, + -9, + -4, + -3, + -6, + -3, + ], + ], + [ + [ + -7, + -3, + -5, + -9, + -9, + -5, + -6, + -5, + -2, + -8, + -7, + -10, + -2, + -10, + -6, + -10, + -5, + -8, + -6, + -1, + -7, + -6, + -3, + -5, + -3, + -6, + -6, + ], + [ + -3, + -6, + -3, + -2, + -9, + -3, + -1, + -3, + -6, + -10, + -5, + -4, + -9, + -2, + -10, + -7, + -10, + -10, + -6, + -8, + -6, + -4, + -4, + -1, + -3, + -5, + -8, + ], + [ + -9, + -9, + -5, + -9, + -6, + -3, + -6, + -2, + -7, + -2, + -5, + -10, + -3, + -5, + -3, + -4, + -9, + -8, + -3, + -1, + -6, + -2, + -2, + -7, + -10, + -10, + -3, + ], + ], + [ + [ + -1, + -8, + -5, + -4, + -2, + -5, + -1, + -10, + -5, + -2, + -1, + -3, + -7, + -3, + -5, + -1, + -7, + -9, + -9, + -4, + -5, + -5, + -10, + -3, + -6, + -2, + -6, + ], + [ + -5, + -7, + -1, + -9, + -3, + -7, + -6, + -10, + -8, + -9, + -4, + -1, + -8, + -5, + -1, + -10, + -6, + -4, + -4, + -7, + -6, + -10, + -5, + -8, + -7, + -3, + -2, + ], + [ + -6, + -8, + -6, + -3, + -1, + -6, + -7, + -2, + -9, + -7, + -9, + -10, + -4, + -3, + -6, + -5, + -5, + -10, + -4, + -4, + -5, + -4, + -10, + -3, + -4, + -5, + -3, + ], + ], + ] return HGG(players_actions, utilities, hypergraph) @pytest.fixture def first_hgg_fraction(): players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] - utilities = [[[Fraction(-3, 2), Fraction(-7, 2), Fraction(-7, 2), - Fraction(-10, 2), Fraction(-1, 2), Fraction(-5, 2), - Fraction(-5, 2), Fraction(-9, 2)], - [Fraction(-3, 4), Fraction(-7, 4), Fraction(-1, 4), - Fraction(-5, 4), Fraction(-7, 4), Fraction(-10, 4), - Fraction(-5, 4), Fraction(-9, 4)], - [-3, -1, -7, -5, -7, -5, -10, -9]], - [[Fraction(-1, 4), Fraction(-5, 4), 0, Fraction(-3, 4)], - [Fraction(-1, 3), 0, Fraction(-5, 3), Fraction(-3, 3)]], - [[-1, -5, 0, -3], - [Fraction(-1, 3), 0, Fraction(-5, 3), Fraction(-3, 3)]]] + utilities = [ + [ + [ + Fraction(-3, 2), + Fraction(-7, 2), + Fraction(-7, 2), + Fraction(-10, 2), + Fraction(-1, 2), + Fraction(-5, 2), + Fraction(-5, 2), + Fraction(-9, 2), + ], + [ + Fraction(-3, 4), + Fraction(-7, 4), + Fraction(-1, 4), + Fraction(-5, 4), + Fraction(-7, 4), + Fraction(-10, 4), + Fraction(-5, 4), + Fraction(-9, 4), + ], + [-3, -1, -7, -5, -7, -5, -10, -9], + ], + [ + [Fraction(-1, 4), Fraction(-5, 4), 0, Fraction(-3, 4)], + [Fraction(-1, 3), 0, Fraction(-5, 3), Fraction(-3, 3)], + ], + [[-1, -5, 0, -3], [Fraction(-1, 3), 0, Fraction(-5, 3), Fraction(-3, 3)]], + ] hypergraph = [[0, 1, 2], [1, 3], [2, 3]] return HGG(players_actions, utilities, hypergraph) @@ -93,43 +379,88 @@ def first_hgg_fraction(): # joint_actions + def test_joint_actions1(first_hgg): - assert (first_hgg.local_normalformgames[0].joint_actions == np.mat( - [[0., 0., 0.], [0., 0., 1.], [0., 1., 0.], [0., 1., 1.], [1., 0., 0.], - [1., 0., 1.], [1., 1., 0.], [1., 1., 1.]])).all() + assert ( + first_hgg.local_normalformgames[0].joint_actions + == np.mat( + [ + [0.0, 0.0, 0.0], + [0.0, 0.0, 1.0], + [0.0, 1.0, 0.0], + [0.0, 1.0, 1.0], + [1.0, 0.0, 0.0], + [1.0, 0.0, 1.0], + [1.0, 1.0, 0.0], + [1.0, 1.0, 1.0], + ] + ) + ).all() def test_joint_actions2(first_hgg): - assert (first_hgg.local_normalformgames[1].joint_actions == np.mat( - [[0., 0.], [0., 1.], [1., 0.], [1., 1.]])).all() + assert ( + first_hgg.local_normalformgames[1].joint_actions + == np.mat([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]]) + ).all() def test_joint_actions3(first_hgg): - assert (first_hgg.local_normalformgames[2].joint_actions == np.mat( - [[0., 0.], [0., 1.], [1., 0.], [1., 1.]])).all() + assert ( + first_hgg.local_normalformgames[2].joint_actions + == np.mat([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]]) + ).all() def test_joint_actions4(degen_hgg): - assert (degen_hgg.local_normalformgames[0].joint_actions == np.mat( - [[0., 0., 0.], [0., 0., 1.], [0., 0., 2.], [0., 1., 0.], [0., 1., 1.], - [0., 1., 2.], - [0., 2., 0.], [0., 2., 1.], [0., 2., 2.], [1., 0., 0.], [1., 0., 1.], - [1., 0., 2.], - [1., 1., 0.], [1., 1., 1.], [1., 1., 2.], [1., 2., 0.], [1., 2., 1.], - [1., 2., 2.], - [2., 0., 0.], [2., 0., 1.], [2., 0., 2.], [2., 1., 0.], [2., 1., 1.], - [2., 1., 2.], - [2., 2., 0.], [2., 2., 1.], [2., 2., 2.]])).all() + assert ( + degen_hgg.local_normalformgames[0].joint_actions + == np.mat( + [ + [0.0, 0.0, 0.0], + [0.0, 0.0, 1.0], + [0.0, 0.0, 2.0], + [0.0, 1.0, 0.0], + [0.0, 1.0, 1.0], + [0.0, 1.0, 2.0], + [0.0, 2.0, 0.0], + [0.0, 2.0, 1.0], + [0.0, 2.0, 2.0], + [1.0, 0.0, 0.0], + [1.0, 0.0, 1.0], + [1.0, 0.0, 2.0], + [1.0, 1.0, 0.0], + [1.0, 1.0, 1.0], + [1.0, 1.0, 2.0], + [1.0, 2.0, 0.0], + [1.0, 2.0, 1.0], + [1.0, 2.0, 2.0], + [2.0, 0.0, 0.0], + [2.0, 0.0, 1.0], + [2.0, 0.0, 2.0], + [2.0, 1.0, 0.0], + [2.0, 1.0, 1.0], + [2.0, 1.0, 2.0], + [2.0, 2.0, 0.0], + [2.0, 2.0, 1.0], + [2.0, 2.0, 2.0], + ] + ) + ).all() def test_joint_actions5(degen_hgg): - assert (degen_hgg.local_normalformgames[0].joint_actions == - degen_hgg.local_normalformgames[1].joint_actions).all() + assert ( + degen_hgg.local_normalformgames[0].joint_actions + == degen_hgg.local_normalformgames[1].joint_actions + ).all() def test_joint_actions6(degen_hgg): - assert (degen_hgg.local_normalformgames[0].joint_actions == - degen_hgg.local_normalformgames[2].joint_actions).all() + assert ( + degen_hgg.local_normalformgames[0].joint_actions + == degen_hgg.local_normalformgames[2].joint_actions + ).all() # Add test on creation of local games? @@ -139,8 +470,10 @@ def test_joint_actions6(degen_hgg): # from method, useless?, confusing and redondant def test_utilities1(first_hgg): assert first_hgg.local_normalformgames[0].utilities == [ - [-3, -7, -7, -10, -1, -5, -5, -9], [-3, -7, -1, -5, -7, -10, -5, -9], - [-3, -1, -7, -5, -7, -5, -10, -9]] + [-3, -7, -7, -10, -1, -5, -5, -9], + [-3, -7, -1, -5, -7, -10, -5, -9], + [-3, -1, -7, -5, -7, -5, -10, -9], + ] # assert first_hgg.local_normalformgames[0].utilities.all() == # np.array([[-3, -7, -7, -10, -1, -5, -5, -9], # [-3, -7, -1, -5, -7, -10, -5, -9], @@ -148,181 +481,446 @@ def test_utilities1(first_hgg): def test_utilities2(first_hgg): - assert first_hgg.local_normalformgames[1].utilities == [[-1, -5, 0, -3], - [-1, 0, -5, -3]] + assert first_hgg.local_normalformgames[1].utilities == [ + [-1, -5, 0, -3], + [-1, 0, -5, -3], + ] def test_utilities3(first_hgg): - assert first_hgg.local_normalformgames[2].utilities == [[-1, -5, 0, -3], - [-1, 0, -5, -3]] + assert first_hgg.local_normalformgames[2].utilities == [ + [-1, -5, 0, -3], + [-1, 0, -5, -3], + ] def test_utilities4(degen_hgg): - assert degen_hgg.local_normalformgames[0].utilities == \ - [[-6, -3, -3, -1, -4, -10, -7, -5, -5, -10, -2, -1, -1, -3, -7, -6, - -1, -2, -6, -3, -3, -4, -8, -3, -7, -8, -8], - [-9, -1, -8, -2, -7, -6, -7, -6, -9, -2, -4, -2, -5, -2, -3, -7, - -3, -7, -7, -5, -3, -5, -10, -5, -8, -9, -9], - [-3, -1, -2, -4, -1, -4, -8, -7, -3, -6, -9, -1, -1, -3, -7, -3, - -7, -2, -1, -4, -10, -4, -9, -4, -3, -6, -3]] + assert degen_hgg.local_normalformgames[0].utilities == [ + [ + -6, + -3, + -3, + -1, + -4, + -10, + -7, + -5, + -5, + -10, + -2, + -1, + -1, + -3, + -7, + -6, + -1, + -2, + -6, + -3, + -3, + -4, + -8, + -3, + -7, + -8, + -8, + ], + [ + -9, + -1, + -8, + -2, + -7, + -6, + -7, + -6, + -9, + -2, + -4, + -2, + -5, + -2, + -3, + -7, + -3, + -7, + -7, + -5, + -3, + -5, + -10, + -5, + -8, + -9, + -9, + ], + [ + -3, + -1, + -2, + -4, + -1, + -4, + -8, + -7, + -3, + -6, + -9, + -1, + -1, + -3, + -7, + -3, + -7, + -2, + -1, + -4, + -10, + -4, + -9, + -4, + -3, + -6, + -3, + ], + ] def test_utilities5(degen_hgg): - assert degen_hgg.local_normalformgames[1].utilities == \ - [[-7, -3, -5, -9, -9, -5, -6, -5, -2, -8, -7, -10, -2, -10, -6, -10, - -5, -8, -6, -1, -7, -6, -3, -5, -3, -6, -6], - [-3, -6, -3, -2, -9, -3, -1, -3, -6, -10, -5, -4, -9, -2, -10, -7, - -10, -10, -6, -8, -6, -4, -4, -1, -3, -5, -8], - [-9, -9, -5, -9, -6, -3, -6, -2, -7, -2, -5, -10, -3, -5, -3, -4, - -9, -8, -3, -1, -6, -2, -2, -7, -10, -10, -3]] + assert degen_hgg.local_normalformgames[1].utilities == [ + [ + -7, + -3, + -5, + -9, + -9, + -5, + -6, + -5, + -2, + -8, + -7, + -10, + -2, + -10, + -6, + -10, + -5, + -8, + -6, + -1, + -7, + -6, + -3, + -5, + -3, + -6, + -6, + ], + [ + -3, + -6, + -3, + -2, + -9, + -3, + -1, + -3, + -6, + -10, + -5, + -4, + -9, + -2, + -10, + -7, + -10, + -10, + -6, + -8, + -6, + -4, + -4, + -1, + -3, + -5, + -8, + ], + [ + -9, + -9, + -5, + -9, + -6, + -3, + -6, + -2, + -7, + -2, + -5, + -10, + -3, + -5, + -3, + -4, + -9, + -8, + -3, + -1, + -6, + -2, + -2, + -7, + -10, + -10, + -3, + ], + ] def test_utilities6(degen_hgg): - assert degen_hgg.local_normalformgames[2].utilities == \ - [[-1, -8, -5, -4, -2, -5, -1, -10, -5, -2, -1, -3, -7, -3, -5, -1, - -7, -9, -9, -4, -5, -5, -10, -3, -6, -2, -6], - [-5, -7, -1, -9, -3, -7, -6, -10, -8, -9, -4, -1, -8, -5, -1, -10, - -6, -4, -4, -7, -6, -10, -5, -8, -7, -3, -2], - [-6, -8, -6, -3, -1, -6, -7, -2, -9, -7, -9, -10, -4, -3, -6, -5, - -5, -10, -4, -4, -5, -4, -10, -3, -4, -5, -3]] + assert degen_hgg.local_normalformgames[2].utilities == [ + [ + -1, + -8, + -5, + -4, + -2, + -5, + -1, + -10, + -5, + -2, + -1, + -3, + -7, + -3, + -5, + -1, + -7, + -9, + -9, + -4, + -5, + -5, + -10, + -3, + -6, + -2, + -6, + ], + [ + -5, + -7, + -1, + -9, + -3, + -7, + -6, + -10, + -8, + -9, + -4, + -1, + -8, + -5, + -1, + -10, + -6, + -4, + -4, + -7, + -6, + -10, + -5, + -8, + -7, + -3, + -2, + ], + [ + -6, + -8, + -6, + -3, + -1, + -6, + -7, + -2, + -9, + -7, + -9, + -10, + -4, + -3, + -6, + -5, + -5, + -10, + -4, + -4, + -5, + -4, + -10, + -3, + -4, + -5, + -3, + ], + ] # joint_action_except_i # no degen hgg + def test_joint_action_except_i1(first_hgg): - assert (first_hgg.joint_action_except_i(0)[0] == np.mat( - [[0., 0.], [0., 1.], [1., 0.], [1., 1.]])).all() + assert ( + first_hgg.joint_action_except_i(0)[0] + == np.mat([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]]) + ).all() def test_joint_action_except_i2(first_hgg): - assert (first_hgg.joint_action_except_i(1)[0] == np.mat( - [[0., 0.], [0., 1.], [1., 0.], [1., 1.]])).all() + assert ( + first_hgg.joint_action_except_i(1)[0] + == np.mat([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]]) + ).all() def test_joint_action_except_i3(first_hgg): - assert (first_hgg.joint_action_except_i(2)[0] == np.mat( - [[0., 0.], [0., 1.], [1., 0.], [1., 1.]])).all() + assert ( + first_hgg.joint_action_except_i(2)[0] + == np.mat([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]]) + ).all() def test_joint_action_except_i4(first_hgg): - assert (first_hgg.joint_action_except_i(0)[1] == []) + assert first_hgg.joint_action_except_i(0)[1] == [] def test_joint_action_except_i5(first_hgg): - assert (first_hgg.joint_action_except_i(0)[2] == []) + assert first_hgg.joint_action_except_i(0)[2] == [] def test_joint_action_except_i6(first_hgg): - assert (first_hgg.joint_action_except_i(1)[1] == np.mat( - [[0.], [1.]])).all() + assert (first_hgg.joint_action_except_i(1)[1] == np.mat([[0.0], [1.0]])).all() def test_joint_action_except_i7(first_hgg): - assert (first_hgg.joint_action_except_i(1)[2] == []) + assert first_hgg.joint_action_except_i(1)[2] == [] def test_joint_action_except_i8(first_hgg): - assert (first_hgg.joint_action_except_i(2)[1] == []) + assert first_hgg.joint_action_except_i(2)[1] == [] def test_joint_action_except_i9(first_hgg): - assert (first_hgg.joint_action_except_i(1)[2] == np.mat( - [[0.], [1.]])).all() + assert (first_hgg.joint_action_except_i(1)[2] == np.mat([[0.0], [1.0]])).all() def test_joint_action_except_i10(first_hgg): - assert (first_hgg.joint_action_except_i(3)[0] == []) + assert first_hgg.joint_action_except_i(3)[0] == [] def test_joint_action_except_i11(first_hgg): - assert (first_hgg.joint_action_except_i(3)[1] == np.mat( - [[0.], [1.]])).all() + assert (first_hgg.joint_action_except_i(3)[1] == np.mat([[0.0], [1.0]])).all() def test_joint_action_except_i12(first_hgg): - assert (first_hgg.joint_action_except_i(3)[2] == np.mat( - [[0.], [1.]])).all() + assert (first_hgg.joint_action_except_i(3)[2] == np.mat([[0.0], [1.0]])).all() # expected_utilities # no degen hff + def test_expected_utilities1(first_hgg): - assert (first_hgg.expected_utilities( - {0: [1, 0], 1: [1, 0], 2: [1, 0], 3: [1, 0]}) == np.mat( - [-3., -4., -4., -2.])).all() + assert ( + first_hgg.expected_utilities({0: [1, 0], 1: [1, 0], 2: [1, 0], 3: [1, 0]}) + == np.mat([-3.0, -4.0, -4.0, -2.0]) + ).all() def test_expected_utilities2(first_hgg): - assert (first_hgg.expected_utilities( - {0: [0, 1], 1: [0, 1], 2: [0, 1], 3: [0, 1]}) == np.mat( - [-9., -12., -12., -6.])).all() + assert ( + first_hgg.expected_utilities({0: [0, 1], 1: [0, 1], 2: [0, 1], 3: [0, 1]}) + == np.mat([-9.0, -12.0, -12.0, -6.0]) + ).all() def test_expected_utilities3(first_hgg): - assert (first_hgg.expected_utilities( - {0: [1, 0], 1: [1, 0], 2: [0, 1], 3: [0, 1]}) == np.mat( - [-7., -12., -4., -3.])).all() + assert ( + first_hgg.expected_utilities({0: [1, 0], 1: [1, 0], 2: [0, 1], 3: [0, 1]}) + == np.mat([-7.0, -12.0, -4.0, -3.0]) + ).all() def test_expected_utilities4(first_hgg): - assert (first_hgg.expected_utilities( - {0: [1 / 2, 1 / 2], 1: [1 / 2, 1 / 2], 2: [1 / 2, 1 / 2], - 3: [1 / 2, 1 / 2]}) == np.mat([-5.875, -8.125, -8.125, -4.5])).all() + assert ( + first_hgg.expected_utilities( + {0: [1 / 2, 1 / 2], 1: [1 / 2, 1 / 2], 2: [1 / 2, 1 / 2], 3: [1 / 2, 1 / 2]} + ) + == np.mat([-5.875, -8.125, -8.125, -4.5]) + ).all() # is_equilibrium # no degen + def test_is_equilibrium1(first_hgg): - assert not ( - first_hgg.is_equilibrium({0: [1, 0], 1: [1, 0], 2: [1, 0], 3: [1, 0]})) + assert not (first_hgg.is_equilibrium({0: [1, 0], 1: [1, 0], 2: [1, 0], 3: [1, 0]})) def test_is_equilibrium2(first_hgg): - assert ( - first_hgg.is_equilibrium({0: [0, 1], 1: [0, 1], 2: [0, 1], 3: [0, 1]})) + assert first_hgg.is_equilibrium({0: [0, 1], 1: [0, 1], 2: [0, 1], 3: [0, 1]}) def test_is_equilibrium3(first_hgg): - assert not ( - first_hgg.is_equilibrium({0: [1, 0], 1: [1, 0], 2: [0, 1], 3: [0, 1]})) + assert not (first_hgg.is_equilibrium({0: [1, 0], 1: [1, 0], 2: [0, 1], 3: [0, 1]})) def test_is_equilibrium4(first_hgg): - assert not (first_hgg.is_equilibrium( - {0: [1 / 2, 1 / 2], 1: [1 / 2, 1 / 2], 2: [1 / 2, 1 / 2], - 3: [1 / 2, 1 / 2]})) + assert not ( + first_hgg.is_equilibrium( + {0: [1 / 2, 1 / 2], 1: [1 / 2, 1 / 2], 2: [1 / 2, 1 / 2], 3: [1 / 2, 1 / 2]} + ) + ) # util_of_player # no degen + def test_util_of_player1(first_hgg): - assert (first_hgg.util_of_player(0).keys() == {0} and - (first_hgg.util_of_player(0)[0] == [-3, -7, -7, -10, -1, -5, -5, - -9])) + assert first_hgg.util_of_player(0).keys() == {0} and ( + first_hgg.util_of_player(0)[0] == [-3, -7, -7, -10, -1, -5, -5, -9] + ) def test_util_of_player2(first_hgg): - assert (first_hgg.util_of_player(1).keys() == {0, 1} and - (first_hgg.util_of_player(1)[0] == [-3, -7, -1, -5, -7, -10, -5, - -9]) and - (first_hgg.util_of_player(1)[1] == [-1, -5, 0, -3])) + assert ( + first_hgg.util_of_player(1).keys() == {0, 1} + and (first_hgg.util_of_player(1)[0] == [-3, -7, -1, -5, -7, -10, -5, -9]) + and (first_hgg.util_of_player(1)[1] == [-1, -5, 0, -3]) + ) def test_util_of_player3(first_hgg): - assert (first_hgg.util_of_player(2).keys() == {0, 2} and - (first_hgg.util_of_player(2)[0] == [-3, -1, -7, -5, -7, -5, -10, - -9]) and - (first_hgg.util_of_player(2)[2] == [-1, -5, 0, -3])) + assert ( + first_hgg.util_of_player(2).keys() == {0, 2} + and (first_hgg.util_of_player(2)[0] == [-3, -1, -7, -5, -7, -5, -10, -9]) + and (first_hgg.util_of_player(2)[2] == [-1, -5, 0, -3]) + ) def test_util_of_player4(first_hgg): - assert (first_hgg.util_of_player(3).keys() == {1, 2} and - (first_hgg.util_of_player(3)[1] == [-1, 0, -5, -3]) and - (first_hgg.util_of_player(3)[2] == [-1, 0, -5, -3])) + assert ( + first_hgg.util_of_player(3).keys() == {1, 2} + and (first_hgg.util_of_player(3)[1] == [-1, 0, -5, -3]) + and (first_hgg.util_of_player(3)[2] == [-1, 0, -5, -3]) + ) # PNE METHOD MISSING @@ -335,9 +933,7 @@ def test_util_of_player4(first_hgg): def test_get_all_PNE1(first_hgg): - assert first_hgg.get_all_PNE() == [ - {0: [0, 1], 1: [0, 1], 2: [0, 1], 3: [0, 1]} - ] + assert first_hgg.get_all_PNE() == [{0: [0, 1], 1: [0, 1], 2: [0, 1], 3: [0, 1]}] def test_get_all_PNE2(second_hgg): @@ -353,15 +949,13 @@ def test_get_all_PNE4(degen_hgg): {0: [1, 0, 0], 1: [1, 0, 0], 2: [1, 0, 0], 3: [0, 0, 1]}, {0: [1, 0, 0], 1: [0, 1, 0], 2: [0, 1, 0], 3: [0, 1, 0]}, {0: [1, 0, 0], 1: [0, 0, 1], 2: [1, 0, 0], 3: [0, 1, 0]}, - {0: [0, 1, 0], 1: [1, 0, 0], 2: [0, 1, 0], 3: [1, 0, 0]} + {0: [0, 1, 0], 1: [1, 0, 0], 2: [0, 1, 0], 3: [1, 0, 0]}, ] def test_get_all_PNE5(first_hgg_fraction): tmp_hgg = first_hgg_fraction.game_as_int() - assert tmp_hgg.get_all_PNE() == [ - {0: [0, 1], 1: [0, 1], 2: [0, 1], 3: [0, 1]} - ] + assert tmp_hgg.get_all_PNE() == [{0: [0, 1], 1: [0, 1], 2: [0, 1], 3: [0, 1]}] def test_pne_exist1(first_hgg): @@ -383,37 +977,56 @@ def test_pne_exist4(degen_hgg): def test_pne_exist5(first_hgg_fraction): tmp_hgg = first_hgg_fraction.game_as_int() assert tmp_hgg.pne_exist() + + # build_subgame # no degen def test_build_subgame1(first_hgg): sub_first_hgg1 = first_hgg.build_subgame({3: [1, 0]}) - assert (sub_first_hgg1.players_actions == [[0, 1], [0, 1], [0, 1], - [-1]] and - sub_first_hgg1.utilities == [[[-3, -7, -7, -10, -1, -5, -5, -9], - [-3, -7, -1, -5, -7, -10, -5, -9], - [-3, -1, -7, -5, -7, -5, -10, -9]], - [[-1, 0], [-1, -5]], - [[-1, 0], [-1, -5]]]) + assert sub_first_hgg1.players_actions == [ + [0, 1], + [0, 1], + [0, 1], + [-1], + ] and sub_first_hgg1.utilities == [ + [ + [-3, -7, -7, -10, -1, -5, -5, -9], + [-3, -7, -1, -5, -7, -10, -5, -9], + [-3, -1, -7, -5, -7, -5, -10, -9], + ], + [[-1, 0], [-1, -5]], + [[-1, 0], [-1, -5]], + ] def test_build_subgame2(first_hgg): sub_first_hgg2 = first_hgg.build_subgame({0: [1, 0]}) - assert (sub_first_hgg2.players_actions == [[-1], [0, 1], [0, 1], - [0, 1]] and - sub_first_hgg2.utilities == [ - [[-3, -7, -7, -10], [-3, -7, -1, -5], [-3, -1, -7, -5]], - [[-1, -5, 0, -3], [-1, 0, -5, -3]], - [[-1, -5, 0, -3], [-1, 0, -5, -3]]]) + assert sub_first_hgg2.players_actions == [ + [-1], + [0, 1], + [0, 1], + [0, 1], + ] and sub_first_hgg2.utilities == [ + [[-3, -7, -7, -10], [-3, -7, -1, -5], [-3, -1, -7, -5]], + [[-1, -5, 0, -3], [-1, 0, -5, -3]], + [[-1, -5, 0, -3], [-1, 0, -5, -3]], + ] def test_build_subgame3(first_hgg): sub_first_hgg3 = first_hgg.build_subgame({1: [1, 0], 2: [0, 1]}) - assert (sub_first_hgg3.players_actions == [[0, 1], [-1], [-1], [0, 1]] and - sub_first_hgg3.utilities == [[[-7, -5], [-7, -10], [-1, -5]], - [[-1, -5], [-1, 0]], - [[0, -3], [-5, -3]]]) + assert sub_first_hgg3.players_actions == [ + [0, 1], + [-1], + [-1], + [0, 1], + ] and sub_first_hgg3.utilities == [ + [[-7, -5], [-7, -10], [-1, -5]], + [[-1, -5], [-1, 0]], + [[0, -3], [-5, -3]], + ] # [[[-3, -7, -7, -10, -1, -5, -5, -9], [-3, -7, -1, -5, -7, -10, -5, -9], # [-3, -1, -7, -5, -7, -5, -10, -9]], @@ -435,14 +1048,20 @@ MODIFICATION OF SIMPLIFY REQUIRED def test_simplify_subgame1(first_hgg): - simplify_first_hgg1 = first_hgg.build_subgame( - {3: [1, 0]}).simplify_subgame() - assert (simplify_first_hgg1.players_actions == [[0, 1], [0, 1], [0, 1]] and - simplify_first_hgg1.utilities == [ - [[-3, -7, -7, -10, -1, -5, -5, -9], - [-3, -7, -1, -5, -7, -10, -5, -9], - [-3, -1, -7, -5, -7, -5, -10, -9]], - [[-1, 0]], [[-1, 0]]]) + simplify_first_hgg1 = first_hgg.build_subgame({3: [1, 0]}).simplify_subgame() + assert simplify_first_hgg1.players_actions == [ + [0, 1], + [0, 1], + [0, 1], + ] and simplify_first_hgg1.utilities == [ + [ + [-3, -7, -7, -10, -1, -5, -5, -9], + [-3, -7, -1, -5, -7, -10, -5, -9], + [-3, -1, -7, -5, -7, -5, -10, -9], + ], + [[-1, 0]], + [[-1, 0]], + ] # ISSUE WITH THE DURING THE SIMPLIFICATION @@ -461,66 +1080,89 @@ def test_simplify_subgame1(first_hgg): # get_subgame_fixed_strat # no degen + def test_get_subgame_fixed_strat1(first_hgg): sub_first_hgg1 = first_hgg.get_subgame_fixed_strat( - {0: [1, 1], 1: [1, 1], 2: [1, 1], 3: [1, 0]}) - assert (sub_first_hgg1.players_actions == [[0, 1], [0, 1], [0, 1], [0]] and - sub_first_hgg1.utilities == [[[-3, -7, -7, -10, -1, -5, -5, -9], - [-3, -7, -1, -5, -7, -10, -5, -9], - [-3, -1, -7, -5, -7, -5, -10, -9]], - [[-1, 0], [-1, -5]], - [[-1, 0], [-1, -5]]]) + {0: [1, 1], 1: [1, 1], 2: [1, 1], 3: [1, 0]} + ) + assert sub_first_hgg1.players_actions == [ + [0, 1], + [0, 1], + [0, 1], + [0], + ] and sub_first_hgg1.utilities == [ + [ + [-3, -7, -7, -10, -1, -5, -5, -9], + [-3, -7, -1, -5, -7, -10, -5, -9], + [-3, -1, -7, -5, -7, -5, -10, -9], + ], + [[-1, 0], [-1, -5]], + [[-1, 0], [-1, -5]], + ] def test_get_subgame_fixed_strat2(first_hgg): sub_first_hgg2 = first_hgg.get_subgame_fixed_strat( - {0: [1, 0], 1: [1, 1], 2: [1, 1], 3: [1, 1]}) - assert (sub_first_hgg2.players_actions == [[0], [0, 1], [0, 1], [0, 1]] and - sub_first_hgg2.utilities == [ - [[-3, -7, -7, -10], [-3, -7, -1, -5], [-3, -1, -7, -5]], - [[-1, -5, 0, -3], [-1, 0, -5, -3]], - [[-1, -5, 0, -3], [-1, 0, -5, -3]]]) + {0: [1, 0], 1: [1, 1], 2: [1, 1], 3: [1, 1]} + ) + assert sub_first_hgg2.players_actions == [ + [0], + [0, 1], + [0, 1], + [0, 1], + ] and sub_first_hgg2.utilities == [ + [[-3, -7, -7, -10], [-3, -7, -1, -5], [-3, -1, -7, -5]], + [[-1, -5, 0, -3], [-1, 0, -5, -3]], + [[-1, -5, 0, -3], [-1, 0, -5, -3]], + ] def test_get_subgame_fixed_strat3(first_hgg): sub_first_hgg3 = first_hgg.get_subgame_fixed_strat( - {0: [1, 1], 1: [1, 0], 2: [0, 1], 3: [1, 1]}) - assert (sub_first_hgg3.players_actions == [[0, 1], [0], [1], [0, 1]] and - sub_first_hgg3.utilities == [[[-7, -5], [-7, -10], [-1, -5]], - [[-1, -5], [-1, 0]], - [[0, -3], [-5, -3]]]) + {0: [1, 1], 1: [1, 0], 2: [0, 1], 3: [1, 1]} + ) + assert sub_first_hgg3.players_actions == [ + [0, 1], + [0], + [1], + [0, 1], + ] and sub_first_hgg3.utilities == [ + [[-7, -5], [-7, -10], [-1, -5]], + [[-1, -5], [-1, 0]], + [[0, -3], [-5, -3]], + ] def test_local_game_of_player_n1(first_hgg, degen_hgg): - assert (first_hgg.local_game_of_player_n(0) == [0]) + assert first_hgg.local_game_of_player_n(0) == [0] def test_local_game_of_player_n2(first_hgg): - assert (first_hgg.local_game_of_player_n(1) == [0, 1]) + assert first_hgg.local_game_of_player_n(1) == [0, 1] def test_local_game_of_player_n3(first_hgg): - assert (first_hgg.local_game_of_player_n(2) == [0, 2]) + assert first_hgg.local_game_of_player_n(2) == [0, 2] def test_local_game_of_player_n4(first_hgg): - assert (first_hgg.local_game_of_player_n(3) == [1, 2]) + assert first_hgg.local_game_of_player_n(3) == [1, 2] def test_local_game_of_player_n5(degen_hgg): - assert (degen_hgg.local_game_of_player_n(0) == [1, 2]) + assert degen_hgg.local_game_of_player_n(0) == [1, 2] def test_local_game_of_player_n6(degen_hgg): - assert (degen_hgg.local_game_of_player_n(1) == [0, 1, 2]) + assert degen_hgg.local_game_of_player_n(1) == [0, 1, 2] def test_local_game_of_player_n7(degen_hgg): - assert (degen_hgg.local_game_of_player_n(2) == [0, 2]) + assert degen_hgg.local_game_of_player_n(2) == [0, 2] def test_local_game_of_player_n8(degen_hgg): - assert (degen_hgg.local_game_of_player_n(3) == [0, 1]) + assert degen_hgg.local_game_of_player_n(3) == [0, 1] """ @@ -530,234 +1172,431 @@ Add another hypergraphical game # get_max_value_of_player_n def test_get_max_value_of_player_n1(first_hgg): - assert (first_hgg.get_max_value_of_player_n(0) == -1) + assert first_hgg.get_max_value_of_player_n(0) == -1 def test_get_max_value_of_player_n2(first_hgg): - assert (first_hgg.get_max_value_of_player_n(1) == 0) + assert first_hgg.get_max_value_of_player_n(1) == 0 def test_get_max_value_of_player_n3(first_hgg): - assert (first_hgg.get_max_value_of_player_n(2) == 0) + assert first_hgg.get_max_value_of_player_n(2) == 0 def test_get_max_value_of_player_n4(first_hgg): - assert (first_hgg.get_max_value_of_player_n(3) == 0) + assert first_hgg.get_max_value_of_player_n(3) == 0 def test_get_max_value_of_player_n5(degen_hgg): - assert (degen_hgg.get_max_value_of_player_n(0) == -1) + assert degen_hgg.get_max_value_of_player_n(0) == -1 def test_get_max_value_of_player_n6(degen_hgg): - assert (degen_hgg.get_max_value_of_player_n(1) == -1) + assert degen_hgg.get_max_value_of_player_n(1) == -1 def test_get_max_value_of_player_n7(degen_hgg): - assert (degen_hgg.get_max_value_of_player_n(2) == -1) + assert degen_hgg.get_max_value_of_player_n(2) == -1 def test_get_max_value_of_player_n8(degen_hgg): - assert (degen_hgg.get_max_value_of_player_n(3) == -1) + assert degen_hgg.get_max_value_of_player_n(3) == -1 # index_of_player_in_local def test_index_of_player_in_local1(first_hgg, degen_hgg): - assert (first_hgg.index_of_player_in_local(0) == {0: 0}) + assert first_hgg.index_of_player_in_local(0) == {0: 0} def test_index_of_player_in_local2(first_hgg): - assert (first_hgg.index_of_player_in_local(1) == {0: 1, 1: 0}) + assert first_hgg.index_of_player_in_local(1) == {0: 1, 1: 0} def test_index_of_player_in_local3(first_hgg): - assert (first_hgg.index_of_player_in_local(2) == {0: 2, 2: 0}) + assert first_hgg.index_of_player_in_local(2) == {0: 2, 2: 0} def test_index_of_player_in_local4(first_hgg): - assert (first_hgg.index_of_player_in_local(3) == {1: 1, 2: 1}) + assert first_hgg.index_of_player_in_local(3) == {1: 1, 2: 1} def test_index_of_player_in_local5(degen_hgg): - assert (degen_hgg.index_of_player_in_local(0) == {1: 0, 2: 0}) + assert degen_hgg.index_of_player_in_local(0) == {1: 0, 2: 0} def test_index_of_player_in_local6(degen_hgg): - assert (degen_hgg.index_of_player_in_local(1) == {0: 0, 1: 1, 2: 1}) + assert degen_hgg.index_of_player_in_local(1) == {0: 0, 1: 1, 2: 1} def test_index_of_player_in_local7(degen_hgg): - assert (degen_hgg.index_of_player_in_local(2) == {0: 1, 2: 2}) + assert degen_hgg.index_of_player_in_local(2) == {0: 1, 2: 2} def test_index_of_player_in_local8(degen_hgg): - assert (degen_hgg.index_of_player_in_local(3) == {0: 2, 1: 2}) + assert degen_hgg.index_of_player_in_local(3) == {0: 2, 1: 2} # get_subgame_level + def test_get_subgame_level1(first_hgg): sub_level_first_hgg1 = first_hgg.get_subgame_level( - {0: [1, 0], 1: [1, 0], 2: [1, 0], 3: [1, 0]}) - assert (sub_level_first_hgg1.players_actions == [[0, 1], [0, 1], - [0, 1]] and - sub_level_first_hgg1.utilities == [ - [[-3, -7, -7, -10, -1, -5, -5, -9], - [-3, -7, -1, -5, -7, -10, -5, -9], - [-3, -1, -7, -5, -7, -5, -10, -9]], - [[-1, 0]], [[-1, 0]]]) + {0: [1, 0], 1: [1, 0], 2: [1, 0], 3: [1, 0]} + ) + assert sub_level_first_hgg1.players_actions == [ + [0, 1], + [0, 1], + [0, 1], + ] and sub_level_first_hgg1.utilities == [ + [ + [-3, -7, -7, -10, -1, -5, -5, -9], + [-3, -7, -1, -5, -7, -10, -5, -9], + [-3, -1, -7, -5, -7, -5, -10, -9], + ], + [[-1, 0]], + [[-1, 0]], + ] def test_get_subgame_level2(first_hgg): sub_level_first_hgg2 = first_hgg.get_subgame_level( - {0: [1, 0], 1: [1, 0], 2: [1, 0], 3: [0, 1]}) - assert (sub_level_first_hgg2.players_actions == [[0, 1], [0, 1], - [0, 1]] and - sub_level_first_hgg2.utilities == [ - [[-3, -7, -7, -10, -1, -5, -5, -9], - [-3, -7, -1, -5, -7, -10, -5, -9], - [-3, -1, -7, -5, -7, -5, -10, -9]], - [[-5, -3]], [[-5, -3]]]) + {0: [1, 0], 1: [1, 0], 2: [1, 0], 3: [0, 1]} + ) + assert sub_level_first_hgg2.players_actions == [ + [0, 1], + [0, 1], + [0, 1], + ] and sub_level_first_hgg2.utilities == [ + [ + [-3, -7, -7, -10, -1, -5, -5, -9], + [-3, -7, -1, -5, -7, -10, -5, -9], + [-3, -1, -7, -5, -7, -5, -10, -9], + ], + [[-5, -3]], + [[-5, -3]], + ] def test_get_subgame_level3(degen_hgg): sub_level_degen_hgg1 = degen_hgg.get_subgame_level( - {0: [1, 0, 0], 1: [1, 0, 0], 2: [1, 0, 0], 3: [1, 0, 0]}) - assert (sub_level_degen_hgg1.players_actions == [[0, 1, 2], [0, 1, 2], - [0, 1, 2]] and - sub_level_degen_hgg1.utilities == [ - [[-6, -1, -7, -10, -1, -6, -6, -4, -7], - [-9, -2, -7, -2, -5, -7, -7, -5, -8]], - [[-7, -9, -6, -8, -2, -10, -6, -6, -3], - [-3, -2, -1, -10, -9, -7, -6, -4, -3]], - [[-1, -8, -5, -4, -2, -5, -1, -10, -5, -2, -1, -3, -7, -3, -5, - -1, -7, -9, -9, -4, -5, -5, -10, -3, -6, -2, -6], - [-5, -7, -1, -9, -3, -7, -6, -10, -8, -9, -4, -1, -8, -5, -1, - -10, -6, -4, -4, -7, -6, -10, -5, -8, -7, -3, -2], - [-6, -8, -6, -3, -1, -6, -7, -2, -9, -7, -9, -10, -4, -3, -6, - -5, -5, -10, -4, -4, -5, -4, -10, -3, -4, -5, -3]]]) + {0: [1, 0, 0], 1: [1, 0, 0], 2: [1, 0, 0], 3: [1, 0, 0]} + ) + assert sub_level_degen_hgg1.players_actions == [ + [0, 1, 2], + [0, 1, 2], + [0, 1, 2], + ] and sub_level_degen_hgg1.utilities == [ + [[-6, -1, -7, -10, -1, -6, -6, -4, -7], [-9, -2, -7, -2, -5, -7, -7, -5, -8]], + [[-7, -9, -6, -8, -2, -10, -6, -6, -3], [-3, -2, -1, -10, -9, -7, -6, -4, -3]], + [ + [ + -1, + -8, + -5, + -4, + -2, + -5, + -1, + -10, + -5, + -2, + -1, + -3, + -7, + -3, + -5, + -1, + -7, + -9, + -9, + -4, + -5, + -5, + -10, + -3, + -6, + -2, + -6, + ], + [ + -5, + -7, + -1, + -9, + -3, + -7, + -6, + -10, + -8, + -9, + -4, + -1, + -8, + -5, + -1, + -10, + -6, + -4, + -4, + -7, + -6, + -10, + -5, + -8, + -7, + -3, + -2, + ], + [ + -6, + -8, + -6, + -3, + -1, + -6, + -7, + -2, + -9, + -7, + -9, + -10, + -4, + -3, + -6, + -5, + -5, + -10, + -4, + -4, + -5, + -4, + -10, + -3, + -4, + -5, + -3, + ], + ], + ] def test_get_subgame_level4(degen_hgg): sub_level_degen_hgg1 = degen_hgg.get_subgame_level( - {0: [1, 0, 0], 1: [1, 0, 0], 2: [1, 0, 0], 3: [1, 0, 0]}) + {0: [1, 0, 0], 1: [1, 0, 0], 2: [1, 0, 0], 3: [1, 0, 0]} + ) sub_level_degen_hgg1bis = sub_level_degen_hgg1.get_subgame_level( - {0: [1, 0, 0], 1: [1, 0, 0], 2: [1, 0, 0]}) - assert (sub_level_degen_hgg1bis.players_actions == [[0, 1, 2], - [0, 1, 2]] and - sub_level_degen_hgg1bis.utilities == [ - [[-6, -10, -6, ]], - [[-7, -9, -6, -8, -2, -10, -6, -6, -3], - [-3, -2, -1, -10, -9, -7, -6, -4, -3]], - [[-1, -4, -1, -2, -7, -1, -9, -5, -6], - [-5, -9, -6, -9, -8, -10, -4, -10, -7]]]) + {0: [1, 0, 0], 1: [1, 0, 0], 2: [1, 0, 0]} + ) + assert sub_level_degen_hgg1bis.players_actions == [ + [0, 1, 2], + [0, 1, 2], + ] and sub_level_degen_hgg1bis.utilities == [ + [ + [ + -6, + -10, + -6, + ] + ], + [[-7, -9, -6, -8, -2, -10, -6, -6, -3], [-3, -2, -1, -10, -9, -7, -6, -4, -3]], + [[-1, -4, -1, -2, -7, -1, -9, -5, -6], [-5, -9, -6, -9, -8, -10, -4, -10, -7]], + ] def test_get_subgame_without_n1(first_hgg): sub_n_first_hgg = first_hgg.get_subgame_without_n( - {0: [1, 0], 1: [1, 0], 2: [1, 0], 3: [1, 0]}, 0) - assert (sub_n_first_hgg.players_actions == [[0, 1], [0, 1], [0, 1]] and - sub_n_first_hgg.utilities == [[[-3, -7, -1, -5], [-3, -1, -7, -5]], - [[-1, -5, 0, -3], [-1, 0, -5, -3]], - [[-1, -5, 0, -3], [-1, 0, -5, -3]]]) + {0: [1, 0], 1: [1, 0], 2: [1, 0], 3: [1, 0]}, 0 + ) + assert sub_n_first_hgg.players_actions == [ + [0, 1], + [0, 1], + [0, 1], + ] and sub_n_first_hgg.utilities == [ + [[-3, -7, -1, -5], [-3, -1, -7, -5]], + [[-1, -5, 0, -3], [-1, 0, -5, -3]], + [[-1, -5, 0, -3], [-1, 0, -5, -3]], + ] def test_get_subgame_without_n2(first_hgg): sub_n_first_hgg = first_hgg.get_subgame_without_n( - {0: [1, 0], 1: [1, 0], 2: [1, 0], 3: [1, 0]}, 2) - assert (sub_n_first_hgg.players_actions == [[0, 1], [0, 1], [0, 1]] and - sub_n_first_hgg.utilities == [[[-3, -7, -1, -5], [-3, -1, -7, -5]], - [[-1, -5, 0, -3], [-1, 0, -5, -3]], - [[-1, 0]]]) + {0: [1, 0], 1: [1, 0], 2: [1, 0], 3: [1, 0]}, 2 + ) + assert sub_n_first_hgg.players_actions == [ + [0, 1], + [0, 1], + [0, 1], + ] and sub_n_first_hgg.utilities == [ + [[-3, -7, -1, -5], [-3, -1, -7, -5]], + [[-1, -5, 0, -3], [-1, 0, -5, -3]], + [[-1, 0]], + ] def test_get_subgame_without_n3(degen_hgg): sub_n_degen_hgg1 = degen_hgg.get_subgame_without_n( - {0: [1, 0, 0], 1: [1, 0, 0], 2: [1, 0, 0], 3: [1, 0, 0]}, 0) - assert (sub_n_degen_hgg1.players_actions == [[0, 1, 2], [0, 1, 2], - [0, 1, 2]] and - sub_n_degen_hgg1.utilities == [[[-6, -3, -3, -1, -4, -10, -7, -5, - -5, -10, -2, -1, -1, -3, -7, -6, - -1, -2, -6, -3, -3, -4, -8, -3, - -7, -8, -8], - [-9, -1, -8, -2, -7, -6, -7, -6, - -9, -2, -4, -2, -5, -2, -3, -7, - -3, -7, -7, -5, -3, -5, -10, -5, - -8, -9, -9], - [-3, -1, -2, -4, -1, -4, -8, -7, - -3, -6, -9, -1, -1, -3, -7, -3, - -7, -2, -1, -4, -10, -4, -9, -4, - -3, -6, -3]], - [[-3, -6, -3, -2, -9, -3, -1, -3, - -6], - [-9, -9, -5, -9, -6, -3, -6, -2, - -7]], - [[-5, -7, -1, -9, -3, -7, -6, -10, - -8], - [-6, -8, -6, -3, -1, -6, -7, -2, - -9]]]) + {0: [1, 0, 0], 1: [1, 0, 0], 2: [1, 0, 0], 3: [1, 0, 0]}, 0 + ) + assert sub_n_degen_hgg1.players_actions == [ + [0, 1, 2], + [0, 1, 2], + [0, 1, 2], + ] and sub_n_degen_hgg1.utilities == [ + [ + [ + -6, + -3, + -3, + -1, + -4, + -10, + -7, + -5, + -5, + -10, + -2, + -1, + -1, + -3, + -7, + -6, + -1, + -2, + -6, + -3, + -3, + -4, + -8, + -3, + -7, + -8, + -8, + ], + [ + -9, + -1, + -8, + -2, + -7, + -6, + -7, + -6, + -9, + -2, + -4, + -2, + -5, + -2, + -3, + -7, + -3, + -7, + -7, + -5, + -3, + -5, + -10, + -5, + -8, + -9, + -9, + ], + [ + -3, + -1, + -2, + -4, + -1, + -4, + -8, + -7, + -3, + -6, + -9, + -1, + -1, + -3, + -7, + -3, + -7, + -2, + -1, + -4, + -10, + -4, + -9, + -4, + -3, + -6, + -3, + ], + ], + [[-3, -6, -3, -2, -9, -3, -1, -3, -6], [-9, -9, -5, -9, -6, -3, -6, -2, -7]], + [[-5, -7, -1, -9, -3, -7, -6, -10, -8], [-6, -8, -6, -3, -1, -6, -7, -2, -9]], + ] # get_player_interact + def test_get_player_interact1(first_hgg): - assert (first_hgg.get_player_interact(0) == [1, 2]) + assert first_hgg.get_player_interact(0) == [1, 2] def test_get_player_interact2(first_hgg): - assert (first_hgg.get_player_interact(1) == [0, 2, 3]) + assert first_hgg.get_player_interact(1) == [0, 2, 3] def test_get_player_interact3(first_hgg): - assert (first_hgg.get_player_interact(2) == [0, 1, 3]) + assert first_hgg.get_player_interact(2) == [0, 1, 3] def test_get_player_interact4(first_hgg): - assert (first_hgg.get_player_interact(3) == [1, 2]) + assert first_hgg.get_player_interact(3) == [1, 2] def test_get_player_interact5(degen_hgg): - assert (degen_hgg.get_player_interact(0) == [1, 2, 3]) + assert degen_hgg.get_player_interact(0) == [1, 2, 3] def test_get_player_interact6(degen_hgg): - assert (degen_hgg.get_player_interact(1) == [0, 2, 3]) + assert degen_hgg.get_player_interact(1) == [0, 2, 3] def test_get_player_interact7(degen_hgg): - assert (degen_hgg.get_player_interact(2) == [0, 1, 3]) + assert degen_hgg.get_player_interact(2) == [0, 1, 3] def test_get_player_interact8(degen_hgg): - assert (degen_hgg.get_player_interact(3) == [0, 1, 2]) + assert degen_hgg.get_player_interact(3) == [0, 1, 2] def test_get_player_interact_except_e1(first_hgg, degen_hgg): - assert (first_hgg.get_player_interact_except_e(0, [0, 1, 2]) == []) + assert first_hgg.get_player_interact_except_e(0, [0, 1, 2]) == [] def test_get_player_interact_except_e2(first_hgg): - assert (first_hgg.get_player_interact_except_e(1, [0, 1, 2]) == [3]) + assert first_hgg.get_player_interact_except_e(1, [0, 1, 2]) == [3] def test_get_player_interact_except_e3(first_hgg): - assert (first_hgg.get_player_interact_except_e(1, [1, 3]) == [0, 2]) + assert first_hgg.get_player_interact_except_e(1, [1, 3]) == [0, 2] def test_get_player_interact_except_e4(first_hgg): - assert (first_hgg.get_player_interact_except_e(2, [0, 1, 2]) == [3]) + assert first_hgg.get_player_interact_except_e(2, [0, 1, 2]) == [3] def test_get_player_interact_except_e5(first_hgg): - assert (first_hgg.get_player_interact_except_e(2, [2, 3]) == [0, 1]) + assert first_hgg.get_player_interact_except_e(2, [2, 3]) == [0, 1] def test_get_player_interact_except_e6(first_hgg): - assert (first_hgg.get_player_interact_except_e(3, [1, 3]) == [2]) + assert first_hgg.get_player_interact_except_e(3, [1, 3]) == [2] def test_get_player_interact_except_e7(first_hgg): - assert (first_hgg.get_player_interact_except_e(3, [2, 3]) == [1]) + assert first_hgg.get_player_interact_except_e(3, [2, 3]) == [1] # Depend on meaning of returned value of get_player_interact_except_e @@ -780,27 +1619,27 @@ def test_get_player_interact_except_e7(first_hgg): def test_get_player_except_e1(first_hgg, degen_hgg): - assert (first_hgg.get_player_except_e([0, 1, 2]) == [3]) + assert first_hgg.get_player_except_e([0, 1, 2]) == [3] def test_get_player_except_e2(first_hgg): - assert (first_hgg.get_player_except_e([1, 3]) == [0, 2]) + assert first_hgg.get_player_except_e([1, 3]) == [0, 2] def test_get_player_except_e3(first_hgg): - assert (first_hgg.get_player_except_e([2, 3]) == [0, 1]) + assert first_hgg.get_player_except_e([2, 3]) == [0, 1] def test_get_player_except_e4(degen_hgg): - assert (degen_hgg.get_player_except_e([1, 2, 3]) == [0]) + assert degen_hgg.get_player_except_e([1, 2, 3]) == [0] def test_get_player_except_e5(degen_hgg): - assert (degen_hgg.get_player_except_e([0, 1, 3]) == [2]) + assert degen_hgg.get_player_except_e([0, 1, 3]) == [2] def test_get_player_except_e6(degen_hgg): - assert (degen_hgg.get_player_except_e([0, 1, 2]) == [3]) + assert degen_hgg.get_player_except_e([0, 1, 2]) == [3] """ @@ -820,7 +1659,8 @@ def test_convert_to_NFG1(first_hgg): [-3, -3, -7, -7, -7, -7, -10, -10, -1, -1, -5, -5, -5, -5, -9, -9], [-4, -8, -8, -12, -1, -4, -5, -8, -8, -12, -11, -15, -5, -8, -9, -12], [-4, -8, -1, -4, -8, -12, -5, -8, -8, -12, -5, -8, -11, -15, -9, -12], - [-2, 0, -6, -3, -6, -3, -10, -6, -2, 0, -6, -3, -6, -3, -10, -6]] + [-2, 0, -6, -3, -6, -3, -10, -6, -2, 0, -6, -3, -6, -3, -10, -6], + ] def test_convert_to_NFG2(second_hgg): @@ -830,7 +1670,8 @@ def test_convert_to_NFG2(second_hgg): [-3, -3, -1, -1, -3, -3, -2, -2, -2, -2, -3, -3, -2, -2, -1, -1], [-2, -4, -4, -6, -7, -7, -3, -3, -2, -4, -7, -9, -5, -5, -6, -6], [-5, -3, -7, -8, -9, -7, -8, -9, -6, -4, -5, -6, -6, -4, -8, -9], - [-2, -5, -2, -7, -3, -4, -3, -6, -2, -5, -2, -7, -3, -4, -3, -6]] + [-2, -5, -2, -7, -3, -4, -3, -6, -2, -5, -2, -7, -3, -4, -3, -6], + ] def test_convert_to_NFG3(third_hgg): @@ -840,52 +1681,367 @@ def test_convert_to_NFG3(third_hgg): [158, 54, 101, 11, 93, 108, 36, 65, 177, 92, 93, 92, 147, 62, 63, 62], [51, 97, 51, 97, 98, 83, 98, 83, 90, 1, 90, 1, 2, 47, 2, 47], [10, 88, 72, 47, 10, 88, 72, 47, 13, 24, 42, 72, 13, 24, 42, 72], - [19, 52, 86, 16, 30, 122, 97, 86, 153, 101, 161, 193, 146, 69, 154, - 161]] + [19, 52, 86, 16, 30, 122, 97, 86, 153, 101, 161, 193, 146, 69, 154, 161], + ] def test_convert_to_NFG4(degen_hgg): new_nfg = degen_hgg.convert_to_NFG() assert new_nfg.players_actions == degen_hgg.players_actions assert new_nfg.utilities == [ - [-8, -4, -6, -15, -11, -13, -12, -8, -10, -13, -13, -9, -11, -11, -7, - -14, -14, -10, -7, -6, -3, -16, -15, -12, -11, -10, -7, -10, -9, -12, - -9, -8, -11, -11, -10, -13, -9, -17, -13, -5, -13, -9, -7, -15, -11, - -11, -6, -9, -17, -12, -15, -19, -14, -17, -15, -10, -16, -10, -5, - -11, -11, -6, -12, -11, -8, -10, -16, -13, -15, -9, -6, -8, -9, -12, - -12, -5, -8, -8, -9, -12, -12], - [-14, -14, -11, -11, -17, -20, -11, -12, -9, -21, -20, -13, -6, -15, - -13, -15, -17, -12, -13, -12, -15, -15, -21, -19, -16, -19, -22, -25, - -17, -16, -15, -13, -18, -18, -11, -10, -27, -12, -19, -15, -10, -22, - -16, -4, -13, -23, -23, -23, -17, -24, -19, -18, -22, -22, -16, -15, - -13, -14, -19, -23, -19, -19, -17, -24, -16, -12, -10, -12, -13, -18, - -13, -11, -16, -15, -18, -10, -16, -14, -12, -15, -18], - [-15, -7, -14, -10, -15, -14, -13, -12, -15, -5, -7, -5, -6, -3, -4, - -13, -9, -13, -14, -12, -10, -7, -12, -7, -17, -18, -18, -16, -8, -15, - -11, -16, -15, -17, -16, -19, -6, -8, -6, -8, -5, -6, -13, -9, -13, - -12, -10, -8, -10, -15, -10, -18, -19, -19, -13, -5, -12, -6, -11, - -10, -12, -11, -14, -6, -8, -6, -15, -12, -13, -10, -6, -10, -11, -9, - -7, -10, -15, -10, -11, -12, -12], - [-12, -10, -7, -13, -10, -9, -17, -16, -8, -15, -15, -4, -10, -9, -10, - -12, -13, -5, -7, -6, -17, -10, -11, -11, -9, -8, -10, -5, -6, -12, - -6, -6, -14, -10, -12, -13, -9, -14, -4, -4, -8, -10, -6, -12, -5, -5, - -13, -18, -8, -18, -12, -7, -15, -11, -6, -2, -8, -7, -2, -10, -11, - -8, -9, -8, -11, -8, -3, -5, -14, -5, -9, -9, -11, -14, -13, -14, -19, - -7, -13, -16, -6]] + [ + -8, + -4, + -6, + -15, + -11, + -13, + -12, + -8, + -10, + -13, + -13, + -9, + -11, + -11, + -7, + -14, + -14, + -10, + -7, + -6, + -3, + -16, + -15, + -12, + -11, + -10, + -7, + -10, + -9, + -12, + -9, + -8, + -11, + -11, + -10, + -13, + -9, + -17, + -13, + -5, + -13, + -9, + -7, + -15, + -11, + -11, + -6, + -9, + -17, + -12, + -15, + -19, + -14, + -17, + -15, + -10, + -16, + -10, + -5, + -11, + -11, + -6, + -12, + -11, + -8, + -10, + -16, + -13, + -15, + -9, + -6, + -8, + -9, + -12, + -12, + -5, + -8, + -8, + -9, + -12, + -12, + ], + [ + -14, + -14, + -11, + -11, + -17, + -20, + -11, + -12, + -9, + -21, + -20, + -13, + -6, + -15, + -13, + -15, + -17, + -12, + -13, + -12, + -15, + -15, + -21, + -19, + -16, + -19, + -22, + -25, + -17, + -16, + -15, + -13, + -18, + -18, + -11, + -10, + -27, + -12, + -19, + -15, + -10, + -22, + -16, + -4, + -13, + -23, + -23, + -23, + -17, + -24, + -19, + -18, + -22, + -22, + -16, + -15, + -13, + -14, + -19, + -23, + -19, + -19, + -17, + -24, + -16, + -12, + -10, + -12, + -13, + -18, + -13, + -11, + -16, + -15, + -18, + -10, + -16, + -14, + -12, + -15, + -18, + ], + [ + -15, + -7, + -14, + -10, + -15, + -14, + -13, + -12, + -15, + -5, + -7, + -5, + -6, + -3, + -4, + -13, + -9, + -13, + -14, + -12, + -10, + -7, + -12, + -7, + -17, + -18, + -18, + -16, + -8, + -15, + -11, + -16, + -15, + -17, + -16, + -19, + -6, + -8, + -6, + -8, + -5, + -6, + -13, + -9, + -13, + -12, + -10, + -8, + -10, + -15, + -10, + -18, + -19, + -19, + -13, + -5, + -12, + -6, + -11, + -10, + -12, + -11, + -14, + -6, + -8, + -6, + -15, + -12, + -13, + -10, + -6, + -10, + -11, + -9, + -7, + -10, + -15, + -10, + -11, + -12, + -12, + ], + [ + -12, + -10, + -7, + -13, + -10, + -9, + -17, + -16, + -8, + -15, + -15, + -4, + -10, + -9, + -10, + -12, + -13, + -5, + -7, + -6, + -17, + -10, + -11, + -11, + -9, + -8, + -10, + -5, + -6, + -12, + -6, + -6, + -14, + -10, + -12, + -13, + -9, + -14, + -4, + -4, + -8, + -10, + -6, + -12, + -5, + -5, + -13, + -18, + -8, + -18, + -12, + -7, + -15, + -11, + -6, + -2, + -8, + -7, + -2, + -10, + -11, + -8, + -9, + -8, + -11, + -8, + -3, + -5, + -14, + -5, + -9, + -9, + -11, + -14, + -13, + -14, + -19, + -7, + -13, + -16, + -6, + ], + ] def test_convert_to_HGG1(): players_actions = [[0, 1], [0, 1], [0, 1]] - utilities = [[-3, -7, -7, -10, -1, -5, -5, -9], - [-3, -7, -1, -5, -7, -10, -5, -9], - [-3, -1, -7, -5, -7, -5, -10, -9]] + utilities = [ + [-3, -7, -7, -10, -1, -5, -5, -9], + [-3, -7, -1, -5, -7, -10, -5, -9], + [-3, -1, -7, -5, -7, -5, -10, -9], + ] nfg = NFG(players_actions, utilities) new_hgg = HGG.convert_to_HGG(nfg) assert new_hgg.players_actions == nfg.players_actions assert new_hgg.hypergraph == [[0, 1, 2]] assert new_hgg.utilities == [ - [[-3, -7, -7, -10, -1, -5, -5, -9], [-3, -7, -1, -5, -7, -10, -5, -9], - [-3, -1, -7, -5, -7, -5, -10, -9]]] + [ + [-3, -7, -7, -10, -1, -5, -5, -9], + [-3, -7, -1, -5, -7, -10, -5, -9], + [-3, -1, -7, -5, -7, -5, -10, -9], + ] + ] def test_convert_to_HGG2(): @@ -894,16 +2050,20 @@ def test_convert_to_HGG2(): [51, 29, 47, 43, 75, 61, 42, 19, 28, 39, 40, 21, 60, 60, 67, 44], [58, 72, 31, 41, 37, 5, 37, 41, 53, 68, 38, 30, 58, 72, 75, 0], [29, 73, 42, 13, 34, 31, 54, 25, 47, 29, 19, 46, 85, 79, 65, 24], - [1, 17, 49, 9, 51, 25, 21, 49, 28, 77, 41, 69, 13, 100, 49, 27]] + [1, 17, 49, 9, 51, 25, 21, 49, 28, 77, 41, 69, 13, 100, 49, 27], + ] nfg = NFG(players_actions, utilities) new_hgg = HGG.convert_to_HGG(nfg) assert new_hgg.players_actions == nfg.players_actions assert new_hgg.hypergraph == [[0, 1, 2, 3]] assert new_hgg.utilities == [ - [[51, 29, 47, 43, 75, 61, 42, 19, 28, 39, 40, 21, 60, 60, 67, 44], - [58, 72, 31, 41, 37, 5, 37, 41, 53, 68, 38, 30, 58, 72, 75, 0], - [29, 73, 42, 13, 34, 31, 54, 25, 47, 29, 19, 46, 85, 79, 65, 24], - [1, 17, 49, 9, 51, 25, 21, 49, 28, 77, 41, 69, 13, 100, 49, 27]]] + [ + [51, 29, 47, 43, 75, 61, 42, 19, 28, 39, 40, 21, 60, 60, 67, 44], + [58, 72, 31, 41, 37, 5, 37, 41, 53, 68, 38, 30, 58, 72, 75, 0], + [29, 73, 42, 13, 34, 31, 54, 25, 47, 29, 19, 46, 85, 79, 65, 24], + [1, 17, 49, 9, 51, 25, 21, 49, 28, 77, 41, 69, 13, 100, 49, 27], + ] + ] def test_game_as_int(first_hgg_fraction, first_hgg): @@ -915,31 +2075,43 @@ def test_read_GameFile1(): read_hgg = HGG.read_GameFile("filestest/CovG_0.hgg") assert read_hgg.players_actions == [[0, 1], [0, 1], [0, 1], [0, 1]] assert read_hgg.hypergraph == [[0, 1, 3], [1, 2, 3]] - assert read_hgg.utilities == [[[100, 33, 31, 40, 35, 52, 40, 30], - [25, 34, 18, 47, 54, 30, 52, 44], - [67, 34, 17, 0, 66, 37, 46, 33]], - [[31, 70, 11, 59, 70, 78, 66, 52], - [6, 87, 58, 42, 68, 92, 52, 51], - [71, 65, 6, 74, 95, 59, 100, 0]]] + assert read_hgg.utilities == [ + [ + [100, 33, 31, 40, 35, 52, 40, 30], + [25, 34, 18, 47, 54, 30, 52, 44], + [67, 34, 17, 0, 66, 37, 46, 33], + ], + [ + [31, 70, 11, 59, 70, 78, 66, 52], + [6, 87, 58, 42, 68, 92, 52, 51], + [71, 65, 6, 74, 95, 59, 100, 0], + ], + ] def test_read_GameFile2(): read_hgg = HGG.read_GameFile("filestest/pileface.hgg") assert read_hgg.players_actions == [[0, 1], [0, 1], [0, 1], [0, 1]] assert read_hgg.hypergraph == [[1, 2, 3], [0, 2], [0, 1]] - assert read_hgg.utilities == [[[0, -1, -1, -2, 2, 1, 1, 0], - [0, -1, 2, 1, -1, -2, 1, 0], - [0, 2, -1, 1, -1, 1, -2, 0]], - [[0, -1, 1, 0], [0, 1, -1, 0]], - [[0, -1, 1, 0], [0, 1, -1, 0]]] + assert read_hgg.utilities == [ + [ + [0, -1, -1, -2, 2, 1, 1, 0], + [0, -1, 2, 1, -1, -2, 1, 0], + [0, 2, -1, 1, -1, 1, -2, 0], + ], + [[0, -1, 1, 0], [0, 1, -1, 0]], + [[0, -1, 1, 0], [0, 1, -1, 0]], + ] def test_read_GameFile3(): read_hgg = HGG.read_GameFile("filestest/DDP_poly.hgg") assert read_hgg.players_actions == [[0, 1], [0, 1], [0, 1]] assert read_hgg.hypergraph == [[1, 2], [0, 1]] - assert read_hgg.utilities == [[[-1, -5, 0, -3], [-1, 0, -5, -3]], - [[-1, -4, 0, -3], [-1, 0, -4, -3]]] + assert read_hgg.utilities == [ + [[-1, -5, 0, -3], [-1, 0, -5, -3]], + [[-1, -4, 0, -3], [-1, 0, -4, -3]], + ] def test_write_GameFile1(first_hgg): diff --git a/test/test_irda.py b/test/test_irda.py index 46b627c..4552a26 100644 --- a/test/test_irda.py +++ b/test/test_irda.py @@ -10,11 +10,15 @@ import pytest @pytest.fixture def hgg1(): players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] - utilities = [[[-3, -1, -3, -2, -2, -3, -2, -1], - [-2, -4, -6, -2, -2, -7, -4, -5], - [-2, -3, -6, -4, -3, -1, -3, -4]], - [[-1, -3, -2, -2], [-2, -3, -3, -2]], - [[-3, -1, -4, -5], [-1, -3, -1, -5]]] + utilities = [ + [ + [-3, -1, -3, -2, -2, -3, -2, -1], + [-2, -4, -6, -2, -2, -7, -4, -5], + [-2, -3, -6, -4, -3, -1, -3, -4], + ], + [[-1, -3, -2, -2], [-2, -3, -3, -2]], + [[-3, -1, -4, -5], [-1, -3, -1, -5]], + ] hypergraph = [[0, 1, 2], [1, 3], [2, 3]] return HGG(players_actions, utilities, hypergraph) @@ -23,10 +27,17 @@ def hgg1(): def hgg2(): players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] utilities = [ - [[87, 77, 0, 49, 63, 99, 98, 25], [76, 100, 10, 43, 73, 65, 8, 56], - [8, 36, 3, 100, 24, 3, 64, 28]], - [[67, 38, 60, 64, 55, 100, 16, 13], [23, 59, 0, 9, 1, 8, 47, 33], - [9, 7, 100, 39, 16, 18, 16, 62]]] + [ + [87, 77, 0, 49, 63, 99, 98, 25], + [76, 100, 10, 43, 73, 65, 8, 56], + [8, 36, 3, 100, 24, 3, 64, 28], + ], + [ + [67, 38, 60, 64, 55, 100, 16, 13], + [23, 59, 0, 9, 1, 8, 47, 33], + [9, 7, 100, 39, 16, 18, 16, 62], + ], + ] hypergraph = [[0, 1, 2], [1, 2, 3]] return HGG(players_actions, utilities, hypergraph) @@ -35,10 +46,17 @@ def hgg2(): def hgg3(): players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] utilities = [ - [[29, 39, 100, 46, 40, 18, 97, 37], [23, 81, 64, 62, 90, 73, 76, 53], - [26, 36, 51, 5, 14, 99, 0, 54]], - [[12, 37, 7, 7, 41, 59, 27, 86], [65, 100, 100, 49, 97, 31, 68, 58], - [29, 70, 44, 61, 0, 53, 92, 74]]] + [ + [29, 39, 100, 46, 40, 18, 97, 37], + [23, 81, 64, 62, 90, 73, 76, 53], + [26, 36, 51, 5, 14, 99, 0, 54], + ], + [ + [12, 37, 7, 7, 41, 59, 27, 86], + [65, 100, 100, 49, 97, 31, 68, 58], + [29, 70, 44, 61, 0, 53, 92, 74], + ], + ] hypergraph = [[0, 2, 3], [1, 2, 3]] return HGG(players_actions, utilities, hypergraph) @@ -46,9 +64,11 @@ def hgg3(): @pytest.fixture def nfg1(): players_actions = [[0, 1], [0, 1], [0, 1]] - utilities = [[37, 63, 100, 69, 46, 60, 47, 41], - [24, 14, 79, 75, 100, 70, 34, 0], - [90, 34, 25, 25, 33, 68, 70, 3]] + utilities = [ + [37, 63, 100, 69, 46, 60, 47, 41], + [24, 14, 79, 75, 100, 70, 34, 0], + [90, 34, 25, 25, 33, 68, 70, 3], + ] return NFG(players_actions, utilities) @@ -58,22 +78,47 @@ def three_bg(): theta = [[0, 1], [0, 1], [0, 1]] all_p = [1, 2, 1, 4, 2, 2, 2, 6] utilities = [ - [[87, 56, 33, 21, 88, 77, 79, 69], [39, 52, 4, 92, 1, 78, 60, 69], - [2, 28, 92, 11, 16, 63, 21, 22]], - [[97, 12, 13, 92, 38, 2, 91, 62], [32, 40, 10, 57, 19, 18, 19, 15], - [35, 12, 0, 56, 93, 22, 52, 35]], - [[67, 0, 13, 87, 83, 6, 1, 80], [27, 63, 31, 22, 18, 8, 46, 81], - [88, 28, 35, 5, 52, 67, 21, 12]], - [[76, 13, 70, 36, 8, 39, 22, 42], [43, 82, 81, 37, 70, 58, 28, 91], - [13, 25, 6, 96, 31, 27, 5, 37]], - [[42, 62, 83, 91, 62, 11, 19, 0], [33, 88, 78, 14, 90, 27, 40, 86], - [29, 91, 63, 65, 78, 36, 3, 35]], - [[78, 51, 25, 64, 84, 53, 19, 30], [94, 8, 47, 52, 17, 89, 21, 54], - [39, 13, 7, 46, 4, 14, 46, 3]], - [[21, 33, 41, 4, 40, 5, 47, 13], [72, 6, 92, 29, 73, 54, 22, 30], - [23, 86, 14, 46, 99, 34, 62, 97]], - [[69, 11, 25, 65, 82, 52, 68, 56], [33, 12, 39, 98, 41, 63, 99, 10], - [18, 62, 99, 58, 62, 25, 55, 7]]] + [ + [87, 56, 33, 21, 88, 77, 79, 69], + [39, 52, 4, 92, 1, 78, 60, 69], + [2, 28, 92, 11, 16, 63, 21, 22], + ], + [ + [97, 12, 13, 92, 38, 2, 91, 62], + [32, 40, 10, 57, 19, 18, 19, 15], + [35, 12, 0, 56, 93, 22, 52, 35], + ], + [ + [67, 0, 13, 87, 83, 6, 1, 80], + [27, 63, 31, 22, 18, 8, 46, 81], + [88, 28, 35, 5, 52, 67, 21, 12], + ], + [ + [76, 13, 70, 36, 8, 39, 22, 42], + [43, 82, 81, 37, 70, 58, 28, 91], + [13, 25, 6, 96, 31, 27, 5, 37], + ], + [ + [42, 62, 83, 91, 62, 11, 19, 0], + [33, 88, 78, 14, 90, 27, 40, 86], + [29, 91, 63, 65, 78, 36, 3, 35], + ], + [ + [78, 51, 25, 64, 84, 53, 19, 30], + [94, 8, 47, 52, 17, 89, 21, 54], + [39, 13, 7, 46, 4, 14, 46, 3], + ], + [ + [21, 33, 41, 4, 40, 5, 47, 13], + [72, 6, 92, 29, 73, 54, 22, 30], + [23, 86, 14, 46, 99, 34, 62, 97], + ], + [ + [69, 11, 25, 65, 82, 52, 68, 56], + [33, 12, 39, 98, 41, 63, 99, 10], + [18, 62, 99, 58, 62, 25, 55, 7], + ], + ] return BG(players_actions, utilities, theta, all_p) @@ -81,54 +126,92 @@ def three_bg(): def bayesian_hgg1(): players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] theta = [[0, 1], [0, 1], [0, 1], [0, 1]] - utilities = [[[[39, 19, 95, 0, 32, 97, 65, 69], - [22, 40, 67, 14, 100, 60, 5, 34], - [46, 27, 72, 45, 18, 84, 100, 33]], - [[61, 96, 22, 34, 34, 35, 39, 54], - [39, 42, 77, 76, 27, 45, 56, 0], - [21, 94, 80, 74, 100, 20, 55, 65]], - [[34, 47, 56, 73, 55, 59, 31, 17], - [57, 43, 0, 23, 41, 100, 73, 86], - [24, 53, 95, 45, 38, 17, 28, 76]], - [[47, 37, 100, 6, 20, 16, 17, 59], - [40, 44, 64, 13, 0, 73, 76, 71], - [23, 52, 19, 70, 41, 43, 30, 28]], - [[53, 38, 44, 33, 9, 71, 31, 82], - [62, 100, 70, 65, 74, 22, 47, 59], - [66, 82, 20, 0, 15, 3, 57, 60]], - [[46, 33, 0, 31, 50, 50, 35, 50], - [26, 77, 56, 47, 37, 51, 56, 57], - [28, 27, 100, 21, 29, 26, 83, 25]], - [[70, 88, 0, 15, 7, 34, 100, 58], - [53, 68, 17, 17, 16, 26, 84, 61], - [63, 80, 10, 15, 11, 43, 84, 50]], - [[91, 49, 99, 85, 62, 38, 21, 87], - [18, 36, 74, 84, 40, 45, 39, 88], - [63, 54, 57, 100, 45, 20, 0, 76]]], - [[[72, 67, 47, 94, 73, 92, 80, 81], - [55, 66, 45, 62, 78, 91, 55, 53], - [54, 75, 47, 42, 0, 52, 47, 100]], - [[64, 79, 39, 7, 43, 22, 68, 26], - [48, 67, 62, 5, 74, 82, 77, 65], - [40, 65, 38, 0, 59, 69, 100, 86]], - [[44, 53, 46, 82, 44, 89, 69, 97], - [61, 96, 88, 93, 70, 20, 100, 46], - [31, 89, 0, 61, 48, 77, 84, 46]], - [[59, 74, 63, 100, 34, 31, 38, 45], - [55, 52, 83, 74, 10, 65, 5, 50], - [74, 64, 65, 96, 19, 70, 0, 38]], - [[32, 100, 0, 54, 5, 37, 45, 66], - [2, 23, 49, 3, 62, 21, 23, 44], - [11, 54, 67, 8, 37, 69, 83, 27]], - [[41, 67, 72, 12, 65, 74, 65, 53], - [68, 68, 57, 49, 0, 91, 80, 61], - [97, 78, 86, 100, 34, 62, 57, 87]], - [[52, 54, 63, 18, 37, 67, 75, 73], - [47, 65, 93, 91, 59, 60, 0, 43], - [82, 76, 49, 91, 100, 82, 95, 50]], - [[39, 19, 95, 0, 32, 97, 65, 69], - [22, 40, 67, 14, 100, 60, 5, 34], - [46, 27, 72, 45, 18, 84, 100, 33]]]] + utilities = [ + [ + [ + [39, 19, 95, 0, 32, 97, 65, 69], + [22, 40, 67, 14, 100, 60, 5, 34], + [46, 27, 72, 45, 18, 84, 100, 33], + ], + [ + [61, 96, 22, 34, 34, 35, 39, 54], + [39, 42, 77, 76, 27, 45, 56, 0], + [21, 94, 80, 74, 100, 20, 55, 65], + ], + [ + [34, 47, 56, 73, 55, 59, 31, 17], + [57, 43, 0, 23, 41, 100, 73, 86], + [24, 53, 95, 45, 38, 17, 28, 76], + ], + [ + [47, 37, 100, 6, 20, 16, 17, 59], + [40, 44, 64, 13, 0, 73, 76, 71], + [23, 52, 19, 70, 41, 43, 30, 28], + ], + [ + [53, 38, 44, 33, 9, 71, 31, 82], + [62, 100, 70, 65, 74, 22, 47, 59], + [66, 82, 20, 0, 15, 3, 57, 60], + ], + [ + [46, 33, 0, 31, 50, 50, 35, 50], + [26, 77, 56, 47, 37, 51, 56, 57], + [28, 27, 100, 21, 29, 26, 83, 25], + ], + [ + [70, 88, 0, 15, 7, 34, 100, 58], + [53, 68, 17, 17, 16, 26, 84, 61], + [63, 80, 10, 15, 11, 43, 84, 50], + ], + [ + [91, 49, 99, 85, 62, 38, 21, 87], + [18, 36, 74, 84, 40, 45, 39, 88], + [63, 54, 57, 100, 45, 20, 0, 76], + ], + ], + [ + [ + [72, 67, 47, 94, 73, 92, 80, 81], + [55, 66, 45, 62, 78, 91, 55, 53], + [54, 75, 47, 42, 0, 52, 47, 100], + ], + [ + [64, 79, 39, 7, 43, 22, 68, 26], + [48, 67, 62, 5, 74, 82, 77, 65], + [40, 65, 38, 0, 59, 69, 100, 86], + ], + [ + [44, 53, 46, 82, 44, 89, 69, 97], + [61, 96, 88, 93, 70, 20, 100, 46], + [31, 89, 0, 61, 48, 77, 84, 46], + ], + [ + [59, 74, 63, 100, 34, 31, 38, 45], + [55, 52, 83, 74, 10, 65, 5, 50], + [74, 64, 65, 96, 19, 70, 0, 38], + ], + [ + [32, 100, 0, 54, 5, 37, 45, 66], + [2, 23, 49, 3, 62, 21, 23, 44], + [11, 54, 67, 8, 37, 69, 83, 27], + ], + [ + [41, 67, 72, 12, 65, 74, 65, 53], + [68, 68, 57, 49, 0, 91, 80, 61], + [97, 78, 86, 100, 34, 62, 57, 87], + ], + [ + [52, 54, 63, 18, 37, 67, 75, 73], + [47, 65, 93, 91, 59, 60, 0, 43], + [82, 76, 49, 91, 100, 82, 95, 50], + ], + [ + [39, 19, 95, 0, 32, 97, 65, 69], + [22, 40, 67, 14, 100, 60, 5, 34], + [46, 27, 72, 45, 18, 84, 100, 33], + ], + ], + ] p = [[6, 9, 8, 6, 6, 4, 3, 3], [1, 7, 9, 1, 7, 3, 6, 9]] hypergraph = [[0, 1, 2], [0, 2, 3]] return BHGG(players_actions, utilities, hypergraph, theta, p) @@ -156,11 +239,15 @@ def test_irda1(hgg1): red_hgg, z_excluded = irda(hgg1) assert z_excluded == [(3, 1)] assert red_hgg.players_actions == [[0, 1], [0, 1], [0, 1], [0]] - assert red_hgg.utilities == [[[-3, -1, -3, -2, -2, -3, -2, -1], - [-2, -4, -6, -2, -2, -7, -4, -5], - [-2, -3, -6, -4, -3, -1, -3, -4]], - [[-1, -2], [-2, -3]], - [[-3, -4], [-1, -1]]] + assert red_hgg.utilities == [ + [ + [-3, -1, -3, -2, -2, -3, -2, -1], + [-2, -4, -6, -2, -2, -7, -4, -5], + [-2, -3, -6, -4, -3, -1, -3, -4], + ], + [[-1, -2], [-2, -3]], + [[-3, -4], [-1, -1]], + ] def test_irda2(hgg2): @@ -169,7 +256,8 @@ def test_irda2(hgg2): assert red_hgg.players_actions == [[0, 1], [0], [0, 1], [0]] assert red_hgg.utilities == [ [[87, 77, 63, 99], [76, 100, 73, 65], [8, 36, 24, 3]], - [[67, 60], [23, 0], [9, 100]]] + [[67, 60], [23, 0], [9, 100]], + ] def test_irda3(hgg3): @@ -177,9 +265,13 @@ def test_irda3(hgg3): assert set(z_excluded) == {(1, 0)} assert red_hgg.players_actions == [[0, 1], [1], [0, 1], [0, 1]] assert red_hgg.utilities == [ - [[29, 39, 100, 46, 40, 18, 97, 37], [23, 81, 64, 62, 90, 73, 76, 53], - [26, 36, 51, 5, 14, 99, 0, 54]], - [[41, 59, 27, 86], [97, 31, 68, 58], [0, 53, 92, 74]]] + [ + [29, 39, 100, 46, 40, 18, 97, 37], + [23, 81, 64, 62, 90, 73, 76, 53], + [26, 36, 51, 5, 14, 99, 0, 54], + ], + [[41, 59, 27, 86], [97, 31, 68, 58], [0, 53, 92, 74]], + ] def test_irda4(nfg1): @@ -193,8 +285,7 @@ def test_irda5(three_bg): tmp_hgg = three_bg.convert_to_HGG()[0] red_hgg, z_excluded = irda(tmp_hgg) assert set(z_excluded) == set([]) - assert red_hgg.players_actions == \ - [[0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1]] + assert red_hgg.players_actions == [[0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1]] assert red_hgg.utilities == tmp_hgg.utilities @@ -202,6 +293,14 @@ def test_irda6(bayesian_hgg1): tmp_hgg = bayesian_hgg1.convert_to_HGG()[0] red_hgg, z_excluded = irda(tmp_hgg) assert set(z_excluded) == set([]) - assert red_hgg.players_actions == [[0, 1], [0, 1], [0, 1], [0, 1], [0, 1], - [0, 1], [0, 1], [0, 1], ] + assert red_hgg.players_actions == [ + [0, 1], + [0, 1], + [0, 1], + [0, 1], + [0, 1], + [0, 1], + [0, 1], + [0, 1], + ] assert red_hgg.utilities == tmp_hgg.utilities diff --git a/test/test_lh_polymatrix.py b/test/test_lh_polymatrix.py index eaac248..d70b5c4 100644 --- a/test/test_lh_polymatrix.py +++ b/test/test_lh_polymatrix.py @@ -10,8 +10,11 @@ from fractions import Fraction @pytest.fixture def polym_3p(): - utilities = [[[2, 0, 3, 4], [0, 1, 5, 4]], [[3, 5, 1, 4], [4, 1, 1, 2]], - [[3, 2, 6, 7], [6, 5, 0, 3]]] + utilities = [ + [[2, 0, 3, 4], [0, 1, 5, 4]], + [[3, 5, 1, 4], [4, 1, 1, 2]], + [[3, 2, 6, 7], [6, 5, 0, 3]], + ] hypergraph = [[0, 1], [0, 2], [1, 2]] players_actions = [[0, 1], [0, 1], [0, 1]] return LHpolymatrix(PMG(players_actions, utilities, hypergraph)) @@ -21,20 +24,31 @@ def polym_3p(): def bayesian_polymatrix(): players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] theta = [[0, 1], [0, 1], [0, 1], [0, 1]] - same_game = [[[3, 0, 0, 2], [3, 0, 0, 2]], [[3, 0, 0, 2], [1, 0, 0, 2]], - [[1, 0, 0, 2], [3, 0, 0, 2]], [[1, 0, 0, 2], [1, 0, 0, 2]]] + same_game = [ + [[3, 0, 0, 2], [3, 0, 0, 2]], + [[3, 0, 0, 2], [1, 0, 0, 2]], + [[1, 0, 0, 2], [3, 0, 0, 2]], + [[1, 0, 0, 2], [1, 0, 0, 2]], + ] same_p = [4, 1, 1, 4] hypergr = [[0, 1], [1, 2], [2, 3], [0, 3]] - bhgg = BHGG(players_actions, [same_game, same_game, same_game, same_game], - hypergr, theta, [same_p, same_p, same_p, same_p]) + bhgg = BHGG( + players_actions, + [same_game, same_game, same_game, same_game], + hypergr, + theta, + [same_p, same_p, same_p, same_p], + ) return LHpolymatrix(bhgg.convert_to_HGG()[0]) @pytest.fixture def polym_3p3a(): - utilities = [[[8, 2, 5, 5, 1, 7, 1, 5, 1], [4, 1, 4, 5, 6, 2, 4, 7, 3]], - [[2, 2, 4, 7, 9, 4, 5, 5, 5], [2, 5, 4, 7, 1, 5, 2, 1, 6]], - [[9, 3, 4, 9, 5, 5, 9, 5, 4], [8, 8, 6, 9, 1, 4, 9, 1, 3]]] + utilities = [ + [[8, 2, 5, 5, 1, 7, 1, 5, 1], [4, 1, 4, 5, 6, 2, 4, 7, 3]], + [[2, 2, 4, 7, 9, 4, 5, 5, 5], [2, 5, 4, 7, 1, 5, 2, 1, 6]], + [[9, 3, 4, 9, 5, 5, 9, 5, 4], [8, 8, 6, 9, 1, 4, 9, 1, 3]], + ] hypergraph = [[0, 1], [0, 2], [1, 2]] players_actions = [[0, 1, 2], [0, 1, 2], [0, 1, 2]] return LHpolymatrix(PMG(players_actions, utilities, hypergraph)) @@ -42,8 +56,7 @@ def polym_3p3a(): @pytest.fixture def bimat_poly(): - utilities = [[[0, 6, 2, 5, 3, 3], - [1, 0, 0, 2, 4, 3]]] + utilities = [[[0, 6, 2, 5, 3, 3], [1, 0, 0, 2, 4, 3]]] hypergraph = [[0, 1]] players_actions = [[0, 1, 2], [0, 1]] return LHpolymatrix(PMG(players_actions, utilities, hypergraph)) @@ -55,8 +68,16 @@ def test_maxu_of_p1(polym_3p): def test_maxu_of_p2(bayesian_polymatrix): - assert bayesian_polymatrix.maxu_of_p == {0: 12, 1: 8, 2: 12, 3: 8, 4: 12, - 5: 8, 6: 12, 7: 8} + assert bayesian_polymatrix.maxu_of_p == { + 0: 12, + 1: 8, + 2: 12, + 3: 8, + 4: 12, + 5: 8, + 6: 12, + 7: 8, + } def test_maxu_of_p3(polym_3p3a): @@ -71,47 +92,82 @@ def test_all_utilities1(polym_3p): assert polym_3p.all_utilities == { 0: {1: [[2, 0], [3, 4]], 2: [[3, 5], [1, 4]]}, 1: {0: [[0, 5], [1, 4]], 2: [[3, 2], [6, 7]]}, - 2: {0: [[4, 1], [1, 2]], 1: [[6, 0], [5, 3]]}} + 2: {0: [[4, 1], [1, 2]], 1: [[6, 0], [5, 3]]}, + } def test_all_utilities2(polym_3p3a): assert polym_3p3a.all_utilities == { - 0: {1: [[8, 2, 5], [5, 1, 7], [1, 5, 1]], - 2: [[2, 2, 4], [7, 9, 4], [5, 5, 5]]}, - 1: {0: [[4, 5, 4], [1, 6, 7], [4, 2, 3]], - 2: [[9, 3, 4], [9, 5, 5], [9, 5, 4]]}, - 2: {0: [[2, 7, 2], [5, 1, 1], [4, 5, 6]], - 1: [[8, 9, 9], [8, 1, 1], [6, 4, 3]]}} + 0: {1: [[8, 2, 5], [5, 1, 7], [1, 5, 1]], 2: [[2, 2, 4], [7, 9, 4], [5, 5, 5]]}, + 1: {0: [[4, 5, 4], [1, 6, 7], [4, 2, 3]], 2: [[9, 3, 4], [9, 5, 5], [9, 5, 4]]}, + 2: {0: [[2, 7, 2], [5, 1, 1], [4, 5, 6]], 1: [[8, 9, 9], [8, 1, 1], [6, 4, 3]]}, + } def test_all_utilities3(bayesian_polymatrix): assert bayesian_polymatrix.all_utilities == { - 0: {2: [[12, 0], [0, 8]], 3: [[3, 0], [0, 2]], - 6: [[12, 0], [0, 8]], 7: [[3, 0], [0, 2]]}, - 1: {2: [[1, 0], [0, 2]], 3: [[4, 0], [0, 8]], - 6: [[1, 0], [0, 2]], 7: [[4, 0], [0, 8]]}, - 2: {0: [[12, 0], [0, 8]], 1: [[3, 0], [0, 2]], - 4: [[12, 0], [0, 8]], 5: [[3, 0], [0, 2]]}, - 3: {0: [[1, 0], [0, 2]], 1: [[4, 0], [0, 8]], - 4: [[1, 0], [0, 2]], 5: [[4, 0], [0, 8]]}, - 4: {2: [[12, 0], [0, 8]], 3: [[3, 0], [0, 2]], - 6: [[12, 0], [0, 8]], 7: [[3, 0], [0, 2]]}, - 5: {2: [[1, 0], [0, 2]], 3: [[4, 0], [0, 8]], - 6: [[1, 0], [0, 2]], 7: [[4, 0], [0, 8]]}, - 6: {0: [[12, 0], [0, 8]], 1: [[3, 0], [0, 2]], - 4: [[12, 0], [0, 8]], 5: [[3, 0], [0, 2]]}, - 7: {0: [[1, 0], [0, 2]], 1: [[4, 0], [0, 8]], - 4: [[1, 0], [0, 2]], 5: [[4, 0], [0, 8]]}} + 0: { + 2: [[12, 0], [0, 8]], + 3: [[3, 0], [0, 2]], + 6: [[12, 0], [0, 8]], + 7: [[3, 0], [0, 2]], + }, + 1: { + 2: [[1, 0], [0, 2]], + 3: [[4, 0], [0, 8]], + 6: [[1, 0], [0, 2]], + 7: [[4, 0], [0, 8]], + }, + 2: { + 0: [[12, 0], [0, 8]], + 1: [[3, 0], [0, 2]], + 4: [[12, 0], [0, 8]], + 5: [[3, 0], [0, 2]], + }, + 3: { + 0: [[1, 0], [0, 2]], + 1: [[4, 0], [0, 8]], + 4: [[1, 0], [0, 2]], + 5: [[4, 0], [0, 8]], + }, + 4: { + 2: [[12, 0], [0, 8]], + 3: [[3, 0], [0, 2]], + 6: [[12, 0], [0, 8]], + 7: [[3, 0], [0, 2]], + }, + 5: { + 2: [[1, 0], [0, 2]], + 3: [[4, 0], [0, 8]], + 6: [[1, 0], [0, 2]], + 7: [[4, 0], [0, 8]], + }, + 6: { + 0: [[12, 0], [0, 8]], + 1: [[3, 0], [0, 2]], + 4: [[12, 0], [0, 8]], + 5: [[3, 0], [0, 2]], + }, + 7: { + 0: [[1, 0], [0, 2]], + 1: [[4, 0], [0, 8]], + 4: [[1, 0], [0, 2]], + 5: [[4, 0], [0, 8]], + }, + } def test_all_utilities4(bimat_poly): - assert bimat_poly.all_utilities == {0: {1: [[0, 6], [2, 5], [3, 3]]}, - 1: {0: [[1, 0, 4], [0, 2, 3]]}} + assert bimat_poly.all_utilities == { + 0: {1: [[0, 6], [2, 5], [3, 3]]}, + 1: {0: [[1, 0, 4], [0, 2, 3]]}, + } # def test_inverse_utilities(polym_3p): # assert polym_3p.inverse_utilities == {} + def test_tucker_schema0(polym_3p): assert (polym_3p.tucker == np.zeros((9, 10))).all() @@ -130,41 +186,64 @@ def test_tucker_schema3(bimat_poly): def test_tucker_schema_meth1(polym_3p): polym_3p.tucker_schema() - assert (polym_3p.tucker == np.mat( - [[0, 0, 0, 4, 6, 3, 1, -1, 0, 0], [0, 0, 0, 3, 2, 5, 2, -1, 0, 0], - [0, 8, 3, 0, 0, 5, 6, 0, -1, 0], [0, 7, 4, 0, 0, 2, 1, 0, -1, 0], - [0, 3, 6, 1, 7, 0, 0, 0, 0, -1], [0, 6, 5, 2, 4, 0, 0, 0, 0, -1], - [-1, 1, 1, 0, 0, 0, 0, 0, 0, 0], - [-1, 0, 0, 1, 1, 0, 0, 0, 0, 0], - [-1, 0, 0, 0, 0, 1, 1, 0, 0, 0]], dtype=float)).all() + assert ( + polym_3p.tucker + == np.mat( + [ + [0, 0, 0, 4, 6, 3, 1, -1, 0, 0], + [0, 0, 0, 3, 2, 5, 2, -1, 0, 0], + [0, 8, 3, 0, 0, 5, 6, 0, -1, 0], + [0, 7, 4, 0, 0, 2, 1, 0, -1, 0], + [0, 3, 6, 1, 7, 0, 0, 0, 0, -1], + [0, 6, 5, 2, 4, 0, 0, 0, 0, -1], + [-1, 1, 1, 0, 0, 0, 0, 0, 0, 0], + [-1, 0, 0, 1, 1, 0, 0, 0, 0, 0], + [-1, 0, 0, 0, 0, 1, 1, 0, 0, 0], + ], + dtype=float, + ) + ).all() def test_tucker_schema_meth2(polym_3p3a): polym_3p3a.tucker_schema() - assert (polym_3p3a.tucker == np.mat( - [[0, 0, 0, 0, 2, 8, 5, 8, 8, 6, -1, 0, 0], - [0, 0, 0, 0, 5, 9, 3, 3, 1, 6, -1, 0, 0], - [0, 0, 0, 0, 9, 5, 9, 5, 5, 5, -1, 0, 0], - [0, 6, 5, 6, 0, 0, 0, 1, 7, 6, 0, -1, 0], - [0, 9, 4, 3, 0, 0, 0, 1, 5, 5, 0, -1, 0], - [0, 6, 8, 7, 0, 0, 0, 1, 5, 6, 0, -1, 0], - [0, 8, 3, 8, 2, 1, 1, 0, 0, 0, 0, 0, -1], - [0, 5, 9, 9, 2, 9, 9, 0, 0, 0, 0, 0, -1], - [0, 6, 5, 4, 4, 6, 7, 0, 0, 0, 0, 0, -1], - [-1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [-1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0], - [-1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0], ])).all() + assert ( + polym_3p3a.tucker + == np.mat( + [ + [0, 0, 0, 0, 2, 8, 5, 8, 8, 6, -1, 0, 0], + [0, 0, 0, 0, 5, 9, 3, 3, 1, 6, -1, 0, 0], + [0, 0, 0, 0, 9, 5, 9, 5, 5, 5, -1, 0, 0], + [0, 6, 5, 6, 0, 0, 0, 1, 7, 6, 0, -1, 0], + [0, 9, 4, 3, 0, 0, 0, 1, 5, 5, 0, -1, 0], + [0, 6, 8, 7, 0, 0, 0, 1, 5, 6, 0, -1, 0], + [0, 8, 3, 8, 2, 1, 1, 0, 0, 0, 0, 0, -1], + [0, 5, 9, 9, 2, 9, 9, 0, 0, 0, 0, 0, -1], + [0, 6, 5, 4, 4, 6, 7, 0, 0, 0, 0, 0, -1], + [-1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [-1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0], + [-1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0], + ] + ) + ).all() def test_tucker_schema_meth3(bimat_poly): bimat_poly.tucker_schema() - assert (bimat_poly.tucker == np.mat([[0, 0, 0, 0, 7, 1, -1, 0], - [0, 0, 0, 0, 5, 2, -1, 0], - [0, 0, 0, 0, 4, 4, -1, 0], - [0, 4, 5, 1, 0, 0, 0, -1], - [0, 5, 3, 2, 0, 0, 0, -1], - [-1, 1, 1, 1, 0, 0, 0, 0], - [-1, 0, 0, 0, 1, 1, 0, 0], ])).all() + assert ( + bimat_poly.tucker + == np.mat( + [ + [0, 0, 0, 0, 7, 1, -1, 0], + [0, 0, 0, 0, 5, 2, -1, 0], + [0, 0, 0, 0, 4, 4, -1, 0], + [0, 4, 5, 1, 0, 0, 0, -1], + [0, 5, 3, 2, 0, 0, 0, -1], + [-1, 1, 1, 1, 0, 0, 0, 0], + [-1, 0, 0, 0, 1, 1, 0, 0], + ] + ) + ).all() def test_launch_solver1(bimat_poly): @@ -175,8 +254,10 @@ def test_launch_solver1(bimat_poly): def test_launch_solver2(bimat_poly): sol = bimat_poly.launch_solver([0, 1]) - assert sol == {0: [Fraction(2, 3), Fraction(1, 3), 0], - 1: [Fraction(1, 3), Fraction(2, 3)]} + assert sol == { + 0: [Fraction(2, 3), Fraction(1, 3), 0], + 1: [Fraction(1, 3), Fraction(2, 3)], + } assert bimat_poly.currentgame.is_equilibrium(sol) diff --git a/test/test_normalformgame.py b/test/test_normalformgame.py index 7f88254..268ccf6 100644 --- a/test/test_normalformgame.py +++ b/test/test_normalformgame.py @@ -12,9 +12,11 @@ Separate assert in multiple fucntion @pytest.fixture def first_nfg(): players_actions = [[0, 1], [0, 1], [0, 1]] - utilities = [[-3, -7, -7, -10, -1, -5, -5, -9], - [-3, -7, -1, -5, -7, -10, -5, -9], - [-3, -1, -7, -5, -7, -5, -10, -9]] + utilities = [ + [-3, -7, -7, -10, -1, -5, -5, -9], + [-3, -7, -1, -5, -7, -10, -5, -9], + [-3, -1, -7, -5, -7, -5, -10, -9], + ] return NFG(players_actions, utilities) @@ -25,7 +27,8 @@ def second_nfg(): [51, 29, 47, 43, 75, 61, 42, 19, 28, 39, 40, 21, 60, 60, 67, 44], [58, 72, 31, 41, 37, 5, 37, 41, 53, 68, 38, 30, 58, 72, 75, 0], [29, 73, 42, 13, 34, 31, 54, 25, 47, 29, 19, 46, 85, 79, 65, 24], - [1, 17, 49, 9, 51, 25, 21, 49, 28, 77, 41, 69, 13, 100, 49, 27]] + [1, 17, 49, 9, 51, 25, 21, 49, 28, 77, 41, 69, 13, 100, 49, 27], + ] return NFG(players_actions, utilities) @@ -34,8 +37,11 @@ def third_nfg(): players_actions = [[0, 1], [0, 1], [0, 1]] # # util=[[79, 50, 98, 11, 17, 95, 46, 0], # [6, 5, 43, 38, 39, 65, 51, 19], [92, 86, 63, 100, 29, 48, 53, 68]] - util = [[86, 100, 87, 90, 1, 5, 0, 94], [16, 71, 4, 3, 4, 59, 66, 86], - [92, 0, 14, 65, 96, 45, 2, 51]] + util = [ + [86, 100, 87, 90, 1, 5, 0, 94], + [16, 71, 4, 3, 4, 59, 66, 86], + [92, 0, 14, 65, 96, 45, 2, 51], + ] return NFG(players_actions, util) @@ -48,123 +54,204 @@ def bimat_nfg(): # joint_actions def test_joint_actions1(first_nfg): - assert (first_nfg.joint_actions == np.mat( - [[0., 0., 0.], [0., 0., 1.], [0., 1., 0.], [0., 1., 1.], [1., 0., 0.], - [1., 0., 1.], [1., 1., 0.], [1., 1., 1.]])).all() + assert ( + first_nfg.joint_actions + == np.mat( + [ + [0.0, 0.0, 0.0], + [0.0, 0.0, 1.0], + [0.0, 1.0, 0.0], + [0.0, 1.0, 1.0], + [1.0, 0.0, 0.0], + [1.0, 0.0, 1.0], + [1.0, 1.0, 0.0], + [1.0, 1.0, 1.0], + ] + ) + ).all() def test_joint_actions2(second_nfg): - assert (second_nfg.joint_actions == np.mat( - [[0, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0], [0, 0, 1, 1], [0, 1, 0, 0], - [0, 1, 0, 1], [0, 1, 1, 0], [0, 1, 1, 1], [1, 0, 0, 0], [1, 0, 0, 1], - [1, 0, 1, 0], [1, 0, 1, 1], [1, 1, 0, 0], [1, 1, 0, 1], [1, 1, 1, 0], - [1, 1, 1, 1]])).all() + assert ( + second_nfg.joint_actions + == np.mat( + [ + [0, 0, 0, 0], + [0, 0, 0, 1], + [0, 0, 1, 0], + [0, 0, 1, 1], + [0, 1, 0, 0], + [0, 1, 0, 1], + [0, 1, 1, 0], + [0, 1, 1, 1], + [1, 0, 0, 0], + [1, 0, 0, 1], + [1, 0, 1, 0], + [1, 0, 1, 1], + [1, 1, 0, 0], + [1, 1, 0, 1], + [1, 1, 1, 0], + [1, 1, 1, 1], + ] + ) + ).all() def test_joint_actions3(bimat_nfg): - assert (bimat_nfg.joint_actions == np.mat( - [[0., 0.], [0., 1.], [1., 0.], [1., 1.], [2., 0.], [2., 1.]])).all() + assert ( + bimat_nfg.joint_actions + == np.mat( + [[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0], [2.0, 0.0], [2.0, 1.0]] + ) + ).all() # all_response_of_player def test_all_response_of_player1(first_nfg): - assert (first_nfg.all_response_of_player(0, [0, 0, 0]) == np.mat( - [[0., 0., 0.], [1., 0., 0.]])).all() + assert ( + first_nfg.all_response_of_player(0, [0, 0, 0]) + == np.mat([[0.0, 0.0, 0.0], [1.0, 0.0, 0.0]]) + ).all() def test_all_response_of_player2(first_nfg): - assert (first_nfg.all_response_of_player(1, [0, 0, 0]) == np.mat( - [[0., 0., 0.], [0., 1., 0.]])).all() + assert ( + first_nfg.all_response_of_player(1, [0, 0, 0]) + == np.mat([[0.0, 0.0, 0.0], [0.0, 1.0, 0.0]]) + ).all() def test_all_response_of_player3(first_nfg): - assert (first_nfg.all_response_of_player(2, [0, 0, 0]) == np.mat( - [[0., 0., 0.], [0., 0., 1.]])).all() + assert ( + first_nfg.all_response_of_player(2, [0, 0, 0]) + == np.mat([[0.0, 0.0, 0.0], [0.0, 0.0, 1.0]]) + ).all() def test_all_response_of_player4(first_nfg): - assert (first_nfg.all_response_of_player(0, [1, 1, 1]) == np.mat( - [[0., 1., 1.], [1., 1., 1.]])).all() + assert ( + first_nfg.all_response_of_player(0, [1, 1, 1]) + == np.mat([[0.0, 1.0, 1.0], [1.0, 1.0, 1.0]]) + ).all() def test_all_response_of_player5(first_nfg): - assert (first_nfg.all_response_of_player(1, [1, 1, 1]) == np.mat( - [[1., 0., 1.], [1., 1., 1.]])).all() + assert ( + first_nfg.all_response_of_player(1, [1, 1, 1]) + == np.mat([[1.0, 0.0, 1.0], [1.0, 1.0, 1.0]]) + ).all() def test_all_response_of_player6(first_nfg): - assert (first_nfg.all_response_of_player(2, [1, 1, 1]) == np.mat( - [[1., 1., 0.], [1., 1., 1.]])).all() + assert ( + first_nfg.all_response_of_player(2, [1, 1, 1]) + == np.mat([[1.0, 1.0, 0.0], [1.0, 1.0, 1.0]]) + ).all() def test_all_response_of_player7(first_nfg): - assert (first_nfg.all_response_of_player(0, [1, 1, 1]) == - first_nfg.all_response_of_player(0, [0, 1, 1])).all() + assert ( + first_nfg.all_response_of_player(0, [1, 1, 1]) + == first_nfg.all_response_of_player(0, [0, 1, 1]) + ).all() def test_all_response_of_player8(first_nfg): - assert (first_nfg.all_response_of_player(1, [1, 0, 0]) == - first_nfg.all_response_of_player(1, [1, 1, 0])).all() + assert ( + first_nfg.all_response_of_player(1, [1, 0, 0]) + == first_nfg.all_response_of_player(1, [1, 1, 0]) + ).all() def test_all_response_of_player9(first_nfg): - assert (first_nfg.all_response_of_player(2, [0, 1, 1]) == - first_nfg.all_response_of_player(2, [0, 1, 0])).all() + assert ( + first_nfg.all_response_of_player(2, [0, 1, 1]) + == first_nfg.all_response_of_player(2, [0, 1, 0]) + ).all() def test_all_response_of_player10(second_nfg): - assert (second_nfg.all_response_of_player(0, [0, 0, 0, 0]) == np.mat( - [[0., 0., 0., 0.], [1., 0., 0., 0.]])).all() + assert ( + second_nfg.all_response_of_player(0, [0, 0, 0, 0]) + == np.mat([[0.0, 0.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0]]) + ).all() def test_all_response_of_player11(second_nfg): - assert (second_nfg.all_response_of_player(1, [1, 0, 0, 1]) == np.mat( - [[1., 0., 0., 1.], [1., 1., 0., 1.]])).all() + assert ( + second_nfg.all_response_of_player(1, [1, 0, 0, 1]) + == np.mat([[1.0, 0.0, 0.0, 1.0], [1.0, 1.0, 0.0, 1.0]]) + ).all() def test_all_response_of_player12(second_nfg): - assert (second_nfg.all_response_of_player(2, [1, 1, 1, 1]) == np.mat( - [[1., 1., 0., 1.], [1., 1., 1., 1.]])).all() + assert ( + second_nfg.all_response_of_player(2, [1, 1, 1, 1]) + == np.mat([[1.0, 1.0, 0.0, 1.0], [1.0, 1.0, 1.0, 1.0]]) + ).all() def test_all_response_of_player13(bimat_nfg): - assert (bimat_nfg.all_response_of_player(0, [0, 0]) == np.mat( - [[0., 0.], [1., 0.], [2., 0.]])).all() + assert ( + bimat_nfg.all_response_of_player(0, [0, 0]) + == np.mat([[0.0, 0.0], [1.0, 0.0], [2.0, 0.0]]) + ).all() def test_all_response_of_player14(bimat_nfg): - assert (bimat_nfg.all_response_of_player(1, [0, 1]) == np.mat( - [[0., 0.], [0., 1.]])).all() + assert ( + bimat_nfg.all_response_of_player(1, [0, 1]) == np.mat([[0.0, 0.0], [0.0, 1.0]]) + ).all() def test_all_response_of_player15(bimat_nfg): - assert (bimat_nfg.all_response_of_player(1, [2, 0]) == np.mat( - [[2., 0.], [2., 1.]])).all() + assert ( + bimat_nfg.all_response_of_player(1, [2, 0]) == np.mat([[2.0, 0.0], [2.0, 1.0]]) + ).all() def test_all_response_of_player16(bimat_nfg): - assert (bimat_nfg.all_response_of_player(0, [0, 0]) == - bimat_nfg.all_response_of_player(0, [2, 0])).all() + assert ( + bimat_nfg.all_response_of_player(0, [0, 0]) + == bimat_nfg.all_response_of_player(0, [2, 0]) + ).all() def test_all_response_of_player17(bimat_nfg): - assert (bimat_nfg.all_response_of_player(0, [1, 0]) == - bimat_nfg.all_response_of_player(0, [2, 0])).all() + assert ( + bimat_nfg.all_response_of_player(0, [1, 0]) + == bimat_nfg.all_response_of_player(0, [2, 0]) + ).all() # joint_action_except_i + def test_joint_action_except_i1(first_nfg, second_nfg, bimat_nfg): for n in range(first_nfg.n_players): - assert (first_nfg.joint_action_except_i(n) == np.mat( - [[0., 0.], [0., 1.], [1., 0.], [1., 1.]])).all() + assert ( + first_nfg.joint_action_except_i(n) + == np.mat([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]]) + ).all() def test_joint_action_except_i2(second_nfg): for n in range(second_nfg.n_players): - assert (second_nfg.joint_action_except_i(n) == np.mat( - [[0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1], [1, 0, 0], [1, 0, 1], - [1, 1, 0], [1, 1, 1]])).all() + assert ( + second_nfg.joint_action_except_i(n) + == np.mat( + [ + [0, 0, 0], + [0, 0, 1], + [0, 1, 0], + [0, 1, 1], + [1, 0, 0], + [1, 0, 1], + [1, 1, 0], + [1, 1, 1], + ] + ) + ).all() def test_joint_action_except_i3(bimat_nfg): @@ -172,8 +259,7 @@ def test_joint_action_except_i3(bimat_nfg): def test_joint_action_except_i4(bimat_nfg): - assert (bimat_nfg.joint_action_except_i(1) == np.mat( - [[0], [1], [2]])).all() + assert (bimat_nfg.joint_action_except_i(1) == np.mat([[0], [1], [2]])).all() # get_sub_jointact_of_n @@ -181,53 +267,83 @@ def test_joint_action_except_i4(bimat_nfg): def test_get_sub_jointact_of_n1(first_nfg): - assert (first_nfg.get_sub_jointact_of_n(0) == [[0, 4], [1, 5], [2, 6], - [3, 7]]) + assert first_nfg.get_sub_jointact_of_n(0) == [[0, 4], [1, 5], [2, 6], [3, 7]] def test_get_sub_jointact_of_n2(first_nfg): - assert (first_nfg.get_sub_jointact_of_n(1) == [[0, 2], [1, 3], [4, 6], - [5, 7]]) + assert first_nfg.get_sub_jointact_of_n(1) == [[0, 2], [1, 3], [4, 6], [5, 7]] def test_get_sub_jointact_of_n3(first_nfg): - assert (first_nfg.get_sub_jointact_of_n(2) == [[0, 1], [2, 3], [4, 5], - [6, 7]]) + assert first_nfg.get_sub_jointact_of_n(2) == [[0, 1], [2, 3], [4, 5], [6, 7]] def test_get_sub_jointact_of_n4(bimat_nfg): - assert (bimat_nfg.get_sub_jointact_of_n(0) == [[0, 2, 4], [1, 3, 5]]) + assert bimat_nfg.get_sub_jointact_of_n(0) == [[0, 2, 4], [1, 3, 5]] def test_get_sub_jointact_of_n5(bimat_nfg): - assert (bimat_nfg.get_sub_jointact_of_n(1) == [[0, 1], [2, 3], [4, 5]]) + assert bimat_nfg.get_sub_jointact_of_n(1) == [[0, 1], [2, 3], [4, 5]] # disutilities + def test_disutilities1(first_nfg): - assert (first_nfg.disutilities == np.mat( - [[3, 3, 3], [7, 7, 1], [7, 1, 7], [10, 5, 5], [1, 7, 7], [5, 10, 5], - [5, 5, 10], [9, 9, 9]])).all() + assert ( + first_nfg.disutilities + == np.mat( + [ + [3, 3, 3], + [7, 7, 1], + [7, 1, 7], + [10, 5, 5], + [1, 7, 7], + [5, 10, 5], + [5, 5, 10], + [9, 9, 9], + ] + ) + ).all() def test_disutilities2(second_nfg): - assert (second_nfg.disutilities == np.mat( - [[25, 18, 57, 100], [47, 4, 13, 84], [29, 45, 44, 52], - [33, 35, 73, 92], [1, 39, 52, 50], [15, 71, 55, 76], [34, 39, 32, 80], - [57, 35, 61, 52], [48, 23, 39, 73], [37, 8, 57, 24], [36, 38, 67, 60], - [55, 46, 40, 32], [16, 18, 1, 88], [16, 4, 7, 1], [9, 1, 21, 52], - [32, 76, 62, 74]])).all() + assert ( + second_nfg.disutilities + == np.mat( + [ + [25, 18, 57, 100], + [47, 4, 13, 84], + [29, 45, 44, 52], + [33, 35, 73, 92], + [1, 39, 52, 50], + [15, 71, 55, 76], + [34, 39, 32, 80], + [57, 35, 61, 52], + [48, 23, 39, 73], + [37, 8, 57, 24], + [36, 38, 67, 60], + [55, 46, 40, 32], + [16, 18, 1, 88], + [16, 4, 7, 1], + [9, 1, 21, 52], + [32, 76, 62, 74], + ] + ) + ).all() def test_disutilities3(bimat_nfg): - assert (bimat_nfg.disutilities == np.mat( - [[4, 4], [4, 5], [5, 5], [2, 1], [7, 4], [1, 6]])).all() + assert ( + bimat_nfg.disutilities + == np.mat([[4, 4], [4, 5], [5, 5], [2, 1], [7, 4], [1, 6]]) + ).all() # row_where_p_is_i # No second_nfg + def test_row_where_p_is_i1(first_nfg, second_nfg, bimat_nfg): assert (first_nfg.row_where_p_is_i(0, 0) == np.mat([0, 1, 2, 3])).all() @@ -303,6 +419,7 @@ def test_util_of_row6(bimat_nfg): # disutil_of_row # no second_nfg + def test_disutil_of_row1(first_nfg): for n in range(first_nfg.n_players): assert (first_nfg.disutil_of_row(n, 0) == np.mat([3, 7, 7, 10])).all() @@ -335,53 +452,73 @@ def test_disutil_of_row6(bimat_nfg): # expected_utilities # no second_nfg def test_expected_utilities1(first_nfg): - assert (first_nfg.expected_utilities( - {0: [1, 0], 1: [1, 0], 2: [1, 0]}) == np.mat([-3, -3, -3])).all() + assert ( + first_nfg.expected_utilities({0: [1, 0], 1: [1, 0], 2: [1, 0]}) + == np.mat([-3, -3, -3]) + ).all() def test_expected_utilities2(first_nfg): - assert (first_nfg.expected_utilities( - {0: [1, 0], 1: [0, 1], 2: [1, 0]}) == np.mat([-7, -1, -7])).all() + assert ( + first_nfg.expected_utilities({0: [1, 0], 1: [0, 1], 2: [1, 0]}) + == np.mat([-7, -1, -7]) + ).all() def test_expected_utilities3(first_nfg): - assert (first_nfg.expected_utilities( - {0: [0, 1], 1: [0, 1], 2: [0, 1]}) == np.mat([-9, -9, -9])).all() + assert ( + first_nfg.expected_utilities({0: [0, 1], 1: [0, 1], 2: [0, 1]}) + == np.mat([-9, -9, -9]) + ).all() def test_expected_utilities4(first_nfg): - assert (first_nfg.expected_utilities( - {0: [1 / 2, 1 / 2], 1: [1 / 2, 1 / 2], 2: [1 / 2, 1 / 2]}) == np.mat( - [-5.875, -5.875, -5.875])).all() + assert ( + first_nfg.expected_utilities( + {0: [1 / 2, 1 / 2], 1: [1 / 2, 1 / 2], 2: [1 / 2, 1 / 2]} + ) + == np.mat([-5.875, -5.875, -5.875]) + ).all() def test_expected_utilities5(bimat_nfg): - assert (bimat_nfg.expected_utilities({0: [1, 0, 0], 1: [1, 0]}) == np.mat( - [3, 3])).all() + assert ( + bimat_nfg.expected_utilities({0: [1, 0, 0], 1: [1, 0]}) == np.mat([3, 3]) + ).all() def test_expected_utilities6(bimat_nfg): - assert (bimat_nfg.expected_utilities({0: [0, 0, 1], 1: [0, 1]}) == np.mat( - [6, 1])).all() + assert ( + bimat_nfg.expected_utilities({0: [0, 0, 1], 1: [0, 1]}) == np.mat([6, 1]) + ).all() def test_expected_utilities7(bimat_nfg): - assert (bimat_nfg.expected_utilities({0: [0, 1, 0], 1: [1, 0]}) == np.mat( - [2, 2])).all() + assert ( + bimat_nfg.expected_utilities({0: [0, 1, 0], 1: [1, 0]}) == np.mat([2, 2]) + ).all() def test_expected_utilities8(bimat_nfg): - assert (bimat_nfg.expected_utilities( - {0: [Fraction(1, 3), Fraction(1, 3), Fraction(1, 3)], - 1: [Fraction(1, 2), Fraction(1, 2)]}) == np.mat( - [Fraction(19, 6), Fraction(17, 6)])).all() + assert ( + bimat_nfg.expected_utilities( + { + 0: [Fraction(1, 3), Fraction(1, 3), Fraction(1, 3)], + 1: [Fraction(1, 2), Fraction(1, 2)], + } + ) + == np.mat([Fraction(19, 6), Fraction(17, 6)]) + ).all() # is_equilibrium # No second/bimat def test_is_equilibrium1(first_nfg): - assert not (first_nfg.is_equilibrium( - {0: [1 / 2, 1 / 2], 1: [1 / 2, 1 / 2], 2: [1 / 2, 1 / 2]})) + assert not ( + first_nfg.is_equilibrium( + {0: [1 / 2, 1 / 2], 1: [1 / 2, 1 / 2], 2: [1 / 2, 1 / 2]} + ) + ) # def test_error_equilibrium1(first_nfg): @@ -391,8 +528,9 @@ def test_is_equilibrium1(first_nfg): # def test_error_equilibrium2(first_nfg): # assert first_nfg.error_equilibrium({0: [0, 1], 1: [0, 1], 2: [0, 1]})==0 + def test_is_equilibrium2(first_nfg): - assert (first_nfg.is_equilibrium({0: [0, 1], 1: [0, 1], 2: [0, 1]})) + assert first_nfg.is_equilibrium({0: [0, 1], 1: [0, 1], 2: [0, 1]}) def test_is_equilibrium3(first_nfg): @@ -408,7 +546,7 @@ def test_is_equilibrium4(first_nfg): def test_is_pure_equilibrium1(first_nfg): - assert (first_nfg.is_pure_equilibrium([1, 1, 1])) + assert first_nfg.is_pure_equilibrium([1, 1, 1]) def test_is_pure_equilibrium2(first_nfg): @@ -420,19 +558,19 @@ def test_is_pure_equilibrium3(first_nfg): def test_get_all_PNE1(first_nfg): - assert (first_nfg.get_all_PNE() == [{0: [0, 1], 1: [0, 1], 2: [0, 1]}]) + assert first_nfg.get_all_PNE() == [{0: [0, 1], 1: [0, 1], 2: [0, 1]}] def test_get_all_PNE2(second_nfg): - assert (second_nfg.get_all_PNE() == []) + assert second_nfg.get_all_PNE() == [] def test_get_all_PNE3(bimat_nfg): - assert (bimat_nfg.get_all_PNE() == [{0: [1, 0, 0], 1: [1, 0]}]) + assert bimat_nfg.get_all_PNE() == [{0: [1, 0, 0], 1: [1, 0]}] def test_pne_exist1(first_nfg, second_nfg, bimat_nfg): - assert (first_nfg.pne_exist()) + assert first_nfg.pne_exist() def test_pne_exist2(second_nfg): @@ -440,21 +578,22 @@ def test_pne_exist2(second_nfg): def test_pne_exist3(bimat_nfg): - assert (bimat_nfg.pne_exist()) + assert bimat_nfg.pne_exist() # get_all_PNE + def test_first_pne1(first_nfg, second_nfg, bimat_nfg): - assert (first_nfg.first_pne() == {0: [0, 1], 1: [0, 1], 2: [0, 1]}) + assert first_nfg.first_pne() == {0: [0, 1], 1: [0, 1], 2: [0, 1]} def test_first_pne2(second_nfg): - assert (second_nfg.first_pne() == {}) + assert second_nfg.first_pne() == {} def test_first_pne3(bimat_nfg): - assert (bimat_nfg.first_pne() == {0: [1, 0, 0], 1: [1, 0]}) + assert bimat_nfg.first_pne() == {0: [1, 0, 0], 1: [1, 0]} # def test_build_subgame(first_nfg,second_nfg,bimat_nfg): @@ -467,37 +606,56 @@ def test_first_pne3(bimat_nfg): # build_subgame # no second_nfg + def test_build_subgame1(first_nfg, second_nfg, bimat_nfg): sub_first1 = first_nfg.build_subgame({2: [0, 1]}) - assert (sub_first1.players_actions == [[0, 1], [0, 1], [-1]] and - sub_first1.utilities == [[-7, -10, -5, -9], [-7, -5, -10, -9], - [-1, -5, -5, -9]]) + assert sub_first1.players_actions == [ + [0, 1], + [0, 1], + [-1], + ] and sub_first1.utilities == [ + [-7, -10, -5, -9], + [-7, -5, -10, -9], + [-1, -5, -5, -9], + ] def test_build_subgame2(first_nfg): sub_first2 = first_nfg.build_subgame({0: [1, 0], 1: [0, 1]}) - assert (sub_first2.players_actions == [[-1], [-1], [0, 1]] and - sub_first2.utilities == [[-7, -10], [-1, -5], [-7, -5]]) + assert sub_first2.players_actions == [ + [-1], + [-1], + [0, 1], + ] and sub_first2.utilities == [[-7, -10], [-1, -5], [-7, -5]] def test_build_subgame3(first_nfg): sub_first_mixed = first_nfg.build_subgame({2: [1 / 2, 1 / 2]}) - assert (sub_first_mixed.players_actions == [[0, 1], [0, 1], [-1]] and - sub_first_mixed.utilities == [[-5, -8.5, -3, -7], - [-5, -3, -8.5, -7], - [-2, -6, -6, -9.5]]) + assert sub_first_mixed.players_actions == [ + [0, 1], + [0, 1], + [-1], + ] and sub_first_mixed.utilities == [ + [-5, -8.5, -3, -7], + [-5, -3, -8.5, -7], + [-2, -6, -6, -9.5], + ] def test_build_subgame4(bimat_nfg): sub_bimat1 = bimat_nfg.build_subgame({1: [1, 0]}) - assert (sub_bimat1.players_actions == [[0, 1, 2], [-1]] and - sub_bimat1.utilities == [[3, 2, 0], [3, 2, 3]]) + assert sub_bimat1.players_actions == [[0, 1, 2], [-1]] and sub_bimat1.utilities == [ + [3, 2, 0], + [3, 2, 3], + ] def test_build_subgame5(bimat_nfg): sub_bimat2 = bimat_nfg.build_subgame({0: [1, 0, 0]}) - assert (sub_bimat2.players_actions == [[-1], [0, 1]] and - sub_bimat2.utilities == [[3, 3], [3, 2]]) + assert sub_bimat2.players_actions == [[-1], [0, 1]] and sub_bimat2.utilities == [ + [3, 3], + [3, 2], + ] # get_subgame_level @@ -506,43 +664,53 @@ def test_build_subgame5(bimat_nfg): def test_get_subgame_level1(first_nfg): sub_level_first_nfg1 = first_nfg.get_subgame_level( - {0: [0, 1], 1: [0, 1], 2: [0, 1]}) - assert (sub_level_first_nfg1.players_actions == [[0, 1], [0, 1]] and - sub_level_first_nfg1.utilities == [[-7, -10, -5, -9], - [-7, -5, -10, -9]]) + {0: [0, 1], 1: [0, 1], 2: [0, 1]} + ) + assert sub_level_first_nfg1.players_actions == [ + [0, 1], + [0, 1], + ] and sub_level_first_nfg1.utilities == [[-7, -10, -5, -9], [-7, -5, -10, -9]] def test_get_subgame_level2(first_nfg): sub_level_first_mixed = first_nfg.get_subgame_level( - {0: [0, 1], 1: [1, 0], 2: [1 / 2, 1 / 2]}) - assert (sub_level_first_mixed.players_actions == [[0, 1], [0, 1]] and - sub_level_first_mixed.utilities == [[-5, -8.5, -3, -7], - [-5, -3, -8.5, -7]]) + {0: [0, 1], 1: [1, 0], 2: [1 / 2, 1 / 2]} + ) + assert sub_level_first_mixed.players_actions == [ + [0, 1], + [0, 1], + ] and sub_level_first_mixed.utilities == [[-5, -8.5, -3, -7], [-5, -3, -8.5, -7]] def test_get_subgame_level3(bimat_nfg): sub_level_bimat1 = bimat_nfg.get_subgame_level({0: [0, 1, 0], 1: [1, 0]}) - assert (sub_level_bimat1.players_actions == [[0, 1, 2]] and - sub_level_bimat1.utilities == [[3, 2, 0]]) + assert sub_level_bimat1.players_actions == [ + [0, 1, 2] + ] and sub_level_bimat1.utilities == [[3, 2, 0]] # get_subgame_without_n # no second_nfg, bimat + def test_get_subgame_without_n1(first_nfg): sub_level_first_nfg1 = first_nfg.get_subgame_without_n( - {0: [0, 1], 1: [0, 1], 2: [0, 1]}, 2) - assert (sub_level_first_nfg1.players_actions == [[0, 1], [0, 1]] and - sub_level_first_nfg1.utilities == [[-7, -10, -5, -9], - [-7, -5, -10, -9]]) + {0: [0, 1], 1: [0, 1], 2: [0, 1]}, 2 + ) + assert sub_level_first_nfg1.players_actions == [ + [0, 1], + [0, 1], + ] and sub_level_first_nfg1.utilities == [[-7, -10, -5, -9], [-7, -5, -10, -9]] def test_get_subgame_without_n2(first_nfg): sub_level_first_nfg2 = first_nfg.get_subgame_without_n( - {0: [1, 0], 1: [0, 1], 2: [0, 1]}, 0) - assert (sub_level_first_nfg2.players_actions == [[0, 1], [0, 1]] and - sub_level_first_nfg2.utilities == [[-3, -7, -1, -5], - [-3, -1, -7, -5]]) + {0: [1, 0], 1: [0, 1], 2: [0, 1]}, 0 + ) + assert sub_level_first_nfg2.players_actions == [ + [0, 1], + [0, 1], + ] and sub_level_first_nfg2.utilities == [[-3, -7, -1, -5], [-3, -1, -7, -5]] """ @@ -568,36 +736,47 @@ readNFGpayoff # get_subgame_fixed_strat # no second_nfg + def test_get_subgame_fixed_strat1(first_nfg): sub_first_nfg1 = first_nfg.get_subgame_fixed_strat( - {0: [1, 1], 1: [1, 1], 2: [1, 0]}) - assert (sub_first_nfg1.players_actions == [[0, 1], [0, 1], [ - 0]] and sub_first_nfg1.utilities == [[-3, -7, -1, -5], - [-3, -1, -7, -5], - [-3, -7, -7, -10]]) + {0: [1, 1], 1: [1, 1], 2: [1, 0]} + ) + assert sub_first_nfg1.players_actions == [ + [0, 1], + [0, 1], + [0], + ] and sub_first_nfg1.utilities == [ + [-3, -7, -1, -5], + [-3, -1, -7, -5], + [-3, -7, -7, -10], + ] def test_get_subgame_fixed_strat2(first_nfg): sub_first_nfg2 = first_nfg.get_subgame_fixed_strat( - {0: [0, 1], 1: [0, 1], 2: [0, 1]}) - assert (sub_first_nfg2.players_actions == [[1], [1], [ - 1]] and sub_first_nfg2.utilities == [[-9], [-9], [-9]]) + {0: [0, 1], 1: [0, 1], 2: [0, 1]} + ) + assert sub_first_nfg2.players_actions == [ + [1], + [1], + [1], + ] and sub_first_nfg2.utilities == [[-9], [-9], [-9]] def test_get_subgame_fixed_strat3(bimat_nfg): - sub_bimat_nfg1 = bimat_nfg.get_subgame_fixed_strat( - {0: [1, 1, 0], 1: [1, 1]}) - assert ( - sub_bimat_nfg1.players_actions == - [[0, 1], [0, 1]] and sub_bimat_nfg1.utilities == - [[3, 3, 2, 5], [3, 2, 2, 6]]) + sub_bimat_nfg1 = bimat_nfg.get_subgame_fixed_strat({0: [1, 1, 0], 1: [1, 1]}) + assert sub_bimat_nfg1.players_actions == [ + [0, 1], + [0, 1], + ] and sub_bimat_nfg1.utilities == [[3, 3, 2, 5], [3, 2, 2, 6]] def test_get_subgame_fixed_strat4(bimat_nfg): - sub_bimat_nfg2 = bimat_nfg.get_subgame_fixed_strat( - {0: [0, 1, 1], 1: [1, 0]}) - assert (sub_bimat_nfg2.players_actions == [[1, 2], [ - 0]] and sub_bimat_nfg2.utilities == [[2, 0], [2, 3]]) + sub_bimat_nfg2 = bimat_nfg.get_subgame_fixed_strat({0: [0, 1, 1], 1: [1, 0]}) + assert sub_bimat_nfg2.players_actions == [ + [1, 2], + [0], + ] and sub_bimat_nfg2.utilities == [[2, 0], [2, 3]] def test_readNFGpayoff1(): @@ -609,20 +788,21 @@ def test_readNFGpayoff1(): def test_readNFGpayoff2(): read_game = NFG.readNFGpayoff("filestest/RandG_0.nfg") assert read_game.players_actions == [[0, 1], [0, 1], [0, 1]] - assert read_game.utilities == [[43, 38, 1, 63, 61, 21, 12, 46], - [89, 35, 0, 88, 87, 68, 24, 22], - [72, 92, 61, 71, 95, 2, 4, 100]] + assert read_game.utilities == [ + [43, 38, 1, 63, 61, 21, 12, 46], + [89, 35, 0, 88, 87, 68, 24, 22], + [72, 92, 61, 71, 95, 2, 4, 100], + ] def test_readNFGpayoff3(): read_game = NFG.readNFGpayoff("filestest/custom_game1.nfg") assert read_game.players_actions == [[0, 1, 2], [0, 1, 2], [0, 1]] assert read_game.utilities == [ - [91, 49, 69, 98, 95, 15, 70, 59, 68, 52, 45, 22, 14, 37, 54, 58, 41, - 92], - [71, 89, 23, 47, 26, 17, 94, 99, 49, 55, 22, 72, 70, 85, 85, 82, 38, - 62], - [54, 39, 53, 50, 66, 55, 8, 59, 49, 40, 67, 19, 7, 39, 14, 62, 80, 76]] + [91, 49, 69, 98, 95, 15, 70, 59, 68, 52, 45, 22, 14, 37, 54, 58, 41, 92], + [71, 89, 23, 47, 26, 17, 94, 99, 49, 55, 22, 72, 70, 85, 85, 82, 38, 62], + [54, 39, 53, 50, 66, 55, 8, 59, 49, 40, 67, 19, 7, 39, 14, 62, 80, 76], + ] def test_readNFGpayoff4(): diff --git a/test/test_pns.py b/test/test_pns.py index 5d432ae..7557e06 100644 --- a/test/test_pns.py +++ b/test/test_pns.py @@ -4,8 +4,7 @@ from gtnash.game.normalformgame import NFG from gtnash.game.hypergraphicalgame import HGG from fractions import Fraction from gtnash.util.irda import irda -from gtnash.solver.pns import PNS_solver,\ - unbalance_partitions, allbalancedsupports +from gtnash.solver.pns import PNS_solver, unbalance_partitions, allbalancedsupports """ PNS_solver @@ -68,115 +67,205 @@ def test_unbalance_partitions6(): # for i in allbalancedsupports([[0, 1, 2], [0, 1], [0, 1, 2]]): # print(i) + def test_allbalancedsupports1(): - all_support = [({0}, {0}, {0}), ({0}, {0}, {1}), ({0}, {1}, {0}), - ({0}, {1}, {1}), ({1}, {0}, {0}), ({1}, {0}, {1}), - ({1}, {1}, {0}), ({1}, {1}, {1}), ({0, 1}, {0}, {0}), - ({0, 1}, {0}, {1}), ({0, 1}, {1}, {0}), ({0, 1}, {1}, {1}), - ({0}, {0, 1}, {0}), ({0}, {0, 1}, {1}), ({1}, {0, 1}, {0}), - ({1}, {0, 1}, {1}), ({0}, {0}, {0, 1}), ({0}, {1}, {0, 1}), - ({1}, {0}, {0, 1}), ({1}, {1}, {0, 1}), - ({0, 1}, {0, 1}, {0}), - ({0, 1}, {0, 1}, {1}), ({0, 1}, {0}, {0, 1}), - ({0, 1}, {1}, {0, 1}), - ({0}, {0, 1}, {0, 1}), ({1}, {0, 1}, {0, 1}), - ({0, 1}, {0, 1}, {0, 1})] + all_support = [ + ({0}, {0}, {0}), + ({0}, {0}, {1}), + ({0}, {1}, {0}), + ({0}, {1}, {1}), + ({1}, {0}, {0}), + ({1}, {0}, {1}), + ({1}, {1}, {0}), + ({1}, {1}, {1}), + ({0, 1}, {0}, {0}), + ({0, 1}, {0}, {1}), + ({0, 1}, {1}, {0}), + ({0, 1}, {1}, {1}), + ({0}, {0, 1}, {0}), + ({0}, {0, 1}, {1}), + ({1}, {0, 1}, {0}), + ({1}, {0, 1}, {1}), + ({0}, {0}, {0, 1}), + ({0}, {1}, {0, 1}), + ({1}, {0}, {0, 1}), + ({1}, {1}, {0, 1}), + ({0, 1}, {0, 1}, {0}), + ({0, 1}, {0, 1}, {1}), + ({0, 1}, {0}, {0, 1}), + ({0, 1}, {1}, {0, 1}), + ({0}, {0, 1}, {0, 1}), + ({1}, {0, 1}, {0, 1}), + ({0, 1}, {0, 1}, {0, 1}), + ] for s_i, s in enumerate(allbalancedsupports([[0, 1], [0, 1], [0, 1]])): assert s == all_support[s_i] def test_allbalancedsupports2(): - all_support = [({0}, {0}, {0}), ({0}, {0}, {1}), ({0}, {0}, {2}), - ({0}, {1}, {0}), - ({0}, {1}, {1}), ({0}, {1}, {2}), ({1}, {0}, {0}), - ({1}, {0}, {1}), - ({1}, {0}, {2}), ({1}, {1}, {0}), ({1}, {1}, {1}), - ({1}, {1}, {2}), - ({2}, {0}, {0}), ({2}, {0}, {1}), ({2}, {0}, {2}), - ({2}, {1}, {0}), - ({2}, {1}, {1}), ({2}, {1}, {2}), ({0, 1}, {0}, {0}), - ({0, 1}, {0}, {1}), - ({0, 1}, {0}, {2}), ({0, 1}, {1}, {0}), ({0, 1}, {1}, {1}), - ({0, 1}, {1}, {2}), - ({0, 2}, {0}, {0}), ({0, 2}, {0}, {1}), ({0, 2}, {0}, {2}), - ({0, 2}, {1}, {0}), - ({0, 2}, {1}, {1}), ({0, 2}, {1}, {2}), ({1, 2}, {0}, {0}), - ({1, 2}, {0}, {1}), - ({1, 2}, {0}, {2}), ({1, 2}, {1}, {0}), ({1, 2}, {1}, {1}), - ({1, 2}, {1}, {2}), - ({0}, {0, 1}, {0}), ({0}, {0, 1}, {1}), ({0}, {0, 1}, {2}), - ({1}, {0, 1}, {0}), - ({1}, {0, 1}, {1}), ({1}, {0, 1}, {2}), ({2}, {0, 1}, {0}), - ({2}, {0, 1}, {1}), - ({2}, {0, 1}, {2}), ({0}, {0}, {0, 1}), ({0}, {0}, {0, 2}), - ({0}, {0}, {1, 2}), - ({0}, {1}, {0, 1}), ({0}, {1}, {0, 2}), ({0}, {1}, {1, 2}), - ({1}, {0}, {0, 1}), - ({1}, {0}, {0, 2}), ({1}, {0}, {1, 2}), ({1}, {1}, {0, 1}), - ({1}, {1}, {0, 2}), - ({1}, {1}, {1, 2}), ({2}, {0}, {0, 1}), ({2}, {0}, {0, 2}), - ({2}, {0}, {1, 2}), - ({2}, {1}, {0, 1}), ({2}, {1}, {0, 2}), ({2}, {1}, {1, 2}), - ({0, 1}, {0, 1}, {0}), - ({0, 1}, {0, 1}, {1}), ({0, 1}, {0, 1}, {2}), - ({0, 2}, {0, 1}, {0}), ({0, 2}, {0, 1}, {1}), - ({0, 2}, {0, 1}, {2}), ({1, 2}, {0, 1}, {0}), - ({1, 2}, {0, 1}, {1}), ({1, 2}, {0, 1}, {2}), - ({0, 1}, {0}, {0, 1}), ({0, 1}, {0}, {0, 2}), - ({0, 1}, {0}, {1, 2}), ({0, 1}, {1}, {0, 1}), - ({0, 1}, {1}, {0, 2}), ({0, 1}, {1}, {1, 2}), - ({0, 2}, {0}, {0, 1}), ({0, 2}, {0}, {0, 2}), - ({0, 2}, {0}, {1, 2}), ({0, 2}, {1}, {0, 1}), - ({0, 2}, {1}, {0, 2}), ({0, 2}, {1}, {1, 2}), - ({1, 2}, {0}, {0, 1}), ({1, 2}, {0}, {0, 2}), - ({1, 2}, {0}, {1, 2}), ({1, 2}, {1}, {0, 1}), - ({1, 2}, {1}, {0, 2}), ({1, 2}, {1}, {1, 2}), - ({0}, {0, 1}, {0, 1}), ({0}, {0, 1}, {0, 2}), - ({0}, {0, 1}, {1, 2}), ({1}, {0, 1}, {0, 1}), - ({1}, {0, 1}, {0, 2}), ({1}, {0, 1}, {1, 2}), - ({2}, {0, 1}, {0, 1}), ({2}, {0, 1}, {0, 2}), - ({2}, {0, 1}, {1, 2}), ({0, 1, 2}, {0}, {0}), - ({0, 1, 2}, {0}, {1}), ({0, 1, 2}, {0}, {2}), - ({0, 1, 2}, {1}, {0}), ({0, 1, 2}, {1}, {1}), - ({0, 1, 2}, {1}, {2}), ({0}, {0}, {0, 1, 2}), - ({0}, {1}, {0, 1, 2}), ({1}, {0}, {0, 1, 2}), - ({1}, {1}, {0, 1, 2}), ({2}, {0}, {0, 1, 2}), - ({2}, {1}, {0, 1, 2}), ({0, 1}, {0, 1}, {0, 1}), - ({0, 1}, {0, 1}, {0, 2}), ({0, 1}, {0, 1}, {1, 2}), - ({0, 2}, {0, 1}, {0, 1}), - ({0, 2}, {0, 1}, {0, 2}), - ({0, 2}, {0, 1}, {1, 2}), ({1, 2}, {0, 1}, {0, 1}), - ({1, 2}, {0, 1}, {0, 2}), - ({1, 2}, {0, 1}, {1, 2}), - ({0, 1, 2}, {0, 1}, {0}), ({0, 1, 2}, {0, 1}, {1}), - ({0, 1, 2}, {0, 1}, {2}), - ({0, 1, 2}, {0}, {0, 1}), - ({0, 1, 2}, {0}, {0, 2}), ({0, 1, 2}, {0}, {1, 2}), - ({0, 1, 2}, {1}, {0, 1}), - ({0, 1, 2}, {1}, {0, 2}), - ({0, 1, 2}, {1}, {1, 2}), ({0, 1}, {0}, {0, 1, 2}), - ({0, 1}, {1}, {0, 1, 2}), - ({0, 2}, {0}, {0, 1, 2}), - ({0, 2}, {1}, {0, 1, 2}), ({1, 2}, {0}, {0, 1, 2}), - ({1, 2}, {1}, {0, 1, 2}), - ({0}, {0, 1}, {0, 1, 2}), - ({1}, {0, 1}, {0, 1, 2}), ({2}, {0, 1}, {0, 1, 2}), - ({0, 1, 2}, {0, 1}, {0, 1}), - ({0, 1, 2}, {0, 1}, {0, 2}), - ({0, 1, 2}, {0, 1}, {1, 2}), ({0, 1}, {0, 1}, {0, 1, 2}), - ({0, 2}, {0, 1}, {0, 1, 2}), - ({1, 2}, {0, 1}, {0, 1, 2}), - ({0, 1, 2}, {0}, {0, 1, 2}), ({0, 1, 2}, {1}, {0, 1, 2}), - ({0, 1, 2}, {0, 1}, {0, 1, 2})] - for s_i, s in enumerate( - allbalancedsupports([[0, 1, 2], [0, 1], [0, 1, 2]])): + all_support = [ + ({0}, {0}, {0}), + ({0}, {0}, {1}), + ({0}, {0}, {2}), + ({0}, {1}, {0}), + ({0}, {1}, {1}), + ({0}, {1}, {2}), + ({1}, {0}, {0}), + ({1}, {0}, {1}), + ({1}, {0}, {2}), + ({1}, {1}, {0}), + ({1}, {1}, {1}), + ({1}, {1}, {2}), + ({2}, {0}, {0}), + ({2}, {0}, {1}), + ({2}, {0}, {2}), + ({2}, {1}, {0}), + ({2}, {1}, {1}), + ({2}, {1}, {2}), + ({0, 1}, {0}, {0}), + ({0, 1}, {0}, {1}), + ({0, 1}, {0}, {2}), + ({0, 1}, {1}, {0}), + ({0, 1}, {1}, {1}), + ({0, 1}, {1}, {2}), + ({0, 2}, {0}, {0}), + ({0, 2}, {0}, {1}), + ({0, 2}, {0}, {2}), + ({0, 2}, {1}, {0}), + ({0, 2}, {1}, {1}), + ({0, 2}, {1}, {2}), + ({1, 2}, {0}, {0}), + ({1, 2}, {0}, {1}), + ({1, 2}, {0}, {2}), + ({1, 2}, {1}, {0}), + ({1, 2}, {1}, {1}), + ({1, 2}, {1}, {2}), + ({0}, {0, 1}, {0}), + ({0}, {0, 1}, {1}), + ({0}, {0, 1}, {2}), + ({1}, {0, 1}, {0}), + ({1}, {0, 1}, {1}), + ({1}, {0, 1}, {2}), + ({2}, {0, 1}, {0}), + ({2}, {0, 1}, {1}), + ({2}, {0, 1}, {2}), + ({0}, {0}, {0, 1}), + ({0}, {0}, {0, 2}), + ({0}, {0}, {1, 2}), + ({0}, {1}, {0, 1}), + ({0}, {1}, {0, 2}), + ({0}, {1}, {1, 2}), + ({1}, {0}, {0, 1}), + ({1}, {0}, {0, 2}), + ({1}, {0}, {1, 2}), + ({1}, {1}, {0, 1}), + ({1}, {1}, {0, 2}), + ({1}, {1}, {1, 2}), + ({2}, {0}, {0, 1}), + ({2}, {0}, {0, 2}), + ({2}, {0}, {1, 2}), + ({2}, {1}, {0, 1}), + ({2}, {1}, {0, 2}), + ({2}, {1}, {1, 2}), + ({0, 1}, {0, 1}, {0}), + ({0, 1}, {0, 1}, {1}), + ({0, 1}, {0, 1}, {2}), + ({0, 2}, {0, 1}, {0}), + ({0, 2}, {0, 1}, {1}), + ({0, 2}, {0, 1}, {2}), + ({1, 2}, {0, 1}, {0}), + ({1, 2}, {0, 1}, {1}), + ({1, 2}, {0, 1}, {2}), + ({0, 1}, {0}, {0, 1}), + ({0, 1}, {0}, {0, 2}), + ({0, 1}, {0}, {1, 2}), + ({0, 1}, {1}, {0, 1}), + ({0, 1}, {1}, {0, 2}), + ({0, 1}, {1}, {1, 2}), + ({0, 2}, {0}, {0, 1}), + ({0, 2}, {0}, {0, 2}), + ({0, 2}, {0}, {1, 2}), + ({0, 2}, {1}, {0, 1}), + ({0, 2}, {1}, {0, 2}), + ({0, 2}, {1}, {1, 2}), + ({1, 2}, {0}, {0, 1}), + ({1, 2}, {0}, {0, 2}), + ({1, 2}, {0}, {1, 2}), + ({1, 2}, {1}, {0, 1}), + ({1, 2}, {1}, {0, 2}), + ({1, 2}, {1}, {1, 2}), + ({0}, {0, 1}, {0, 1}), + ({0}, {0, 1}, {0, 2}), + ({0}, {0, 1}, {1, 2}), + ({1}, {0, 1}, {0, 1}), + ({1}, {0, 1}, {0, 2}), + ({1}, {0, 1}, {1, 2}), + ({2}, {0, 1}, {0, 1}), + ({2}, {0, 1}, {0, 2}), + ({2}, {0, 1}, {1, 2}), + ({0, 1, 2}, {0}, {0}), + ({0, 1, 2}, {0}, {1}), + ({0, 1, 2}, {0}, {2}), + ({0, 1, 2}, {1}, {0}), + ({0, 1, 2}, {1}, {1}), + ({0, 1, 2}, {1}, {2}), + ({0}, {0}, {0, 1, 2}), + ({0}, {1}, {0, 1, 2}), + ({1}, {0}, {0, 1, 2}), + ({1}, {1}, {0, 1, 2}), + ({2}, {0}, {0, 1, 2}), + ({2}, {1}, {0, 1, 2}), + ({0, 1}, {0, 1}, {0, 1}), + ({0, 1}, {0, 1}, {0, 2}), + ({0, 1}, {0, 1}, {1, 2}), + ({0, 2}, {0, 1}, {0, 1}), + ({0, 2}, {0, 1}, {0, 2}), + ({0, 2}, {0, 1}, {1, 2}), + ({1, 2}, {0, 1}, {0, 1}), + ({1, 2}, {0, 1}, {0, 2}), + ({1, 2}, {0, 1}, {1, 2}), + ({0, 1, 2}, {0, 1}, {0}), + ({0, 1, 2}, {0, 1}, {1}), + ({0, 1, 2}, {0, 1}, {2}), + ({0, 1, 2}, {0}, {0, 1}), + ({0, 1, 2}, {0}, {0, 2}), + ({0, 1, 2}, {0}, {1, 2}), + ({0, 1, 2}, {1}, {0, 1}), + ({0, 1, 2}, {1}, {0, 2}), + ({0, 1, 2}, {1}, {1, 2}), + ({0, 1}, {0}, {0, 1, 2}), + ({0, 1}, {1}, {0, 1, 2}), + ({0, 2}, {0}, {0, 1, 2}), + ({0, 2}, {1}, {0, 1, 2}), + ({1, 2}, {0}, {0, 1, 2}), + ({1, 2}, {1}, {0, 1, 2}), + ({0}, {0, 1}, {0, 1, 2}), + ({1}, {0, 1}, {0, 1, 2}), + ({2}, {0, 1}, {0, 1, 2}), + ({0, 1, 2}, {0, 1}, {0, 1}), + ({0, 1, 2}, {0, 1}, {0, 2}), + ({0, 1, 2}, {0, 1}, {1, 2}), + ({0, 1}, {0, 1}, {0, 1, 2}), + ({0, 2}, {0, 1}, {0, 1, 2}), + ({1, 2}, {0, 1}, {0, 1, 2}), + ({0, 1, 2}, {0}, {0, 1, 2}), + ({0, 1, 2}, {1}, {0, 1, 2}), + ({0, 1, 2}, {0, 1}, {0, 1, 2}), + ] + for s_i, s in enumerate(allbalancedsupports([[0, 1, 2], [0, 1], [0, 1, 2]])): assert s == all_support[s_i] def test_allbalancedsupports3(): - all_support = [({1}, {0}, {0}), ({1}, {0}, {1}), ({1}, {0}, {2}), - ({1}, {0}, {0, 1}), ({1}, {0}, {0, 2}), ({1}, {0}, {1, 2}), - ({1}, {0}, {0, 1, 2})] + all_support = [ + ({1}, {0}, {0}), + ({1}, {0}, {1}), + ({1}, {0}, {2}), + ({1}, {0}, {0, 1}), + ({1}, {0}, {0, 2}), + ({1}, {0}, {1, 2}), + ({1}, {0}, {0, 1, 2}), + ] for s_i, s in enumerate(allbalancedsupports([[1], [0], [0, 1, 2]])): assert s == all_support[s_i] @@ -192,7 +281,8 @@ def pns_4player_nfg(): [50, 59, 27, 4, 72, 69, 18, 35, 6, 89, 78, 19, 36, 76, 64, 20], [97, 5, 90, 60, 6, 13, 56, 82, 89, 79, 52, 34, 35, 100, 60, 34], [15, 30, 53, 12, 79, 77, 15, 38, 100, 82, 35, 10, 24, 0, 29, 27], - [28, 66, 83, 1, 54, 89, 71, 35, 46, 62, 96, 26, 20, 58, 16, 81]] + [28, 66, 83, 1, 54, 89, 71, 35, 46, 62, 96, 26, 20, 58, 16, 81], + ] players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] tmp_nfg = NFG(players_actions, utilities) @@ -207,8 +297,11 @@ def empty_pns(): @pytest.fixture def pns_3player_nfg(): players_actions = [[0, 1], [0, 1], [0, 1]] - utilities = [[6, 7, 0, 5, 1, 4, 2, 3], [0, 3, 7, 4, 6, 5, 1, 2], - [4, 7, 4, 0, 3, 2, 6, 1]] + utilities = [ + [6, 7, 0, 5, 1, 4, 2, 3], + [0, 3, 7, 4, 6, 5, 1, 2], + [4, 7, 4, 0, 3, 2, 6, 1], + ] current_nfg = NFG(players_actions, utilities) return PNS_solver(current_nfg) @@ -219,7 +312,8 @@ def pns_4p_nfg_degen(): [50, 59, 27, 4, 72, 69, 18, 35, 6, 89, 78, 19, 36, 76, 64, 20], [97, 5, 90, 60, 6, 13, 56, 82, 89, 79, 52, 34, 35, 100, 60, 34], [15, 30, 53, 12, 79, 77, 15, 38, 100, 82, 35, 10, 24, 0, 29, 27], - [28, 66, 83, 1, 54, 89, 71, 35, 46, 62, 96, 26, 20, 58, 16, 81]] + [28, 66, 83, 1, 54, 89, 71, 35, 46, 62, 96, 26, 20, 58, 16, 81], + ] players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] current_nfg = NFG(players_actions, utilities) return PNS_solver(current_nfg) @@ -229,9 +323,14 @@ def pns_4p_nfg_degen(): def pns_hgg1(): players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] utilities = [ - [[-3, -7, -7, -10, -1, -5, -5, -9], [-3, -7, -1, -5, -7, -10, -5, -9], - [-3, -1, -7, -5, -7, -5, -10, -9]], - [[-1, -5, 0, -3], [-1, 0, -5, -3]], [[-1, -5, 0, -3], [-1, 0, -5, -3]]] + [ + [-3, -7, -7, -10, -1, -5, -5, -9], + [-3, -7, -1, -5, -7, -10, -5, -9], + [-3, -1, -7, -5, -7, -5, -10, -9], + ], + [[-1, -5, 0, -3], [-1, 0, -5, -3]], + [[-1, -5, 0, -3], [-1, 0, -5, -3]], + ] hypergraph = [[0, 1, 2], [1, 3], [2, 3]] hgg = HGG(players_actions, utilities, hypergraph) return PNS_solver(hgg) @@ -240,10 +339,14 @@ def pns_hgg1(): @pytest.fixture def pns_hgg2(): utilities = [ - [[-3, -1, -3, -2, -2, -3, -2, -1], [-1, -3, -5, -1, -1, -6, -3, -4], - [-2, -3, -6, -4, -3, -1, -3, -4]], + [ + [-3, -1, -3, -2, -2, -3, -2, -1], + [-1, -3, -5, -1, -1, -6, -3, -4], + [-2, -3, -6, -4, -3, -1, -3, -4], + ], [[-1, -3, -2, -2], [-1, -2, -2, -1]], - [[-3, -1, -4, -5], [-1, -3, -1, -5]]] + [[-3, -1, -4, -5], [-1, -3, -1, -5]], + ] # Error up level impossible, 2->3, [[0,1],[0,1],[0,1],[0,1]] hypergraph = [[0, 1, 2], [1, 3], [2, 3]] players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] @@ -254,10 +357,17 @@ def pns_hgg2(): @pytest.fixture def pns_hgg3(): utilities = [ - [[74, 6, 9, 60, 77, 30, 47, 0], [51, 97, 98, 83, 90, 1, 2, 47], - [18, 16, 29, 86, 100, 96, 93, 64]], - [[84, 48, 27, 5, 100, 62, 16, 62], [10, 88, 72, 47, 13, 24, 42, 72], - [1, 36, 68, 0, 53, 5, 61, 97]]] + [ + [74, 6, 9, 60, 77, 30, 47, 0], + [51, 97, 98, 83, 90, 1, 2, 47], + [18, 16, 29, 86, 100, 96, 93, 64], + ], + [ + [84, 48, 27, 5, 100, 62, 16, 62], + [10, 88, 72, 47, 13, 24, 42, 72], + [1, 36, 68, 0, 53, 5, 61, 97], + ], + ] hypergraph = [[0, 1, 3], [0, 2, 3]] players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] hgg = HGG(players_actions, utilities, hypergraph) @@ -268,10 +378,17 @@ def pns_hgg3(): def pns_hgg_irda1(): players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] utilities = [ - [[87, 77, 0, 49, 63, 99, 98, 25], [76, 100, 10, 43, 73, 65, 8, 56], - [8, 36, 3, 100, 24, 3, 64, 28]], - [[67, 38, 60, 64, 55, 100, 16, 13], [23, 59, 0, 9, 1, 8, 47, 33], - [9, 7, 100, 39, 16, 18, 16, 62]]] + [ + [87, 77, 0, 49, 63, 99, 98, 25], + [76, 100, 10, 43, 73, 65, 8, 56], + [8, 36, 3, 100, 24, 3, 64, 28], + ], + [ + [67, 38, 60, 64, 55, 100, 16, 13], + [23, 59, 0, 9, 1, 8, 47, 33], + [9, 7, 100, 39, 16, 18, 16, 62], + ], + ] hypergraph = [[0, 1, 2], [1, 2, 3]] hgg = HGG(players_actions, utilities, hypergraph) red_hgg, z_excluded = irda(hgg) @@ -282,10 +399,17 @@ def pns_hgg_irda1(): def pns_hgg_irda2(): players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] utilities = [ - [[29, 39, 100, 46, 40, 18, 97, 37], [23, 81, 64, 62, 90, 73, 76, 53], - [26, 36, 51, 5, 14, 99, 0, 54]], - [[12, 37, 7, 7, 41, 59, 27, 86], [65, 100, 100, 49, 97, 31, 68, 58], - [29, 70, 44, 61, 0, 53, 92, 74]]] + [ + [29, 39, 100, 46, 40, 18, 97, 37], + [23, 81, 64, 62, 90, 73, 76, 53], + [26, 36, 51, 5, 14, 99, 0, 54], + ], + [ + [12, 37, 7, 7, 41, 59, 27, 86], + [65, 100, 100, 49, 97, 31, 68, 58], + [29, 70, 44, 61, 0, 53, 92, 74], + ], + ] hypergraph = [[0, 2, 3], [1, 2, 3]] hgg = HGG(players_actions, utilities, hypergraph) red_hgg, z_excluded = irda(hgg) @@ -326,78 +450,101 @@ def test_final_support_size8(pns_hgg_irda2): def test_support_to_strategy1(pns_4player_nfg): assert pns_4player_nfg.support_to_strategy(({0}, {0}, {0}, {0})) == { - 0: [1, 0], 1: [1, 0], 2: [1, 0], 3: [1, 0]} + 0: [1, 0], + 1: [1, 0], + 2: [1, 0], + 3: [1, 0], + } def test_support_to_strategy2(pns_4player_nfg): - assert pns_4player_nfg.support_to_strategy( - ({0, 1}, {0, 1}, {0, 1}, {0, 1})) == {0: [1, 1], 1: [1, 1], 2: [1, 1], - 3: [1, 1]} + assert pns_4player_nfg.support_to_strategy(({0, 1}, {0, 1}, {0, 1}, {0, 1})) == { + 0: [1, 1], + 1: [1, 1], + 2: [1, 1], + 3: [1, 1], + } def test_support_to_strategy3(pns_4player_nfg): assert pns_4player_nfg.support_to_strategy(({0, 1}, {1}, {0}, {1})) == { - 0: [1, 1], 1: [0, 1], 2: [1, 0], 3: [0, 1]} + 0: [1, 1], + 1: [0, 1], + 2: [1, 0], + 3: [0, 1], + } def test_support_to_strategy4(pns_hgg_irda1): assert pns_hgg_irda1.support_to_strategy(({0, 1}, {0}, {1}, {0})) == { - 0: [1, 1], 1: [1], 2: [0, 1], 3: [1]} + 0: [1, 1], + 1: [1], + 2: [0, 1], + 3: [1], + } def test_support_to_strategy5(pns_hgg_irda2): assert pns_hgg_irda2.support_to_strategy(({0, 1}, {1}, {0}, {1})) == { - 0: [1, 1], 1: [1], 2: [1, 0], 3: [0, 1]} + 0: [1, 1], + 1: [1], + 2: [1, 0], + 3: [0, 1], + } def test_create_W_from_support_strat1(pns_4player_nfg): stratsupport = pns_4player_nfg.support_to_strategy(({0}, {0}, {0}, {0})) - assert set( - pns_4player_nfg.create_W_from_support_strat(stratsupport)) == set( - [(0, 0), (1, 0), (2, 0), (3, 0)]) + assert set(pns_4player_nfg.create_W_from_support_strat(stratsupport)) == set( + [(0, 0), (1, 0), (2, 0), (3, 0)] + ) def test_create_W_from_support_strat2(pns_4player_nfg): - stratsupport = pns_4player_nfg.support_to_strategy( - ({0, 1}, {0, 1}, {0, 1}, {0, 1})) - assert set( - pns_4player_nfg.create_W_from_support_strat(stratsupport)) == {(0, 0), - (1, 0), - (2, 0), - (3, 0), - (0, 1), - (1, 1), - (2, 1), - (3, 1)} + stratsupport = pns_4player_nfg.support_to_strategy(({0, 1}, {0, 1}, {0, 1}, {0, 1})) + assert set(pns_4player_nfg.create_W_from_support_strat(stratsupport)) == { + (0, 0), + (1, 0), + (2, 0), + (3, 0), + (0, 1), + (1, 1), + (2, 1), + (3, 1), + } def test_create_W_from_support_strat3(pns_hgg_irda1): stratsupport = pns_hgg_irda1.support_to_strategy(({0}, {0}, {0}, {0})) assert set(pns_hgg_irda1.create_W_from_support_strat(stratsupport)) == { - (0, 0), (1, 0), (2, 0), (3, 0)} + (0, 0), + (1, 0), + (2, 0), + (3, 0), + } def test_create_Wb_from_support_strat1(pns_4player_nfg): stratsupport = pns_4player_nfg.support_to_strategy(({0}, {0}, {0}, {0})) - assert set( - pns_4player_nfg.create_Wb_from_support_strat(stratsupport)) == {(0, 1), - (1, 1), - (2, 1), - (3, 1)} + assert set(pns_4player_nfg.create_Wb_from_support_strat(stratsupport)) == { + (0, 1), + (1, 1), + (2, 1), + (3, 1), + } def test_create_Wb_from_support_strat2(pns_4player_nfg): - stratsupport = pns_4player_nfg.support_to_strategy( - ({0, 1}, {0, 1}, {0, 1}, {0, 1})) - assert set( - pns_4player_nfg.create_Wb_from_support_strat(stratsupport)) == set([]) + stratsupport = pns_4player_nfg.support_to_strategy(({0, 1}, {0, 1}, {0, 1}, {0, 1})) + assert set(pns_4player_nfg.create_Wb_from_support_strat(stratsupport)) == set([]) def test_create_Wb_from_support_strat3(pns_hgg_irda1): stratsupport = pns_hgg_irda1.support_to_strategy(({0}, {0}, {0}, {0})) - assert set( - pns_hgg_irda1.create_Wb_from_support_strat(stratsupport)) == {(0, 1), - (2, 1)} + assert set(pns_hgg_irda1.create_Wb_from_support_strat(stratsupport)) == { + (0, 1), + (2, 1), + } def test_launch_pns1(pns_4player_nfg): @@ -405,50 +552,71 @@ def test_launch_pns1(pns_4player_nfg): # for x in sol.keys(): # for v_i, v in enumerate(sol[x]): # print(v.radical_expression()) - check_sol = {0: [Fraction(65, 103), Fraction(38, 103)], 1: [1, 0], - 2: [Fraction(51, 95), Fraction(44, 95)], 3: [1, 0]} + check_sol = { + 0: [Fraction(65, 103), Fraction(38, 103)], + 1: [1, 0], + 2: [Fraction(51, 95), Fraction(44, 95)], + 3: [1, 0], + } for p in sol.keys(): for v_i, v in enumerate(sol[p]): - assert float(v) - check_sol[p][v_i] < 0.00001 and float(v) - \ - check_sol[p][v_i] > -0.000001 + assert ( + float(v) - check_sol[p][v_i] < 0.00001 + and float(v) - check_sol[p][v_i] > -0.000001 + ) def test_launch_pns2(pns_hgg1): - assert pns_hgg1.launch_pns() == {0: [0, 1], 1: [0, 1], 2: [0, 1], - 3: [0, 1]} + assert pns_hgg1.launch_pns() == {0: [0, 1], 1: [0, 1], 2: [0, 1], 3: [0, 1]} def test_launch_pns3(pns_hgg2): sol = pns_hgg2.launch_pns() - check_sol = {0: [Fraction(1, 3), Fraction(2, 3)], 1: [1, 0], - 2: [Fraction(2, 3), Fraction(1, 3)], 3: [1, 0]} + check_sol = { + 0: [Fraction(1, 3), Fraction(2, 3)], + 1: [1, 0], + 2: [Fraction(2, 3), Fraction(1, 3)], + 3: [1, 0], + } for p in sol.keys(): for v_i, v in enumerate(sol[p]): - assert float(v) - check_sol[p][v_i] < 0.00001 and float(v) - \ - check_sol[p][v_i] > -0.000001 + assert ( + float(v) - check_sol[p][v_i] < 0.00001 + and float(v) - check_sol[p][v_i] > -0.000001 + ) def test_launch_pns4(pns_hgg3): sol = pns_hgg3.launch_pns() - check_sol = {0: [Fraction(23, 30), Fraction(7, 30)], - 1: [Fraction(23, 42), Fraction(19, 42)], 2: [1, 0], - 3: [0, 1]} + check_sol = { + 0: [Fraction(23, 30), Fraction(7, 30)], + 1: [Fraction(23, 42), Fraction(19, 42)], + 2: [1, 0], + 3: [0, 1], + } for p in sol.keys(): for v_i, v in enumerate(sol[p]): - assert float(v) - check_sol[p][v_i] < 0.00001 and float(v) - \ - check_sol[p][v_i] > -0.000001 + assert ( + float(v) - check_sol[p][v_i] < 0.00001 + and float(v) - check_sol[p][v_i] > -0.000001 + ) def test_launch_pns5(pns_hgg_irda1): sol = pns_hgg_irda1.launch_pns() - check_sol = {0: [Fraction(44, 49), Fraction(5, 49)], 1: [1], - 2: [Fraction(11, 23), Fraction(12, 23)], 3: [1]} + check_sol = { + 0: [Fraction(44, 49), Fraction(5, 49)], + 1: [1], + 2: [Fraction(11, 23), Fraction(12, 23)], + 3: [1], + } for p in sol.keys(): for v_i, v in enumerate(sol[p]): - assert float(v) - check_sol[p][v_i] < 0.00001 and float(v) - \ - check_sol[p][v_i] > -0.000001 + assert ( + float(v) - check_sol[p][v_i] < 0.00001 + and float(v) - check_sol[p][v_i] > -0.000001 + ) def test_launch_pns6(pns_hgg_irda2): - assert pns_hgg_irda2.launch_pns() == {0: [1, 0], 1: [1], 2: [0, 1], - 3: [1, 0]} + assert pns_hgg_irda2.launch_pns() == {0: [1, 0], 1: [1], 2: [0, 1], 3: [1, 0]} diff --git a/test/test_polynomial_complementary_problem.py b/test/test_polynomial_complementary_problem.py index 70d1a50..c3ac03d 100644 --- a/test/test_polynomial_complementary_problem.py +++ b/test/test_polynomial_complementary_problem.py @@ -2,10 +2,13 @@ import numpy as np import pytest from sage.all import ideal -from gtnash.util.polynomial_complementary_problem import \ - PolynomialComplementaryProblem, Subsystem +from gtnash.util.polynomial_complementary_problem import ( + PolynomialComplementaryProblem, + Subsystem, +) from gtnash.game.normalformgame import NFG from gtnash.game.hypergraphicalgame import HGG + # from gtnash.util.irda import irda # # from fractions import Fraction @@ -41,7 +44,8 @@ def pcp_4player_nfg(): [50, 59, 27, 4, 72, 69, 18, 35, 6, 89, 78, 19, 36, 76, 64, 20], [97, 5, 90, 60, 6, 13, 56, 82, 89, 79, 52, 34, 35, 100, 60, 34], [15, 30, 53, 12, 79, 77, 15, 38, 100, 82, 35, 10, 24, 0, 29, 27], - [28, 66, 83, 1, 54, 89, 71, 35, 46, 62, 96, 26, 20, 58, 16, 81]] + [28, 66, 83, 1, 54, 89, 71, 35, 46, 62, 96, 26, 20, 58, 16, 81], + ] players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] tmp_nfg = NFG(players_actions, utilities) @@ -57,8 +61,11 @@ def empty_pcp(): @pytest.fixture def pcp_3player_nfg(): players_actions = [[0, 1], [0, 1], [0, 1]] - utilities = [[6, 7, 0, 5, 1, 4, 2, 3], [0, 3, 7, 4, 6, 5, 1, 2], - [4, 7, 4, 0, 3, 2, 6, 1]] + utilities = [ + [6, 7, 0, 5, 1, 4, 2, 3], + [0, 3, 7, 4, 6, 5, 1, 2], + [4, 7, 4, 0, 3, 2, 6, 1], + ] current_nfg = NFG(players_actions, utilities) return PolynomialComplementaryProblem(current_nfg) @@ -66,8 +73,11 @@ def pcp_3player_nfg(): @pytest.fixture def pcp_3player_nfg_no_y(): players_actions = [[0, 1], [0, 1], [0, 1]] - utilities = [[6, 7, 0, 5, 1, 4, 2, 3], [0, 3, 7, 4, 6, 5, 1, 2], - [4, 7, 4, 0, 3, 2, 6, 1]] + utilities = [ + [6, 7, 0, 5, 1, 4, 2, 3], + [0, 3, 7, 4, 6, 5, 1, 2], + [4, 7, 4, 0, 3, 2, 6, 1], + ] current_nfg = NFG(players_actions, utilities) return PolynomialComplementaryProblem(current_nfg, fact_y=False) @@ -78,7 +88,8 @@ def pcp_4p_nfg_degen(): [50, 59, 27, 4, 72, 69, 18, 35, 6, 89, 78, 19, 36, 76, 64, 20], [97, 5, 90, 60, 6, 13, 56, 82, 89, 79, 52, 34, 35, 100, 60, 34], [15, 30, 53, 12, 79, 77, 15, 38, 100, 82, 35, 10, 24, 0, 29, 27], - [28, 66, 83, 1, 54, 89, 71, 35, 46, 62, 96, 26, 20, 58, 16, 81]] + [28, 66, 83, 1, 54, 89, 71, 35, 46, 62, 96, 26, 20, 58, 16, 81], + ] players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] current_nfg = NFG(players_actions, utilities) return PolynomialComplementaryProblem(current_nfg) @@ -88,9 +99,14 @@ def pcp_4p_nfg_degen(): def pcp_hgg1(): players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] utilities = [ - [[-3, -7, -7, -10, -1, -5, -5, -9], [-3, -7, -1, -5, -7, -10, -5, -9], - [-3, -1, -7, -5, -7, -5, -10, -9]], - [[-1, -5, 0, -3], [-1, 0, -5, -3]], [[-1, -5, 0, -3], [-1, 0, -5, -3]]] + [ + [-3, -7, -7, -10, -1, -5, -5, -9], + [-3, -7, -1, -5, -7, -10, -5, -9], + [-3, -1, -7, -5, -7, -5, -10, -9], + ], + [[-1, -5, 0, -3], [-1, 0, -5, -3]], + [[-1, -5, 0, -3], [-1, 0, -5, -3]], + ] hypergraph = [[0, 1, 2], [1, 3], [2, 3]] hgg = HGG(players_actions, utilities, hypergraph) return PolynomialComplementaryProblem(hgg) @@ -99,9 +115,14 @@ def pcp_hgg1(): def pcp_hgg1_no_y(): players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] utilities = [ - [[-3, -7, -7, -10, -1, -5, -5, -9], [-3, -7, -1, -5, -7, -10, -5, -9], - [-3, -1, -7, -5, -7, -5, -10, -9]], - [[-1, -5, 0, -3], [-1, 0, -5, -3]], [[-1, -5, 0, -3], [-1, 0, -5, -3]]] + [ + [-3, -7, -7, -10, -1, -5, -5, -9], + [-3, -7, -1, -5, -7, -10, -5, -9], + [-3, -1, -7, -5, -7, -5, -10, -9], + ], + [[-1, -5, 0, -3], [-1, 0, -5, -3]], + [[-1, -5, 0, -3], [-1, 0, -5, -3]], + ] hypergraph = [[0, 1, 2], [1, 3], [2, 3]] hgg = HGG(players_actions, utilities, hypergraph) return PolynomialComplementaryProblem(hgg, fact_y=False) @@ -110,10 +131,14 @@ def pcp_hgg1_no_y(): @pytest.fixture def pcp_hgg2(): utilities = [ - [[-3, -1, -3, -2, -2, -3, -2, -1], [-1, -3, -5, -1, -1, -6, -3, -4], - [-2, -3, -6, -4, -3, -1, -3, -4]], + [ + [-3, -1, -3, -2, -2, -3, -2, -1], + [-1, -3, -5, -1, -1, -6, -3, -4], + [-2, -3, -6, -4, -3, -1, -3, -4], + ], [[-1, -3, -2, -2], [-1, -2, -2, -1]], - [[-3, -1, -4, -5], [-1, -3, -1, -5]]] + [[-3, -1, -4, -5], [-1, -3, -1, -5]], + ] # Error up level impossible, 2->3, [[0,1],[0,1],[0,1],[0,1]] hypergraph = [[0, 1, 2], [1, 3], [2, 3]] players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] @@ -124,10 +149,17 @@ def pcp_hgg2(): @pytest.fixture def pcp_hgg3(): utilities = [ - [[74, 6, 9, 60, 77, 30, 47, 0], [51, 97, 98, 83, 90, 1, 2, 47], - [18, 16, 29, 86, 100, 96, 93, 64]], - [[84, 48, 27, 5, 100, 62, 16, 62], [10, 88, 72, 47, 13, 24, 42, 72], - [1, 36, 68, 0, 53, 5, 61, 97]]] + [ + [74, 6, 9, 60, 77, 30, 47, 0], + [51, 97, 98, 83, 90, 1, 2, 47], + [18, 16, 29, 86, 100, 96, 93, 64], + ], + [ + [84, 48, 27, 5, 100, 62, 16, 62], + [10, 88, 72, 47, 13, 24, 42, 72], + [1, 36, 68, 0, 53, 5, 61, 97], + ], + ] hypergraph = [[0, 1, 3], [0, 2, 3]] players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] hgg = HGG(players_actions, utilities, hypergraph) @@ -139,40 +171,48 @@ def test_generate_id_to_act1(empty_pcp): def test_generate_id_to_act2(pcp_4player_nfg): - assert pcp_4player_nfg.generate_id_to_act() == {0: [0, 1], 1: [0, 1], - 2: [0, 1], 3: [0, 1]} + assert pcp_4player_nfg.generate_id_to_act() == { + 0: [0, 1], + 1: [0, 1], + 2: [0, 1], + 3: [0, 1], + } def test_generate_id_to_act3(pcp_3player_nfg): - assert pcp_3player_nfg.generate_id_to_act() == {0: [0, 1], 1: [0, 1], - 2: [0, 1]} + assert pcp_3player_nfg.generate_id_to_act() == {0: [0, 1], 1: [0, 1], 2: [0, 1]} def test_generate_id_to_act4(pcp_4p_nfg_degen): - assert pcp_4p_nfg_degen.generate_id_to_act() == {0: [0, 1], 1: [0, 1], - 2: [0, 1], 3: [0, 1]} + assert pcp_4p_nfg_degen.generate_id_to_act() == { + 0: [0, 1], + 1: [0, 1], + 2: [0, 1], + 3: [0, 1], + } def test_generate_id_to_act5(pcp_hgg1): - assert pcp_hgg1.generate_id_to_act() == {0: [0, 1], 1: [0, 1], 2: [0, 1], - 3: [0, 1]} + assert pcp_hgg1.generate_id_to_act() == {0: [0, 1], 1: [0, 1], 2: [0, 1], 3: [0, 1]} def test_generate_id_to_act6(pcp_hgg2): - assert pcp_hgg2.generate_id_to_act() == {0: [0, 1], 1: [0, 1], 2: [0, 1], - 3: [0, 1]} + assert pcp_hgg2.generate_id_to_act() == {0: [0, 1], 1: [0, 1], 2: [0, 1], 3: [0, 1]} def test_generate_id_to_act7(pcp_hgg3): - assert pcp_hgg3.generate_id_to_act() == {0: [0, 1], 1: [0, 1], 2: [0, 1], - 3: [0, 1]} + assert pcp_hgg3.generate_id_to_act() == {0: [0, 1], 1: [0, 1], 2: [0, 1], 3: [0, 1]} def test_generate_id_to_act8(empty_pcp): players_actions = [[0, 1, 2], [0, 1, 2], [0, 1, 2, 3], [0, 1]] empty_pcp.game = gen_random_nfg(players_actions) - assert empty_pcp.generate_id_to_act() == {0: [0, 1, 2], 1: [0, 1, 2], - 2: [0, 1, 2, 3], 3: [0, 1]} + assert empty_pcp.generate_id_to_act() == { + 0: [0, 1, 2], + 1: [0, 1, 2], + 2: [0, 1, 2, 3], + 3: [0, 1], + } def test_generate_id_to_nb_act1(empty_pcp): @@ -213,15 +253,34 @@ def test_gen_var_x0(empty_pcp): players_actions = [[0, 1, 2], [0, 1, 2], [0, 1, 2, 3], [0, 1]] empty_pcp.game = gen_random_nfg(players_actions) empty_pcp.gen_var_x() - assert empty_pcp.set_x == ['x0_0', 'x0_1', 'x0_2', 'x1_0', 'x1_1', 'x1_2', - 'x2_0', 'x2_1', 'x2_2', 'x2_3', 'x3_0', - 'x3_1', ] - assert empty_pcp.couple_to_x == {(0, 0): 'x0_0', (0, 1): 'x0_1', - (0, 2): 'x0_2', (1, 0): 'x1_0', - (1, 1): 'x1_1', (1, 2): 'x1_2', - (2, 0): 'x2_0', (2, 1): 'x2_1', - (2, 2): 'x2_2', (2, 3): 'x2_3', - (3, 0): 'x3_0', (3, 1): 'x3_1'} + assert empty_pcp.set_x == [ + "x0_0", + "x0_1", + "x0_2", + "x1_0", + "x1_1", + "x1_2", + "x2_0", + "x2_1", + "x2_2", + "x2_3", + "x3_0", + "x3_1", + ] + assert empty_pcp.couple_to_x == { + (0, 0): "x0_0", + (0, 1): "x0_1", + (0, 2): "x0_2", + (1, 0): "x1_0", + (1, 1): "x1_1", + (1, 2): "x1_2", + (2, 0): "x2_0", + (2, 1): "x2_1", + (2, 2): "x2_2", + (2, 3): "x2_3", + (3, 0): "x3_0", + (3, 1): "x3_1", + } # {(0,0):'x0_0','x0_1','x0_2', @@ -231,61 +290,136 @@ def test_gen_var_x0(empty_pcp): def test_gen_var_x1(pcp_3player_nfg): - assert pcp_3player_nfg.set_x == ['x0_0', 'x0_1', 'x1_0', 'x1_1', 'x2_0', - 'x2_1'] - assert pcp_3player_nfg.couple_to_x == {(0, 0): 'x0_0', (0, 1): 'x0_1', - (1, 0): 'x1_0', (1, 1): 'x1_1', - (2, 0): 'x2_0', (2, 1): 'x2_1'} + assert pcp_3player_nfg.set_x == ["x0_0", "x0_1", "x1_0", "x1_1", "x2_0", "x2_1"] + assert pcp_3player_nfg.couple_to_x == { + (0, 0): "x0_0", + (0, 1): "x0_1", + (1, 0): "x1_0", + (1, 1): "x1_1", + (2, 0): "x2_0", + (2, 1): "x2_1", + } def test_gen_var_x2(pcp_4player_nfg): - assert pcp_4player_nfg.set_x == ['x0_0', 'x0_1', 'x1_0', 'x1_1', 'x2_0', - 'x2_1', 'x3_0', 'x3_1'] - assert pcp_4player_nfg.couple_to_x == {(0, 0): 'x0_0', (0, 1): 'x0_1', - (1, 0): 'x1_0', (1, 1): 'x1_1', - (2, 0): 'x2_0', (2, 1): 'x2_1', - (3, 0): 'x3_0', (3, 1): 'x3_1'} + assert pcp_4player_nfg.set_x == [ + "x0_0", + "x0_1", + "x1_0", + "x1_1", + "x2_0", + "x2_1", + "x3_0", + "x3_1", + ] + assert pcp_4player_nfg.couple_to_x == { + (0, 0): "x0_0", + (0, 1): "x0_1", + (1, 0): "x1_0", + (1, 1): "x1_1", + (2, 0): "x2_0", + (2, 1): "x2_1", + (3, 0): "x3_0", + (3, 1): "x3_1", + } def test_gen_var_x3(pcp_4p_nfg_degen): - assert pcp_4p_nfg_degen.set_x == ['x0_0', 'x0_1', 'x1_0', 'x1_1', 'x2_0', - 'x2_1', 'x3_0', 'x3_1'] - assert pcp_4p_nfg_degen.couple_to_x == {(0, 0): 'x0_0', (0, 1): 'x0_1', - (1, 0): 'x1_0', (1, 1): 'x1_1', - (2, 0): 'x2_0', (2, 1): 'x2_1', - (3, 0): 'x3_0', (3, 1): 'x3_1'} + assert pcp_4p_nfg_degen.set_x == [ + "x0_0", + "x0_1", + "x1_0", + "x1_1", + "x2_0", + "x2_1", + "x3_0", + "x3_1", + ] + assert pcp_4p_nfg_degen.couple_to_x == { + (0, 0): "x0_0", + (0, 1): "x0_1", + (1, 0): "x1_0", + (1, 1): "x1_1", + (2, 0): "x2_0", + (2, 1): "x2_1", + (3, 0): "x3_0", + (3, 1): "x3_1", + } def test_gen_var_x4(pcp_hgg1): - assert pcp_hgg1.set_x == ['x0_0', 'x0_1', 'x1_0', 'x1_1', 'x2_0', 'x2_1', - 'x3_0', 'x3_1'] - assert pcp_hgg1.couple_to_x == {(0, 0): 'x0_0', (0, 1): 'x0_1', - (1, 0): 'x1_0', (1, 1): 'x1_1', - (2, 0): 'x2_0', (2, 1): 'x2_1', - (3, 0): 'x3_0', (3, 1): 'x3_1'} + assert pcp_hgg1.set_x == [ + "x0_0", + "x0_1", + "x1_0", + "x1_1", + "x2_0", + "x2_1", + "x3_0", + "x3_1", + ] + assert pcp_hgg1.couple_to_x == { + (0, 0): "x0_0", + (0, 1): "x0_1", + (1, 0): "x1_0", + (1, 1): "x1_1", + (2, 0): "x2_0", + (2, 1): "x2_1", + (3, 0): "x3_0", + (3, 1): "x3_1", + } def test_gen_var_x5(pcp_hgg2): - assert pcp_hgg2.set_x == ['x0_0', 'x0_1', 'x1_0', 'x1_1', 'x2_0', 'x2_1', - 'x3_0', 'x3_1'] - assert pcp_hgg2.couple_to_x == {(0, 0): 'x0_0', (0, 1): 'x0_1', - (1, 0): 'x1_0', (1, 1): 'x1_1', - (2, 0): 'x2_0', (2, 1): 'x2_1', - (3, 0): 'x3_0', (3, 1): 'x3_1'} + assert pcp_hgg2.set_x == [ + "x0_0", + "x0_1", + "x1_0", + "x1_1", + "x2_0", + "x2_1", + "x3_0", + "x3_1", + ] + assert pcp_hgg2.couple_to_x == { + (0, 0): "x0_0", + (0, 1): "x0_1", + (1, 0): "x1_0", + (1, 1): "x1_1", + (2, 0): "x2_0", + (2, 1): "x2_1", + (3, 0): "x3_0", + (3, 1): "x3_1", + } def test_gen_var_x6(pcp_hgg3): - assert pcp_hgg3.set_x == ['x0_0', 'x0_1', 'x1_0', 'x1_1', 'x2_0', 'x2_1', - 'x3_0', 'x3_1'] - assert pcp_hgg3.couple_to_x == {(0, 0): 'x0_0', (0, 1): 'x0_1', - (1, 0): 'x1_0', (1, 1): 'x1_1', - (2, 0): 'x2_0', (2, 1): 'x2_1', - (3, 0): 'x3_0', (3, 1): 'x3_1'} + assert pcp_hgg3.set_x == [ + "x0_0", + "x0_1", + "x1_0", + "x1_1", + "x2_0", + "x2_1", + "x3_0", + "x3_1", + ] + assert pcp_hgg3.couple_to_x == { + (0, 0): "x0_0", + (0, 1): "x0_1", + (1, 0): "x1_0", + (1, 1): "x1_1", + (2, 0): "x2_0", + (2, 1): "x2_1", + (3, 0): "x3_0", + (3, 1): "x3_1", + } # GEN OMEGA0 was modified to avoid using IRDA which was "useless" # as we are supposed to use it before creating the pcp + def test_omega0_1(pcp_3player_nfg): assert pcp_3player_nfg.omega0 == {0: 0, 1: 0, 2: 0} @@ -306,182 +440,218 @@ def test_omega0_4(pcp_hgg2): # def test_generate_Q0(empty_pcp): + def test_generate_R1(pcp_3player_nfg): ring = pcp_3player_nfg.ring assert pcp_3player_nfg.generate_R() == { - (0, 0, 0): (-2) * ring('x1_0') * ring('x2_0') - ring('x1_0') * ring( - 'x2_1') + (-8) * ring('x1_1') * ring('x2_0') + (-3) * ring( - 'x1_1') * ring('x2_1'), - (0, 1, 0): (-7) * ring('x1_0') * ring('x2_0') + (-4) * ring( - 'x1_0') * ring('x2_1') + (-6) * ring('x1_1') * ring('x2_0') + ( - -5) * ring('x1_1') * ring('x2_1'), - (1, 0, 0): (-8) * ring('x0_0') * ring('x2_0') + (-5) * ring( - 'x0_0') * ring('x2_1') + (-2) * ring('x0_1') * ring('x2_0') + ( - -3) * ring('x0_1') * ring('x2_1'), - (1, 1, 0): -ring('x0_0') * ring('x2_0') + (-4) * ring('x0_0') * ring( - 'x2_1') + (-7) * ring('x0_1') * ring('x2_0') + (-6) * ring( - 'x0_1') * ring('x2_1'), - (2, 0, 0): (-4) * ring('x0_0') * ring('x1_0') + (-4) * ring( - 'x0_0') * ring('x1_1') + (-5) * ring('x0_1') * ring('x1_0') + ( - -2) * ring('x0_1') * ring('x1_1'), - (2, 1, 0): -ring('x0_0') * ring('x1_0') + (-8) * ring('x0_0') * ring( - 'x1_1') + (-6) * ring('x0_1') * ring('x1_0') + (-7) * ring( - 'x0_1') * ring('x1_1')} + (0, 0, 0): (-2) * ring("x1_0") * ring("x2_0") + - ring("x1_0") * ring("x2_1") + + (-8) * ring("x1_1") * ring("x2_0") + + (-3) * ring("x1_1") * ring("x2_1"), + (0, 1, 0): (-7) * ring("x1_0") * ring("x2_0") + + (-4) * ring("x1_0") * ring("x2_1") + + (-6) * ring("x1_1") * ring("x2_0") + + (-5) * ring("x1_1") * ring("x2_1"), + (1, 0, 0): (-8) * ring("x0_0") * ring("x2_0") + + (-5) * ring("x0_0") * ring("x2_1") + + (-2) * ring("x0_1") * ring("x2_0") + + (-3) * ring("x0_1") * ring("x2_1"), + (1, 1, 0): -ring("x0_0") * ring("x2_0") + + (-4) * ring("x0_0") * ring("x2_1") + + (-7) * ring("x0_1") * ring("x2_0") + + (-6) * ring("x0_1") * ring("x2_1"), + (2, 0, 0): (-4) * ring("x0_0") * ring("x1_0") + + (-4) * ring("x0_0") * ring("x1_1") + + (-5) * ring("x0_1") * ring("x1_0") + + (-2) * ring("x0_1") * ring("x1_1"), + (2, 1, 0): -ring("x0_0") * ring("x1_0") + + (-8) * ring("x0_0") * ring("x1_1") + + (-6) * ring("x0_1") * ring("x1_0") + + (-7) * ring("x0_1") * ring("x1_1"), + } def test_generate_R2(pcp_hgg1): ring = pcp_hgg1.ring assert pcp_hgg1.generate_R() == { - (0, 0, 0): (-3) * ring('x1_0') * ring('x2_0') + (-7) * ring( - 'x1_0') * ring('x2_1') + (-7) * ring('x1_1') * ring('x2_0') + ( - -10) * ring('x1_1') * ring('x2_1'), - (0, 1, 0): -ring('x1_0') * ring('x2_0') + (-5) * ring('x1_0') * ring( - 'x2_1') + (-5) * ring('x1_1') * ring('x2_0') + (-9) * ring( - 'x1_1') * ring('x2_1'), - (1, 0, 0): (-4) * ring('x0_0') * ring('x2_0') + (-8) * ring( - 'x0_0') * ring('x2_1') + (-8) * ring('x0_1') * ring('x2_0') + ( - -11) * ring('x0_1') * ring('x2_1'), - (1, 0, 1): (-2) * ring('x3_0') + (-6) * ring('x3_1'), - (1, 1, 0): (-2) * ring('x0_0') * ring('x2_0') + (-6) * ring( - 'x0_0') * ring('x2_1') + (-6) * ring('x0_1') * ring('x2_0') + ( - -10) * ring('x0_1') * ring('x2_1'), - (1, 1, 1): -ring('x3_0') + (-4) * ring('x3_1'), - (2, 0, 0): (-4) * ring('x0_0') * ring('x1_0') + (-8) * ring( - 'x0_0') * ring('x1_1') + (-8) * ring('x0_1') * ring('x1_0') + ( - -11) * ring('x0_1') * ring('x1_1'), - (2, 0, 2): (-2) * ring('x3_0') + (-6) * ring('x3_1'), - (2, 1, 0): (-2) * ring('x0_0') * ring('x1_0') + (-6) * ring( - 'x0_0') * ring('x1_1') + (-6) * ring('x0_1') * ring('x1_0') + ( - -10) * ring('x0_1') * ring('x1_1'), - (2, 1, 2): -ring('x3_0') + (-4) * ring('x3_1'), - (3, 0, 1): (-2) * ring('x1_0') + (-6) * ring('x1_1'), - (3, 0, 2): (-2) * ring('x2_0') + (-6) * ring('x2_1'), - (3, 1, 1): -ring('x1_0') + (-4) * ring('x1_1'), - (3, 1, 2): -ring('x2_0') + (-4) * ring('x2_1') + (0, 0, 0): (-3) * ring("x1_0") * ring("x2_0") + + (-7) * ring("x1_0") * ring("x2_1") + + (-7) * ring("x1_1") * ring("x2_0") + + (-10) * ring("x1_1") * ring("x2_1"), + (0, 1, 0): -ring("x1_0") * ring("x2_0") + + (-5) * ring("x1_0") * ring("x2_1") + + (-5) * ring("x1_1") * ring("x2_0") + + (-9) * ring("x1_1") * ring("x2_1"), + (1, 0, 0): (-4) * ring("x0_0") * ring("x2_0") + + (-8) * ring("x0_0") * ring("x2_1") + + (-8) * ring("x0_1") * ring("x2_0") + + (-11) * ring("x0_1") * ring("x2_1"), + (1, 0, 1): (-2) * ring("x3_0") + (-6) * ring("x3_1"), + (1, 1, 0): (-2) * ring("x0_0") * ring("x2_0") + + (-6) * ring("x0_0") * ring("x2_1") + + (-6) * ring("x0_1") * ring("x2_0") + + (-10) * ring("x0_1") * ring("x2_1"), + (1, 1, 1): -ring("x3_0") + (-4) * ring("x3_1"), + (2, 0, 0): (-4) * ring("x0_0") * ring("x1_0") + + (-8) * ring("x0_0") * ring("x1_1") + + (-8) * ring("x0_1") * ring("x1_0") + + (-11) * ring("x0_1") * ring("x1_1"), + (2, 0, 2): (-2) * ring("x3_0") + (-6) * ring("x3_1"), + (2, 1, 0): (-2) * ring("x0_0") * ring("x1_0") + + (-6) * ring("x0_0") * ring("x1_1") + + (-6) * ring("x0_1") * ring("x1_0") + + (-10) * ring("x0_1") * ring("x1_1"), + (2, 1, 2): -ring("x3_0") + (-4) * ring("x3_1"), + (3, 0, 1): (-2) * ring("x1_0") + (-6) * ring("x1_1"), + (3, 0, 2): (-2) * ring("x2_0") + (-6) * ring("x2_1"), + (3, 1, 1): -ring("x1_0") + (-4) * ring("x1_1"), + (3, 1, 2): -ring("x2_0") + (-4) * ring("x2_1"), } # def test_gen_poly + def test_generate_poly1(pcp_3player_nfg): ring = pcp_3player_nfg.ring - y_value = {ring('y2_0'): 1} + y_value = {ring("y2_0"): 1} tmp_couple_poly = { - (n, i): pcp_3player_nfg.couple_to_poly[(n, i)].subs(y_value) for (n, i) - in pcp_3player_nfg.couple_to_poly.keys()} + (n, i): pcp_3player_nfg.couple_to_poly[(n, i)].subs(y_value) + for (n, i) in pcp_3player_nfg.couple_to_poly.keys() + } assert tmp_couple_poly == { - (0, 0): 2 * ring('x1_0') * ring('x2_0') + ring('x1_0') * ring( - 'x2_1') + 8 * ring('x1_1') * ring('x2_0') + 3 * ring( - 'x1_1') * ring('x2_1') - 1, - (0, 1): 7 * ring('x1_0') * ring('x2_0') + 4 * ring('x1_0') * ring( - 'x2_1') + 6 * ring('x1_1') * ring('x2_0') + 5 * ring( - 'x1_1') * ring('x2_1') - 1, - (1, 0): 8 * ring('x0_0') * ring('x2_0') + 5 * ring('x0_0') * ring( - 'x2_1') + 2 * ring('x0_1') * ring('x2_0') + 3 * ring( - 'x0_1') * ring('x2_1') - 1, - (1, 1): ring('x0_0') * ring('x2_0') + 4 * ring('x0_0') * ring( - 'x2_1') + 7 * ring('x0_1') * ring('x2_0') + 6 * ring( - 'x0_1') * ring('x2_1') - 1, - (2, 0): 4 * ring('x0_0') * ring('x1_0') + 4 * ring('x0_0') * ring( - 'x1_1') + 5 * ring('x0_1') * ring('x1_0') + 2 * ring( - 'x0_1') * ring('x1_1') - 1, - (2, 1): ring('x0_0') * ring('x1_0') + 8 * ring('x0_0') * ring( - 'x1_1') + 6 * ring('x0_1') * ring('x1_0') + 7 * ring( - 'x0_1') * ring('x1_1') - 1} + (0, 0): 2 * ring("x1_0") * ring("x2_0") + + ring("x1_0") * ring("x2_1") + + 8 * ring("x1_1") * ring("x2_0") + + 3 * ring("x1_1") * ring("x2_1") + - 1, + (0, 1): 7 * ring("x1_0") * ring("x2_0") + + 4 * ring("x1_0") * ring("x2_1") + + 6 * ring("x1_1") * ring("x2_0") + + 5 * ring("x1_1") * ring("x2_1") + - 1, + (1, 0): 8 * ring("x0_0") * ring("x2_0") + + 5 * ring("x0_0") * ring("x2_1") + + 2 * ring("x0_1") * ring("x2_0") + + 3 * ring("x0_1") * ring("x2_1") + - 1, + (1, 1): ring("x0_0") * ring("x2_0") + + 4 * ring("x0_0") * ring("x2_1") + + 7 * ring("x0_1") * ring("x2_0") + + 6 * ring("x0_1") * ring("x2_1") + - 1, + (2, 0): 4 * ring("x0_0") * ring("x1_0") + + 4 * ring("x0_0") * ring("x1_1") + + 5 * ring("x0_1") * ring("x1_0") + + 2 * ring("x0_1") * ring("x1_1") + - 1, + (2, 1): ring("x0_0") * ring("x1_0") + + 8 * ring("x0_0") * ring("x1_1") + + 6 * ring("x0_1") * ring("x1_0") + + 7 * ring("x0_1") * ring("x1_1") + - 1, + } def test_substitute1(pcp_3player_nfg): ring = pcp_3player_nfg.ring - x_dico = {ring('x0_1'): 0, ring('x1_1'): 0, ring('x2_1'): 0} + x_dico = {ring("x0_1"): 0, ring("x1_1"): 0, ring("x2_1"): 0} assert pcp_3player_nfg.substitute(x_dico, 2).couple_to_poly == { - (0, 0): 2 * ring('x1_0') * ring('x2_0') * ring('y2_0') - 1, - (0, 1): 7 * ring('x1_0') * ring('x2_0') * ring('y2_0') - 1, - (1, 0): 8 * ring('x0_0') * ring('x2_0') * ring('y2_0') - 1, - (1, 1): ring('x0_0') * ring('x2_0') * ring('y2_0') - 1, - (2, 0): 4 * ring('x0_0') * ring('x1_0') * ring('y2_0') - 1, - (2, 1): ring('x0_0') * ring('x1_0') * ring('y2_0') - 1} + (0, 0): 2 * ring("x1_0") * ring("x2_0") * ring("y2_0") - 1, + (0, 1): 7 * ring("x1_0") * ring("x2_0") * ring("y2_0") - 1, + (1, 0): 8 * ring("x0_0") * ring("x2_0") * ring("y2_0") - 1, + (1, 1): ring("x0_0") * ring("x2_0") * ring("y2_0") - 1, + (2, 0): 4 * ring("x0_0") * ring("x1_0") * ring("y2_0") - 1, + (2, 1): ring("x0_0") * ring("x1_0") * ring("y2_0") - 1, + } def test_substitute1b(pcp_3player_nfg_no_y): ring = pcp_3player_nfg_no_y.ring - x_dico = {ring('x0_1'): 0, ring('x1_1'): 0, ring('x2_1'): 0} + x_dico = {ring("x0_1"): 0, ring("x1_1"): 0, ring("x2_1"): 0} assert pcp_3player_nfg_no_y.substitute(x_dico, 2).couple_to_poly == { - (0, 0): 2 * ring('x1_0') * ring('x2_0') - 1, - (0, 1): 7 * ring('x1_0') * ring('x2_0') - 1, - (1, 0): 8 * ring('x0_0') * ring('x2_0') - 1, - (1, 1): ring('x0_0') * ring('x2_0') - 1, - (2, 0): 4 * ring('x0_0') * ring('x1_0') - 1, - (2, 1): ring('x0_0') * ring('x1_0') - 1} + (0, 0): 2 * ring("x1_0") * ring("x2_0") - 1, + (0, 1): 7 * ring("x1_0") * ring("x2_0") - 1, + (1, 0): 8 * ring("x0_0") * ring("x2_0") - 1, + (1, 1): ring("x0_0") * ring("x2_0") - 1, + (2, 0): 4 * ring("x0_0") * ring("x1_0") - 1, + (2, 1): ring("x0_0") * ring("x1_0") - 1, + } def test_substitute2(pcp_3player_nfg): ring = pcp_3player_nfg.ring - x_dico = {ring('x0_1'): 0, ring('x1_1'): 0, ring('x2_1'): 0} + x_dico = {ring("x0_1"): 0, ring("x1_1"): 0, ring("x2_1"): 0} assert pcp_3player_nfg.substitute(x_dico, 1).couple_to_poly == { - (0, 0): 2 * ring('x1_0') * ring('x2_0') * ring('y2_0') - 1, - (0, 1): 7 * ring('x1_0') * ring('x2_0') * ring('y2_0') - 1, - (1, 0): 8 * ring('x0_0') * ring('x2_0') * ring('y2_0') - 1, - (1, 1): ring('x0_0') * ring('x2_0') * ring('y2_0') - 1} + (0, 0): 2 * ring("x1_0") * ring("x2_0") * ring("y2_0") - 1, + (0, 1): 7 * ring("x1_0") * ring("x2_0") * ring("y2_0") - 1, + (1, 0): 8 * ring("x0_0") * ring("x2_0") * ring("y2_0") - 1, + (1, 1): ring("x0_0") * ring("x2_0") * ring("y2_0") - 1, + } def test_substitute2b(pcp_3player_nfg_no_y): ring = pcp_3player_nfg_no_y.ring - x_dico = {ring('x0_1'): 0, ring('x1_1'): 0, ring('x2_1'): 0} + x_dico = {ring("x0_1"): 0, ring("x1_1"): 0, ring("x2_1"): 0} assert pcp_3player_nfg_no_y.substitute(x_dico, 1).couple_to_poly == { - (0, 0): 2 * ring('x1_0') * ring('x2_0') - 1, - (0, 1): 7 * ring('x1_0') * ring('x2_0') - 1, - (1, 0): 8 * ring('x0_0') * ring('x2_0') - 1, - (1, 1): ring('x0_0') * ring('x2_0') - 1} + (0, 0): 2 * ring("x1_0") * ring("x2_0") - 1, + (0, 1): 7 * ring("x1_0") * ring("x2_0") - 1, + (1, 0): 8 * ring("x0_0") * ring("x2_0") - 1, + (1, 1): ring("x0_0") * ring("x2_0") - 1, + } def test_substitute3(pcp_3player_nfg): ring = pcp_3player_nfg.ring - x_dico = {ring('x0_1'): 0, ring('x1_1'): 0, ring('x2_1'): 0} + x_dico = {ring("x0_1"): 0, ring("x1_1"): 0, ring("x2_1"): 0} assert pcp_3player_nfg.substitute(x_dico, 0).couple_to_poly == { - (0, 0): 2 * ring('x1_0') * ring('x2_0') * ring('y2_0') - 1, - (0, 1): 7 * ring('x1_0') * ring('x2_0') * ring('y2_0') - 1 - } + (0, 0): 2 * ring("x1_0") * ring("x2_0") * ring("y2_0") - 1, + (0, 1): 7 * ring("x1_0") * ring("x2_0") * ring("y2_0") - 1, + } def test_substitute3b(pcp_3player_nfg_no_y): ring = pcp_3player_nfg_no_y.ring - x_dico = {ring('x0_1'): 0, ring('x1_1'): 0, ring('x2_1'): 0} + x_dico = {ring("x0_1"): 0, ring("x1_1"): 0, ring("x2_1"): 0} assert pcp_3player_nfg_no_y.substitute(x_dico, 0).couple_to_poly == { - (0, 0): 2 * ring('x1_0') * ring('x2_0') - 1, - (0, 1): 7 * ring('x1_0') * ring('x2_0') - 1 - } + (0, 0): 2 * ring("x1_0") * ring("x2_0") - 1, + (0, 1): 7 * ring("x1_0") * ring("x2_0") - 1, + } def test_substitute4(pcp_3player_nfg): ring = pcp_3player_nfg.ring - x_dico = {ring('x0_1'): 0, ring('x1_1'): 0} + x_dico = {ring("x0_1"): 0, ring("x1_1"): 0} assert pcp_3player_nfg.substitute(x_dico, 2).couple_to_poly == { - (0, 0): 2 * ring('x1_0') * ring('x2_0') * ring('y2_0') + ring( - 'x1_0') * ring('x2_1') * ring('y2_0') - 1, - (0, 1): 7 * ring('x1_0') * ring('x2_0') * ring('y2_0') + 4 * ring( - 'x1_0') * ring('x2_1') * ring('y2_0') - 1, - (1, 0): 8 * ring('x0_0') * ring('x2_0') * ring('y2_0') + 5 * ring( - 'x0_0') * ring('x2_1') * ring('y2_0') - 1, - (1, 1): ring('x0_0') * ring('x2_0') * ring('y2_0') + 4 * ring( - 'x0_0') * ring('x2_1') * ring('y2_0') - 1, - (2, 0): 4 * ring('x0_0') * ring('x1_0') * ring('y2_0') - 1, - (2, 1): ring('x0_0') * ring('x1_0') * ring('y2_0') - 1} + (0, 0): 2 * ring("x1_0") * ring("x2_0") * ring("y2_0") + + ring("x1_0") * ring("x2_1") * ring("y2_0") + - 1, + (0, 1): 7 * ring("x1_0") * ring("x2_0") * ring("y2_0") + + 4 * ring("x1_0") * ring("x2_1") * ring("y2_0") + - 1, + (1, 0): 8 * ring("x0_0") * ring("x2_0") * ring("y2_0") + + 5 * ring("x0_0") * ring("x2_1") * ring("y2_0") + - 1, + (1, 1): ring("x0_0") * ring("x2_0") * ring("y2_0") + + 4 * ring("x0_0") * ring("x2_1") * ring("y2_0") + - 1, + (2, 0): 4 * ring("x0_0") * ring("x1_0") * ring("y2_0") - 1, + (2, 1): ring("x0_0") * ring("x1_0") * ring("y2_0") - 1, + } def test_substitute4b(pcp_3player_nfg_no_y): ring = pcp_3player_nfg_no_y.ring - x_dico = {ring('x0_1'): 0, ring('x1_1'): 0} + x_dico = {ring("x0_1"): 0, ring("x1_1"): 0} assert pcp_3player_nfg_no_y.substitute(x_dico, 2).couple_to_poly == { - (0, 0): 2 * ring('x1_0') * ring('x2_0') + ring( - 'x1_0') * ring('x2_1') - 1, - (0, 1): 7 * ring('x1_0') * ring('x2_0') + 4 * ring( - 'x1_0') * ring('x2_1') - 1, - (1, 0): 8 * ring('x0_0') * ring('x2_0') + 5 * ring( - 'x0_0') * ring('x2_1') - 1, - (1, 1): ring('x0_0') * ring('x2_0') + 4 * ring( - 'x0_0') * ring('x2_1') - 1, - (2, 0): 4 * ring('x0_0') * ring('x1_0') - 1, - (2, 1): ring('x0_0') * ring('x1_0') - 1} + (0, 0): 2 * ring("x1_0") * ring("x2_0") + ring("x1_0") * ring("x2_1") - 1, + (0, 1): 7 * ring("x1_0") * ring("x2_0") + 4 * ring("x1_0") * ring("x2_1") - 1, + (1, 0): 8 * ring("x0_0") * ring("x2_0") + 5 * ring("x0_0") * ring("x2_1") - 1, + (1, 1): ring("x0_0") * ring("x2_0") + 4 * ring("x0_0") * ring("x2_1") - 1, + (2, 0): 4 * ring("x0_0") * ring("x1_0") - 1, + (2, 1): ring("x0_0") * ring("x1_0") - 1, + } + # Substitue for Hgg? @@ -500,41 +670,46 @@ def subsys_empty_no_y(pcp_3player_nfg_no_y): def subsys_3p_2l_n1(pcp_3player_nfg): # return Subsystem(pcp_3player_nfg,[(0,1),(1,0),(2,0)] # ,[(1,1),(0,0),(2,0)],2,{}) - return Subsystem(pcp_3player_nfg, [(2, 1)], - [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0)], 2, {}) + return Subsystem( + pcp_3player_nfg, [(2, 1)], [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0)], 2, {} + ) @pytest.fixture def subsys_3p_2l_n1_no_y(pcp_3player_nfg_no_y): # return Subsystem(pcp_3player_nfg,[(0,1),(1,0),(2,0)] # ,[(1,1),(0,0),(2,0)],2,{}) - return Subsystem(pcp_3player_nfg_no_y, [(2, 1)], - [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0)], 2, {}) + return Subsystem( + pcp_3player_nfg_no_y, [(2, 1)], [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0)], 2, {} + ) @pytest.fixture def subsys_3p_2l_n2(pcp_3player_nfg): # return Subsystem(pcp_3player_nfg,[(0,1),(1,0),(2,0)], # [(1,1),(0,0),(2,1)],2,{}) - return Subsystem(pcp_3player_nfg, [(2, 1)], - [(0, 0), (0, 1), (1, 0), (1, 1), (2, 1)], 2, {}) + return Subsystem( + pcp_3player_nfg, [(2, 1)], [(0, 0), (0, 1), (1, 0), (1, 1), (2, 1)], 2, {} + ) @pytest.fixture def subsys_3p_2l_n2_no_y(pcp_3player_nfg_no_y): # return Subsystem(pcp_3player_nfg,[(0,1),(1,0),(2,0)], # [(1,1),(0,0),(2,1)],2,{}) - return Subsystem(pcp_3player_nfg_no_y, [(2, 1)], - [(0, 0), (0, 1), (1, 0), (1, 1), (2, 1)], 2, {}) + return Subsystem( + pcp_3player_nfg_no_y, [(2, 1)], [(0, 0), (0, 1), (1, 0), (1, 1), (2, 1)], 2, {} + ) def test_equations1(subsys_empty): ring = subsys_empty.ring - assert set( - subsys_empty.equations - ) == {ring('y0_0') - 1, ring('y1_0') - - ring('y0_0'), ring('y2_0') - - ring('y1_0')} + assert set(subsys_empty.equations) == { + ring("y0_0") - 1, + ring("y1_0") - ring("y0_0"), + ring("y2_0") - ring("y1_0"), + } + # def test_equations1b(subsys_empty_no_y): # # ring = subsys_empty_no_y.ring @@ -548,146 +723,162 @@ def test_equations1(subsys_empty): def test_equations2(subsys_3p_2l_n1, pcp_3player_nfg): ring = subsys_3p_2l_n1.ring - dico_x0 = {ring('x2_1'): 0} - assert set( - subsys_3p_2l_n1.equations - ) == {ring('x2_1'), pcp_3player_nfg.couple_to_poly[(0, 0)].subs(dico_x0), - pcp_3player_nfg.couple_to_poly[(0, 1)].subs(dico_x0), - pcp_3player_nfg.couple_to_poly[(1, 0)].subs(dico_x0), - pcp_3player_nfg.couple_to_poly[(1, 1)].subs(dico_x0), - pcp_3player_nfg.couple_to_poly[(2, 0)].subs(dico_x0), - ring('y0_0') - 1, ring('y1_0') - ring('y0_0'), - ring('y2_0') - ring('y1_0')} + dico_x0 = {ring("x2_1"): 0} + assert set(subsys_3p_2l_n1.equations) == { + ring("x2_1"), + pcp_3player_nfg.couple_to_poly[(0, 0)].subs(dico_x0), + pcp_3player_nfg.couple_to_poly[(0, 1)].subs(dico_x0), + pcp_3player_nfg.couple_to_poly[(1, 0)].subs(dico_x0), + pcp_3player_nfg.couple_to_poly[(1, 1)].subs(dico_x0), + pcp_3player_nfg.couple_to_poly[(2, 0)].subs(dico_x0), + ring("y0_0") - 1, + ring("y1_0") - ring("y0_0"), + ring("y2_0") - ring("y1_0"), + } def test_equations2b(subsys_3p_2l_n1_no_y, pcp_3player_nfg_no_y): ring = subsys_3p_2l_n1_no_y.ring - dico_x0 = {ring('x2_1'): 0} - assert set( - subsys_3p_2l_n1_no_y.equations - ) == {ring('x2_1'), - pcp_3player_nfg_no_y.couple_to_poly[(0, 0)].subs(dico_x0), - pcp_3player_nfg_no_y.couple_to_poly[(0, 1)].subs(dico_x0), - pcp_3player_nfg_no_y.couple_to_poly[(1, 0)].subs(dico_x0), - pcp_3player_nfg_no_y.couple_to_poly[(1, 1)].subs(dico_x0), - pcp_3player_nfg_no_y.couple_to_poly[(2, 0)].subs(dico_x0)} + dico_x0 = {ring("x2_1"): 0} + assert set(subsys_3p_2l_n1_no_y.equations) == { + ring("x2_1"), + pcp_3player_nfg_no_y.couple_to_poly[(0, 0)].subs(dico_x0), + pcp_3player_nfg_no_y.couple_to_poly[(0, 1)].subs(dico_x0), + pcp_3player_nfg_no_y.couple_to_poly[(1, 0)].subs(dico_x0), + pcp_3player_nfg_no_y.couple_to_poly[(1, 1)].subs(dico_x0), + pcp_3player_nfg_no_y.couple_to_poly[(2, 0)].subs(dico_x0), + } def test_equations3(subsys_3p_2l_n2, pcp_3player_nfg): ring = subsys_3p_2l_n2.ring - dico_x0 = {ring('x2_1'): 0} - assert set( - subsys_3p_2l_n2.equations - ) == {ring('x2_1'), - pcp_3player_nfg.couple_to_poly[(0, 0)].subs(dico_x0), - pcp_3player_nfg.couple_to_poly[(0, 1)].subs(dico_x0), - pcp_3player_nfg.couple_to_poly[(1, 0)].subs(dico_x0), - pcp_3player_nfg.couple_to_poly[(1, 1)].subs(dico_x0), - pcp_3player_nfg.couple_to_poly[(2, 1)].subs(dico_x0), - ring('y0_0') - 1, - ring('y1_0') - ring('y0_0'), - ring('y2_0') - ring('y1_0')} + dico_x0 = {ring("x2_1"): 0} + assert set(subsys_3p_2l_n2.equations) == { + ring("x2_1"), + pcp_3player_nfg.couple_to_poly[(0, 0)].subs(dico_x0), + pcp_3player_nfg.couple_to_poly[(0, 1)].subs(dico_x0), + pcp_3player_nfg.couple_to_poly[(1, 0)].subs(dico_x0), + pcp_3player_nfg.couple_to_poly[(1, 1)].subs(dico_x0), + pcp_3player_nfg.couple_to_poly[(2, 1)].subs(dico_x0), + ring("y0_0") - 1, + ring("y1_0") - ring("y0_0"), + ring("y2_0") - ring("y1_0"), + } def test_equations3b(subsys_3p_2l_n2_no_y, pcp_3player_nfg_no_y): ring = subsys_3p_2l_n2_no_y.ring - dico_x0 = {ring('x2_1'): 0} - assert set( - subsys_3p_2l_n2_no_y.equations - ) == {ring('x2_1'), - pcp_3player_nfg_no_y.couple_to_poly[(0, 0)].subs(dico_x0), - pcp_3player_nfg_no_y.couple_to_poly[(0, 1)].subs(dico_x0), - pcp_3player_nfg_no_y.couple_to_poly[(1, 0)].subs(dico_x0), - pcp_3player_nfg_no_y.couple_to_poly[(1, 1)].subs(dico_x0), - pcp_3player_nfg_no_y.couple_to_poly[(2, 1)].subs(dico_x0) - } + dico_x0 = {ring("x2_1"): 0} + assert set(subsys_3p_2l_n2_no_y.equations) == { + ring("x2_1"), + pcp_3player_nfg_no_y.couple_to_poly[(0, 0)].subs(dico_x0), + pcp_3player_nfg_no_y.couple_to_poly[(0, 1)].subs(dico_x0), + pcp_3player_nfg_no_y.couple_to_poly[(1, 0)].subs(dico_x0), + pcp_3player_nfg_no_y.couple_to_poly[(1, 1)].subs(dico_x0), + pcp_3player_nfg_no_y.couple_to_poly[(2, 1)].subs(dico_x0), + } def test_inequations1(subsys_empty, pcp_3player_nfg): - assert set(subsys_empty.inequations) == set( - pcp_3player_nfg.couple_to_poly.values()) + assert set(subsys_empty.inequations) == set(pcp_3player_nfg.couple_to_poly.values()) def test_inequations2(subsys_3p_2l_n1, pcp_3player_nfg): ring = subsys_3p_2l_n1.ring - dico_x0 = {ring('x2_1'): 0} + dico_x0 = {ring("x2_1"): 0} assert set(subsys_3p_2l_n1.inequations) == { - pcp_3player_nfg.couple_to_poly[(2, 1)].subs(dico_x0)} + pcp_3player_nfg.couple_to_poly[(2, 1)].subs(dico_x0) + } def test_inequations2b(subsys_3p_2l_n1_no_y, pcp_3player_nfg_no_y): ring = subsys_3p_2l_n1_no_y.ring - dico_x0 = {ring('x2_1'): 0} + dico_x0 = {ring("x2_1"): 0} assert set(subsys_3p_2l_n1_no_y.inequations) == { - pcp_3player_nfg_no_y.couple_to_poly[(2, 1)].subs(dico_x0)} + pcp_3player_nfg_no_y.couple_to_poly[(2, 1)].subs(dico_x0) + } def test_inequations3(subsys_3p_2l_n2, pcp_3player_nfg): ring = subsys_3p_2l_n2.ring - dico_x0 = {ring('x2_1'): 0} + dico_x0 = {ring("x2_1"): 0} assert set(subsys_3p_2l_n2.inequations) == { - pcp_3player_nfg.couple_to_poly[(2, 0)].subs(dico_x0)} + pcp_3player_nfg.couple_to_poly[(2, 0)].subs(dico_x0) + } def test_inequations3b(subsys_3p_2l_n2_no_y, pcp_3player_nfg_no_y): ring = subsys_3p_2l_n2_no_y.ring - dico_x0 = {ring('x2_1'): 0} + dico_x0 = {ring("x2_1"): 0} assert set(subsys_3p_2l_n2_no_y.inequations) == { - pcp_3player_nfg_no_y.couple_to_poly[(2, 0)].subs(dico_x0)} + pcp_3player_nfg_no_y.couple_to_poly[(2, 0)].subs(dico_x0) + } def test_ideal1(subsys_3p_2l_n1, pcp_3player_nfg): ring = subsys_3p_2l_n1.ring - dico_x0 = {ring('x2_1'): 0} - assert subsys_3p_2l_n1.ideal ==\ - ideal([ring('x2_1'), - pcp_3player_nfg.couple_to_poly[(0, 0)].subs(dico_x0), - pcp_3player_nfg.couple_to_poly[(0, 1)].subs(dico_x0), - pcp_3player_nfg.couple_to_poly[(1, 0)].subs(dico_x0), - pcp_3player_nfg.couple_to_poly[(1, 1)].subs(dico_x0), - pcp_3player_nfg.couple_to_poly[(2, 0)].subs(dico_x0), - ring('y0_0') - 1, - ring('y1_0') - ring('y0_0'), - ring('y2_0') - ring('y1_0')]) + dico_x0 = {ring("x2_1"): 0} + assert subsys_3p_2l_n1.ideal == ideal( + [ + ring("x2_1"), + pcp_3player_nfg.couple_to_poly[(0, 0)].subs(dico_x0), + pcp_3player_nfg.couple_to_poly[(0, 1)].subs(dico_x0), + pcp_3player_nfg.couple_to_poly[(1, 0)].subs(dico_x0), + pcp_3player_nfg.couple_to_poly[(1, 1)].subs(dico_x0), + pcp_3player_nfg.couple_to_poly[(2, 0)].subs(dico_x0), + ring("y0_0") - 1, + ring("y1_0") - ring("y0_0"), + ring("y2_0") - ring("y1_0"), + ] + ) def test_ideal1b(subsys_3p_2l_n1_no_y, pcp_3player_nfg_no_y): ring = subsys_3p_2l_n1_no_y.ring - dico_x0 = {ring('x2_1'): 0} - assert subsys_3p_2l_n1_no_y.ideal ==\ - ideal([ring('x2_1'), - pcp_3player_nfg_no_y.couple_to_poly[(0, 0)].subs(dico_x0), - pcp_3player_nfg_no_y.couple_to_poly[(0, 1)].subs(dico_x0), - pcp_3player_nfg_no_y.couple_to_poly[(1, 0)].subs(dico_x0), - pcp_3player_nfg_no_y.couple_to_poly[(1, 1)].subs(dico_x0), - pcp_3player_nfg_no_y.couple_to_poly[(2, 0)].subs(dico_x0)]) + dico_x0 = {ring("x2_1"): 0} + assert subsys_3p_2l_n1_no_y.ideal == ideal( + [ + ring("x2_1"), + pcp_3player_nfg_no_y.couple_to_poly[(0, 0)].subs(dico_x0), + pcp_3player_nfg_no_y.couple_to_poly[(0, 1)].subs(dico_x0), + pcp_3player_nfg_no_y.couple_to_poly[(1, 0)].subs(dico_x0), + pcp_3player_nfg_no_y.couple_to_poly[(1, 1)].subs(dico_x0), + pcp_3player_nfg_no_y.couple_to_poly[(2, 0)].subs(dico_x0), + ] + ) def test_ideal2(subsys_3p_2l_n2, pcp_3player_nfg): ring = subsys_3p_2l_n2.ring - dico_x0 = {ring('x2_1'): 0} - assert subsys_3p_2l_n2.ideal == \ - ideal([ring('x2_1'), - pcp_3player_nfg.couple_to_poly[(0, 0)].subs(dico_x0), - pcp_3player_nfg.couple_to_poly[(0, 1)].subs(dico_x0), - pcp_3player_nfg.couple_to_poly[(1, 0)].subs(dico_x0), - pcp_3player_nfg.couple_to_poly[(1, 1)].subs(dico_x0), - pcp_3player_nfg.couple_to_poly[(2, 1)].subs(dico_x0), - ring('y0_0') - 1, - ring('y1_0') - ring('y0_0'), - ring('y2_0') - ring('y1_0')]) + dico_x0 = {ring("x2_1"): 0} + assert subsys_3p_2l_n2.ideal == ideal( + [ + ring("x2_1"), + pcp_3player_nfg.couple_to_poly[(0, 0)].subs(dico_x0), + pcp_3player_nfg.couple_to_poly[(0, 1)].subs(dico_x0), + pcp_3player_nfg.couple_to_poly[(1, 0)].subs(dico_x0), + pcp_3player_nfg.couple_to_poly[(1, 1)].subs(dico_x0), + pcp_3player_nfg.couple_to_poly[(2, 1)].subs(dico_x0), + ring("y0_0") - 1, + ring("y1_0") - ring("y0_0"), + ring("y2_0") - ring("y1_0"), + ] + ) def test_ideal2b(subsys_3p_2l_n2_no_y, pcp_3player_nfg_no_y): ring = subsys_3p_2l_n2_no_y.ring - dico_x0 = {ring('x2_1'): 0} - assert subsys_3p_2l_n2_no_y.ideal == \ - ideal([ring('x2_1'), - pcp_3player_nfg_no_y.couple_to_poly[(0, 0)].subs(dico_x0), - pcp_3player_nfg_no_y.couple_to_poly[(0, 1)].subs(dico_x0), - pcp_3player_nfg_no_y.couple_to_poly[(1, 0)].subs(dico_x0), - pcp_3player_nfg_no_y.couple_to_poly[(1, 1)].subs(dico_x0), - pcp_3player_nfg_no_y.couple_to_poly[(2, 1)].subs(dico_x0)]) + dico_x0 = {ring("x2_1"): 0} + assert subsys_3p_2l_n2_no_y.ideal == ideal( + [ + ring("x2_1"), + pcp_3player_nfg_no_y.couple_to_poly[(0, 0)].subs(dico_x0), + pcp_3player_nfg_no_y.couple_to_poly[(0, 1)].subs(dico_x0), + pcp_3player_nfg_no_y.couple_to_poly[(1, 0)].subs(dico_x0), + pcp_3player_nfg_no_y.couple_to_poly[(1, 1)].subs(dico_x0), + pcp_3player_nfg_no_y.couple_to_poly[(2, 1)].subs(dico_x0), + ] + ) def test_compute_variety1(subsys_3p_2l_n1): diff --git a/test/test_wilson_algorithm.py b/test/test_wilson_algorithm.py index eed6e3a..4020a36 100644 --- a/test/test_wilson_algorithm.py +++ b/test/test_wilson_algorithm.py @@ -1,11 +1,14 @@ # import numpy as np import pytest + # from fractions import Fraction from sage.all import QQ from gtnash.solver.wilsonalgorithm import Node, irda_on_game, first_node -from gtnash.util.polynomial_complementary_problem import \ - PolynomialComplementaryProblem, Subsystem +from gtnash.util.polynomial_complementary_problem import ( + PolynomialComplementaryProblem, + Subsystem, +) from gtnash.game.normalformgame import NFG from gtnash.game.hypergraphicalgame import HGG @@ -13,8 +16,11 @@ from gtnash.game.hypergraphicalgame import HGG @pytest.fixture def nfg_3player(): players_actions = [[0, 1], [0, 1], [0, 1]] - utilities = [[6, 7, 0, 5, 1, 4, 2, 3], [0, 3, 7, 4, 6, 5, 1, 2], - [4, 7, 4, 0, 3, 2, 6, 1]] + utilities = [ + [6, 7, 0, 5, 1, 4, 2, 3], + [0, 3, 7, 4, 6, 5, 1, 2], + [4, 7, 4, 0, 3, 2, 6, 1], + ] return NFG(players_actions, utilities) # return PolynomialComplementaryProblem(current_nfg) @@ -25,7 +31,8 @@ def nfg_4degen(): [50, 59, 27, 4, 72, 69, 18, 35, 6, 89, 78, 19, 36, 76, 64, 20], [97, 5, 90, 60, 6, 13, 56, 82, 89, 79, 52, 34, 35, 100, 60, 34], [15, 30, 53, 12, 79, 77, 15, 38, 100, 82, 35, 10, 24, 0, 29, 27], - [28, 66, 83, 1, 54, 89, 71, 35, 46, 62, 96, 26, 20, 58, 16, 81]] + [28, 66, 83, 1, 54, 89, 71, 35, 46, 62, 96, 26, 20, 58, 16, 81], + ] players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] return NFG(players_actions, utilities) @@ -33,9 +40,11 @@ def nfg_4degen(): @pytest.fixture def nfg_3descent(): players_actions = [[0, 1], [0, 1], [0, 1]] - utilities = [[19, 58, 64, 66, 87, 52, 59, 79], - [73, 23, 80, 0, 100, 89, 43, 69], - [77, 60, 29, 35, 52, 98, 19, 70]] + utilities = [ + [19, 58, 64, 66, 87, 52, 59, 79], + [73, 23, 80, 0, 100, 89, 43, 69], + [77, 60, 29, 35, 52, 98, 19, 70], + ] return NFG(players_actions, utilities) @@ -43,9 +52,14 @@ def nfg_3descent(): def hgg1(): players_actions = [[0, 1], [0, 1], [0, 1], [0, 1]] utilities = [ - [[-3, -7, -7, -10, -1, -5, -5, -9], [-3, -7, -1, -5, -7, -10, -5, -9], - [-3, -1, -7, -5, -7, -5, -10, -9]], - [[-1, -5, 0, -3], [-1, 0, -5, -3]], [[-1, -5, 0, -3], [-1, 0, -5, -3]]] + [ + [-3, -7, -7, -10, -1, -5, -5, -9], + [-3, -7, -1, -5, -7, -10, -5, -9], + [-3, -1, -7, -5, -7, -5, -10, -9], + ], + [[-1, -5, 0, -3], [-1, 0, -5, -3]], + [[-1, -5, 0, -3], [-1, 0, -5, -3]], + ] hypergraph = [[0, 1, 2], [1, 3], [2, 3]] return HGG(players_actions, utilities, hypergraph) @@ -56,7 +70,7 @@ def pcp_of_game(game): def x_pairval_of_pcp(pcp): xpairs_val = {} - for (n, i) in pcp.couple_to_x.keys(): + for n, i in pcp.couple_to_x.keys(): if pcp.omega0[n] == i: xpairs_val[(n, i)] = 1 else: @@ -66,6 +80,7 @@ def x_pairval_of_pcp(pcp): # Faire un test_irda.py a part pour plus de test la dessus + def test_irda_on_game1(nfg_3player): red_game, red_var = irda_on_game(nfg_3player) assert (red_game.utilities, red_var) == ([nfg_3player.utilities], []) @@ -84,70 +99,127 @@ def test_irda_on_game3(hgg1): def test_node_complementary1(nfg_3player): pcp = pcp_of_game(nfg_3player) x_pairval = x_pairval_of_pcp(pcp) - sub_sys = Subsystem(pcp, [(2, 1)], - [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0)], 2, x_pairval) - assert Node(pcp, [(2, 1)], [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0)], 2, - x_pairval, sub_sys, sub_sys.solutions[0]).is_complementary + sub_sys = Subsystem( + pcp, [(2, 1)], [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0)], 2, x_pairval + ) + assert Node( + pcp, + [(2, 1)], + [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0)], + 2, + x_pairval, + sub_sys, + sub_sys.solutions[0], + ).is_complementary def test_node_complementary2(nfg_3player): pcp = pcp_of_game(nfg_3player) x_pairval = x_pairval_of_pcp(pcp) - sub_sys = Subsystem(pcp, [(2, 1)], - [(0, 0), (0, 1), (1, 0), (1, 1), (2, 1)], 2, x_pairval) - assert not Node(pcp, [(2, 1)], [(0, 0), (0, 1), (1, 0), (1, 1), (2, 1)], 2, - x_pairval, sub_sys, {}).is_complementary + sub_sys = Subsystem( + pcp, [(2, 1)], [(0, 0), (0, 1), (1, 0), (1, 1), (2, 1)], 2, x_pairval + ) + assert not Node( + pcp, + [(2, 1)], + [(0, 0), (0, 1), (1, 0), (1, 1), (2, 1)], + 2, + x_pairval, + sub_sys, + {}, + ).is_complementary def test_node_complementary3(nfg_3player): pcp = pcp_of_game(nfg_3player) x_pairval = x_pairval_of_pcp(pcp) sub_sys = Subsystem(pcp, [(0, 1)], [(0, 0), (1, 1), (0, 1)], 1, x_pairval) - assert not Node(pcp, [(0, 1)], [(0, 0), (1, 1), (0, 1)], 1, x_pairval, - sub_sys, sub_sys.solutions[0]).is_complementary + assert not Node( + pcp, + [(0, 1)], + [(0, 0), (1, 1), (0, 1)], + 1, + x_pairval, + sub_sys, + sub_sys.solutions[0], + ).is_complementary def test_node_complementary4(nfg_3player): pcp = pcp_of_game(nfg_3player) x_pairval = x_pairval_of_pcp(pcp) - sub_sys = Subsystem(pcp, [], [(0, 0), (1, 1), (0, 1), (1, 0)], 1, - x_pairval) - assert Node(pcp, [], [(0, 0), (1, 1), (0, 1), (1, 0)], 1, x_pairval, - sub_sys, sub_sys.solutions[0]).is_complementary + sub_sys = Subsystem(pcp, [], [(0, 0), (1, 1), (0, 1), (1, 0)], 1, x_pairval) + assert Node( + pcp, + [], + [(0, 0), (1, 1), (0, 1), (1, 0)], + 1, + x_pairval, + sub_sys, + sub_sys.solutions[0], + ).is_complementary def test_node_initial1(nfg_3player): pcp = pcp_of_game(nfg_3player) x_pairval = x_pairval_of_pcp(pcp) - sub_sys = Subsystem(pcp, [(2, 1)], - [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0)], 2, x_pairval) - assert Node(pcp, [(2, 1)], [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0)], 2, - x_pairval, sub_sys, sub_sys.solutions[0]).is_initial + sub_sys = Subsystem( + pcp, [(2, 1)], [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0)], 2, x_pairval + ) + assert Node( + pcp, + [(2, 1)], + [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0)], + 2, + x_pairval, + sub_sys, + sub_sys.solutions[0], + ).is_initial def test_node_initial2(nfg_3player): pcp = pcp_of_game(nfg_3player) x_pairval = x_pairval_of_pcp(pcp) - sub_sys = Subsystem(pcp, [], [(0, 0), (1, 1), (0, 1), (1, 0)], 1, - x_pairval) - assert not Node(pcp, [], [(0, 0), (1, 1), (0, 1), (1, 0)], 1, x_pairval, - sub_sys, sub_sys.solutions[0]).is_initial + sub_sys = Subsystem(pcp, [], [(0, 0), (1, 1), (0, 1), (1, 0)], 1, x_pairval) + assert not Node( + pcp, + [], + [(0, 0), (1, 1), (0, 1), (1, 0)], + 1, + x_pairval, + sub_sys, + sub_sys.solutions[0], + ).is_initial def test_node_initial3(nfg_3player): pcp = pcp_of_game(nfg_3player) x_pairval = x_pairval_of_pcp(pcp) sub_sys = Subsystem(pcp, [(0, 1)], [(0, 0), (1, 1), (0, 1)], 1, x_pairval) - assert not Node(pcp, [(0, 1)], [(0, 0), (1, 1), (0, 1)], 1, x_pairval, - sub_sys, sub_sys.solutions[0]).is_initial + assert not Node( + pcp, + [(0, 1)], + [(0, 0), (1, 1), (0, 1)], + 1, + x_pairval, + sub_sys, + sub_sys.solutions[0], + ).is_initial def test_node_initial4(nfg_3player): pcp = pcp_of_game(nfg_3player) x_pairval = x_pairval_of_pcp(pcp) sub_sys = Subsystem(pcp, [(0, 1), (1, 1)], [(0, 0), (1, 1)], 1, x_pairval) - assert Node(pcp, [(0, 1), (1, 1)], [(0, 0), (1, 1)], 1, x_pairval, sub_sys, - sub_sys.solutions[0]).is_initial + assert Node( + pcp, + [(0, 1), (1, 1)], + [(0, 0), (1, 1)], + 1, + x_pairval, + sub_sys, + sub_sys.solutions[0], + ).is_initial # def test_node_degen1(nfg_3player): @@ -186,13 +258,14 @@ def test_node_initial4(nfg_3player): # assert Node(pcp, [(0, 0), (1, 1)], [(0, 1), (1, 0)], 1, # x_pairval, sub_sys,sub_sys.solutions[0]).is_degenerate + def test_first_node0(nfg_3player): pcp = pcp_of_game(nfg_3player) x_pairval = x_pairval_of_pcp(pcp) first_n = first_node(pcp, x_pairval)[0] assert first_n.set_z == [(0, 1)] assert first_n.set_w == [(0, 0)] - assert first_n.coordinates == {pcp.ring('x0_0'): 1, pcp.ring('x0_1'): 0} + assert first_n.coordinates == {pcp.ring("x0_0"): 1, pcp.ring("x0_1"): 0} def test_first_node1(nfg_4degen): @@ -202,7 +275,7 @@ def test_first_node1(nfg_4degen): first_n = first_node(pcp, x_pairval)[0] assert first_n.set_z == [(0, 0)] assert first_n.set_w == [(0, 1)] - assert first_n.coordinates == {pcp.ring('x0_0'): 0, pcp.ring('x0_1'): 1} + assert first_n.coordinates == {pcp.ring("x0_0"): 0, pcp.ring("x0_1"): 1} def test_first_node2(hgg1): @@ -211,7 +284,7 @@ def test_first_node2(hgg1): first_n = first_node(pcp, x_pairval)[0] assert first_n.set_z == [(0, 0)] assert first_n.set_w == [(0, 1)] - assert first_n.coordinates == {pcp.ring('x0_0'): 0, pcp.ring('x0_1'): 1} + assert first_n.coordinates == {pcp.ring("x0_0"): 0, pcp.ring("x0_1"): 1} def test_lift0(nfg_3player): @@ -228,14 +301,19 @@ def test_lift0(nfg_3player): def test_lift1(nfg_3player): pcp = pcp_of_game(nfg_3player) x_pairval = x_pairval_of_pcp(pcp) - sub_sys = Subsystem(pcp, [], [(0, 0), (1, 1), (0, 1), (1, 0)], 1, - x_pairval) - lift_node = Node(pcp, [], [(0, 0), (1, 1), (0, 1), (1, 0)], - 1, x_pairval, sub_sys, - sub_sys.solutions[0]).lift(pcp, x_pairval)[0] - sub_sys_lift = Subsystem(pcp, [(2, 1)], - [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0)], 2, - x_pairval) + sub_sys = Subsystem(pcp, [], [(0, 0), (1, 1), (0, 1), (1, 0)], 1, x_pairval) + lift_node = Node( + pcp, + [], + [(0, 0), (1, 1), (0, 1), (1, 0)], + 1, + x_pairval, + sub_sys, + sub_sys.solutions[0], + ).lift(pcp, x_pairval)[0] + sub_sys_lift = Subsystem( + pcp, [(2, 1)], [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0)], 2, x_pairval + ) assert set(lift_node.set_z) == {(2, 1)} assert set(lift_node.set_w) == {(0, 0), (0, 1), (1, 0), (1, 1), (2, 0)} assert lift_node.coordinates == sub_sys_lift.solutions[0] @@ -251,8 +329,7 @@ def test_traverse0(nfg_3player): first_n = first_node(pcp, x_pairval)[0] lift_node = first_n.lift(pcp, x_pairval)[0] next_node = lift_node.traverse(first_n, x_pairval)[0] - sub_sys_trav = Subsystem(pcp, [(0, 1)], [(0, 0), (1, 1), (0, 1)], 1, - x_pairval) + sub_sys_trav = Subsystem(pcp, [(0, 1)], [(0, 0), (1, 1), (0, 1)], 1, x_pairval) assert set(next_node.set_z) == {(0, 1)} assert set(next_node.set_w) == {(0, 0), (1, 1), (0, 1)} assert next_node.coordinates == sub_sys_trav.solutions[0] @@ -262,14 +339,20 @@ def test_descent0(nfg_3descent): pcp = pcp_of_game(nfg_3descent) pcp.omega0 = {0: 0, 1: 1, 2: 0} x_pairval = x_pairval_of_pcp(pcp) - sub_sys = Subsystem(pcp, [(2, 1)], - [(0, 0), (1, 1), (2, 1), (1, 0), (0, 1)], 2, x_pairval) - current_node = Node(pcp, [(2, 1)], - [(0, 0), (1, 1), (2, 1), (1, 0), (0, 1)], 2, x_pairval, - sub_sys, sub_sys.solutions[0]) + sub_sys = Subsystem( + pcp, [(2, 1)], [(0, 0), (1, 1), (2, 1), (1, 0), (0, 1)], 2, x_pairval + ) + current_node = Node( + pcp, + [(2, 1)], + [(0, 0), (1, 1), (2, 1), (1, 0), (0, 1)], + 2, + x_pairval, + sub_sys, + sub_sys.solutions[0], + ) descent_node = current_node.descend(pcp, x_pairval)[0] - sub_sys_desc = Subsystem(pcp, [], [(0, 0), (1, 1), (1, 0), (0, 1)], 1, - x_pairval) + sub_sys_desc = Subsystem(pcp, [], [(0, 0), (1, 1), (1, 0), (0, 1)], 1, x_pairval) assert set(descent_node.set_z) == set([]) assert set(descent_node.set_w) == {(0, 0), (1, 1), (1, 0), (0, 1)} assert descent_node.coordinates == sub_sys_desc.solutions[0] @@ -287,9 +370,20 @@ def test_compute_arc0(nfg_3player): def test_normalized_strategy0(nfg_3player): pcp = pcp_of_game(nfg_3player) x_pairval = x_pairval_of_pcp(pcp) - sub_sys = Subsystem(pcp, [(2, 1)], - [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0)], 2, x_pairval) - node = Node(pcp, [(2, 1)], [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0)], 2, - x_pairval, sub_sys, sub_sys.solutions[0]) - assert node.normalized_strategy() == {0: [QQ(5 / 12), QQ(7 / 12)], - 1: [QQ(2 / 7), QQ(5 / 7)], 2: [1, 0]} + sub_sys = Subsystem( + pcp, [(2, 1)], [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0)], 2, x_pairval + ) + node = Node( + pcp, + [(2, 1)], + [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0)], + 2, + x_pairval, + sub_sys, + sub_sys.solutions[0], + ) + assert node.normalized_strategy() == { + 0: [QQ(5 / 12), QQ(7 / 12)], + 1: [QQ(2 / 7), QQ(5 / 7)], + 2: [1, 0], + } -- GitLab From 48ebe006c7a0a2fbc2c003f5d0ef3ca533386496 Mon Sep 17 00:00:00 2001 From: Prasanna Maddila <maddilaprasanna10@gmail.com> Date: Wed, 13 Nov 2024 12:15:48 +0100 Subject: [PATCH 08/13] HypergraphicalGame: Int to delete --- gtnash/game/hypergraphicalgame.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gtnash/game/hypergraphicalgame.py b/gtnash/game/hypergraphicalgame.py index b23a7cd..f438742 100644 --- a/gtnash/game/hypergraphicalgame.py +++ b/gtnash/game/hypergraphicalgame.py @@ -715,8 +715,7 @@ class HGG(AbstractGame): prob_jact_i[n] = p_n_prob expc_util_i = self.expected_utilities(prob_jact_i) for n, val_util in enumerate(expc_util_i): - tmp_util[n] += [int(val_util)] - # Int a supprimer + tmp_util[n] += [val_util] return NFG(self.players_actions, tmp_util) # should be classmethod -- GitLab From c92e0abddf17bc874e23c51e35f04c60663029bf Mon Sep 17 00:00:00 2001 From: ssmaddila <siva-sri-prasanna.maddila@inrae.fr> Date: Thu, 14 Nov 2024 09:16:06 +0100 Subject: [PATCH 09/13] Made test/test_normalformgame.py independent of execution directory. Error was that some filepaths for the read and write tests were using hardcoded paths i.e. if I execute `pytest` from `home/user`, while the test directory is at `home/user/gtnash/test`, the failing tests would look for `filestest/` in `home/user` instead of the test directory. Using `pathlib` to resolve the correct path at runtime solves this. --- test/test_normalformgame.py | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/test/test_normalformgame.py b/test/test_normalformgame.py index 268ccf6..aaa1299 100644 --- a/test/test_normalformgame.py +++ b/test/test_normalformgame.py @@ -1,9 +1,13 @@ +import pathlib import numpy as np import pytest from gtnash.game.normalformgame import NFG from fractions import Fraction +PATH = pathlib.Path(__file__).parent.resolve() +FILESTEST = PATH / "filestest" + """ Separate assert in multiple fucntion """ @@ -780,13 +784,13 @@ def test_get_subgame_fixed_strat4(bimat_nfg): def test_readNFGpayoff1(): - read_game = NFG.readNFGpayoff("filestest/e02.nfg") + read_game = NFG.readNFGpayoff(FILESTEST / "e02.nfg") assert read_game.players_actions == [[0, 1], [0, 1, 2]] assert read_game.utilities == [[1, 2, 2, 1, 3, 0], [1, 0, 0, 1, 0, 2]] def test_readNFGpayoff2(): - read_game = NFG.readNFGpayoff("filestest/RandG_0.nfg") + read_game = NFG.readNFGpayoff(FILESTEST / "RandG_0.nfg") assert read_game.players_actions == [[0, 1], [0, 1], [0, 1]] assert read_game.utilities == [ [43, 38, 1, 63, 61, 21, 12, 46], @@ -796,7 +800,7 @@ def test_readNFGpayoff2(): def test_readNFGpayoff3(): - read_game = NFG.readNFGpayoff("filestest/custom_game1.nfg") + read_game = NFG.readNFGpayoff(FILESTEST / "custom_game1.nfg") assert read_game.players_actions == [[0, 1, 2], [0, 1, 2], [0, 1]] assert read_game.utilities == [ [91, 49, 69, 98, 95, 15, 70, 59, 68, 52, 45, 22, 14, 37, 54, 58, 41, 92], @@ -806,34 +810,34 @@ def test_readNFGpayoff3(): def test_readNFGpayoff4(): - read_game = NFG.readNFGpayoff("filestest/custom_game2.nfg") + read_game = NFG.readNFGpayoff(FILESTEST / "custom_game2.nfg") assert read_game.players_actions == [[0, 1], [0, 1]] assert read_game.utilities == [[-69, -67, -100, -14], [-64, -86, -65, -75]] def test_writeNFGpayoff1(first_nfg): - first_nfg.writeNFGpayoff("filestest/first_nfg.nfg") - read_game = NFG.readNFGpayoff("filestest/first_nfg.nfg") + first_nfg.writeNFGpayoff(FILESTEST / "first_nfg.nfg") + read_game = NFG.readNFGpayoff(FILESTEST / "first_nfg.nfg") assert read_game.players_actions == first_nfg.players_actions assert read_game.utilities == first_nfg.utilities def test_writeNFGpayoff2(second_nfg): - second_nfg.writeNFGpayoff("filestest/second_nfg.nfg") - read_game = NFG.readNFGpayoff("filestest/second_nfg.nfg") + second_nfg.writeNFGpayoff(FILESTEST / "second_nfg.nfg") + read_game = NFG.readNFGpayoff(FILESTEST / "second_nfg.nfg") assert read_game.players_actions == second_nfg.players_actions assert read_game.utilities == second_nfg.utilities def test_writeNFGpayoff3(third_nfg): - third_nfg.writeNFGpayoff("filestest/third_nfg.nfg") - read_game = NFG.readNFGpayoff("filestest/third_nfg.nfg") + third_nfg.writeNFGpayoff(FILESTEST / "third_nfg.nfg") + read_game = NFG.readNFGpayoff(FILESTEST / "third_nfg.nfg") assert read_game.players_actions == third_nfg.players_actions assert read_game.utilities == third_nfg.utilities def test_writeNFGpayoff4(bimat_nfg): - bimat_nfg.writeNFGpayoff("filestest/bimat_nfg.nfg") - read_game = NFG.readNFGpayoff("filestest/bimat_nfg.nfg") + bimat_nfg.writeNFGpayoff(FILESTEST / "bimat_nfg.nfg") + read_game = NFG.readNFGpayoff(FILESTEST / "bimat_nfg.nfg") assert read_game.players_actions == bimat_nfg.players_actions assert read_game.utilities == bimat_nfg.utilities -- GitLab From 14f81b5cee73af0806530f7f4abf5bd64b4a42a7 Mon Sep 17 00:00:00 2001 From: ssmaddila <siva-sri-prasanna.maddila@inrae.fr> Date: Thu, 28 Nov 2024 13:09:25 +0100 Subject: [PATCH 10/13] Detecting the right length of the prob_vector --- gtnash/game/normalformgame.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gtnash/game/normalformgame.py b/gtnash/game/normalformgame.py index 8cbf0cb..2da3fe9 100644 --- a/gtnash/game/normalformgame.py +++ b/gtnash/game/normalformgame.py @@ -308,7 +308,9 @@ class NFG(AbstractGame): ) for ai in range(len(self.players_actions[play])): other_strategy = mixed_joint_strategy.copy() - other_strategy[play] = np.zeros(len(mixed_joint_strategy[play])) + other_strategy[play] = np.zeros( + len(mixed_joint_strategy[play].squeeze()) + ) other_strategy[play][ai] = 1 expected_util_of_other = self.expected_utilities(other_strategy) all_valuediff += [ -- GitLab From e63957f5894e40161b37302add8e80efc37c0ee6 Mon Sep 17 00:00:00 2001 From: ssmaddila <siva-sri-prasanna.maddila@inrae.fr> Date: Tue, 10 Dec 2024 10:48:20 +0100 Subject: [PATCH 11/13] HGG.write_GameFile no longer converts rewards to int. This function was writing the rewards (self.utilities) by converting them to integers. --- gtnash/game/hypergraphicalgame.py | 2 +- gtnash/game/yes | 8 ++++++++ gtnash/game/yes.pub | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 gtnash/game/yes create mode 100644 gtnash/game/yes.pub diff --git a/gtnash/game/hypergraphicalgame.py b/gtnash/game/hypergraphicalgame.py index f438742..7c6b9e9 100644 --- a/gtnash/game/hypergraphicalgame.py +++ b/gtnash/game/hypergraphicalgame.py @@ -920,7 +920,7 @@ class HGG(AbstractGame): fileTestwrite.write(str_hyper_edge) str_utilities = "" for uti in payoffwrite[index_hyper_edge]: - str_utilities += f"{int(uti)} " + str_utilities += f"{uti} " fileTestwrite.write(str_utilities + "\n") fileTestwrite.close() diff --git a/gtnash/game/yes b/gtnash/game/yes new file mode 100644 index 0000000..c8abb6a --- /dev/null +++ b/gtnash/game/yes @@ -0,0 +1,8 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW +QyNTUxOQAAACC+FTU5eCYKvfiES8OPxyH3rqxo37iAJpqvQeoKNlMzQwAAAKj0waBZ9MGg +WQAAAAtzc2gtZWQyNTUxOQAAACC+FTU5eCYKvfiES8OPxyH3rqxo37iAJpqvQeoKNlMzQw +AAAEBJLAv4arQ/UowXfR3i16ICmC5lb4w8w8MkkLijocY/0L4VNTl4Jgq9+IRLw4/HIfeu +rGjfuIAmmq9B6go2UzNDAAAAInNpdmEtc3JpLXByYXNhbm5hLm1hZGRpbGFAaW5yYWUuZn +IBAgM= +-----END OPENSSH PRIVATE KEY----- diff --git a/gtnash/game/yes.pub b/gtnash/game/yes.pub new file mode 100644 index 0000000..1f045a1 --- /dev/null +++ b/gtnash/game/yes.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL4VNTl4Jgq9+IRLw4/HIfeurGjfuIAmmq9B6go2UzND siva-sri-prasanna.maddila@inrae.fr -- GitLab From 9c7cc374753d65f063fdcdf5d9c000a4fa09899d Mon Sep 17 00:00:00 2001 From: ssmaddila <siva-sri-prasanna.maddila@inrae.fr> Date: Tue, 10 Dec 2024 11:09:55 +0100 Subject: [PATCH 12/13] Fixed HGG.read_GameFile to accept floats --- gtnash/game/hypergraphicalgame.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gtnash/game/hypergraphicalgame.py b/gtnash/game/hypergraphicalgame.py index 7c6b9e9..2e01224 100644 --- a/gtnash/game/hypergraphicalgame.py +++ b/gtnash/game/hypergraphicalgame.py @@ -823,7 +823,9 @@ class HGG(AbstractGame): # but there is only 1 element to iterate on for i, s in enumerate(iterTest): sublist_utilites = [ - int(sub_int) for sub_int in s.group(1).strip("\n").split(" ") if sub_int + float(sub_int) + for sub_int in s.group(1).strip("\n").split(" ") + if sub_int ] n_players = len(hypergraph[i]) # Initialize the list of utility -- GitLab From e40c71f3f8b6ea6d280a4aaa73b2eeec55394087 Mon Sep 17 00:00:00 2001 From: ssmaddila <siva-sri-prasanna.maddila@inrae.fr> Date: Fri, 24 Jan 2025 10:32:15 +0100 Subject: [PATCH 13/13] gtnash/game/normalformgame.py: removed np.mat since it is deprecated --- gtnash/game/normalformgame.py | 16 +- notebook/quickstart.ipynb | 540 ++++------------------------------ 2 files changed, 66 insertions(+), 490 deletions(-) diff --git a/gtnash/game/normalformgame.py b/gtnash/game/normalformgame.py index 2da3fe9..547ba5d 100644 --- a/gtnash/game/normalformgame.py +++ b/gtnash/game/normalformgame.py @@ -23,9 +23,9 @@ class NFG(AbstractGame): self.joint_actions = [] self.joint_actions = self.generate_joint_actions(players_actions) self.utilities = utilities - self.disutilities = np.mat(np.zeros(self.joint_actions.shape)) + self.disutilities = np.asmatrix(np.zeros(self.joint_actions.shape)) for i, i_utilities in enumerate(utilities): - u_tmp = np.mat(i_utilities) + u_tmp = np.asmatrix(i_utilities) u_tmp = u_tmp.transpose() self.disutilities[:, i] = u_tmp self.transform_utilities() @@ -41,11 +41,13 @@ class NFG(AbstractGame): lists of actions available to every players. :returns: A matrix which rows are the joint strategies. - :rtype: np.matrix of int. + :rtype: np.asmatrixrix of int. """ if players_actions is None: players_actions = self.players_actions - return np.matrix([jaction for jaction in itertools.product(*players_actions)]) + return np.asmatrixrix( + [jaction for jaction in itertools.product(*players_actions)] + ) def all_response_of_player(self, player_ind, action): """Generates all the possible joint strategies obtained by @@ -56,7 +58,7 @@ class NFG(AbstractGame): :param list action: Arbitrary joint strategy of players. :returns: A matrix which rows are the obtained joint strategies. - :rtype: np.matrix. + :rtype: np.asmatrixrix. """ action_in_use = [] for i in range(self.n_players): @@ -74,7 +76,7 @@ class NFG(AbstractGame): :returns: A matrix which rows are all the pure joint strategies excluding player *player_ind*'s action. - :rtype: np.matrix. + :rtype: np.asmatrixrix. """ action_in_use = [ act for i, act in enumerate(self.players_actions) if (i != player_ind) @@ -828,7 +830,7 @@ class NFG(AbstractGame): mat_utilities = mat_utilities.astype(str) tableau_final = np.concatenate( ( - np.mat(label), + np.asmatrix(label), np.concatenate((self.joint_actions, mat_utilities), axis=1), ), axis=0, diff --git a/notebook/quickstart.ipynb b/notebook/quickstart.ipynb index 3489906..e5316b1 100644 --- a/notebook/quickstart.ipynb +++ b/notebook/quickstart.ipynb @@ -17,7 +17,19 @@ "cell_type": "code", "execution_count": 1, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'gtnash'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mnumpy\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mnp\u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mgtnash\u001b[39;00m\n\u001b[1;32m 3\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01msage\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mall\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;241m*\u001b[39m\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mgtnash\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mgame\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mnormalformgame\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;241m*\u001b[39m\n", + "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'gtnash'" + ] + } + ], "source": [ "import numpy as np\n", "import gtnash\n", @@ -38,26 +50,9 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Utilities of the game\n", - "[['A0' 'A1' 'A2' 'U0' 'U1' 'U2']\n", - " ['0' '0' '0' '6' '0' '4']\n", - " ['0' '0' '1' '7' '3' '7']\n", - " ['0' '1' '0' '0' '7' '4']\n", - " ['0' '1' '1' '5' '4' '0']\n", - " ['1' '0' '0' '1' '6' '3']\n", - " ['1' '0' '1' '4' '5' '2']\n", - " ['1' '1' '0' '2' '1' '6']\n", - " ['1' '1' '1' '3' '2' '1']]\n" - ] - } - ], + "outputs": [], "source": [ "players_actions = [[0, 1], [0, 1], [0, 1]]\n", "utilities=[[6,7,0,5,1,4,2,3],[0,3,7,4,6,5,1,2],[4,7,4,0,3,2,6,1]]\n", @@ -94,7 +89,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -110,18 +105,9 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{0: [0.4166666666666667?, 0.5833333333333333?], 1: [0.2857142857142857?, 0.714285714285715?], 2: [1.000000000000000?, 0]}\n", - "Is this an equilibrium? True\n" - ] - } - ], + "outputs": [], "source": [ "equilibrium = wilson(current_nfg)\n", "print(equilibrium)\n", @@ -139,19 +125,9 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Player 0: [5/12, 7/12]\n", - "Player 1: [2/7, 5/7]\n", - "Player 2: [1, 0]\n" - ] - } - ], + "outputs": [], "source": [ "for n in equilibrium.keys():\n", " print(f\"Player {n}: {[x.radical_expression() for x in equilibrium[n]]}\")" @@ -166,19 +142,9 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{0: [0.4166666666666667?, 0.5833333333333333?], 1: [0.2857142857142857?, 0.714285714285715?], 2: [1.000000000000000?, 0]}\n", - "CPU times: user 826 ms, sys: 4.82 ms, total: 831 ms\n", - "Wall time: 830 ms\n" - ] - } - ], + "outputs": [], "source": [ "%time print(wilson(current_nfg))" ] @@ -200,19 +166,9 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{0: [0.4166666666666667?, 0.5833333333333333?], 1: [0.2857142857142857?, 0.714285714285715?], 2: [1.000000000000000?, 0]}\n", - "CPU times: user 188 ms, sys: 28.1 ms, total: 216 ms\n", - "Wall time: 375 ms\n" - ] - } - ], + "outputs": [], "source": [ "from gtnash.solver.pns import *\n", "%time print(PNS_solver(current_nfg).launch_pns())" @@ -235,7 +191,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -252,53 +208,9 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Utilities of the game\n", - "Local game 0 : \n", - " [['A0' 'A1' 'U0' 'U1']\n", - " ['0' '0' '8' '4']\n", - " ['0' '1' '2' '1']\n", - " ['0' '2' '5' '4']\n", - " ['1' '0' '5' '5']\n", - " ['1' '1' '1' '6']\n", - " ['1' '2' '7' '2']\n", - " ['2' '0' '1' '4']\n", - " ['2' '1' '5' '7']\n", - " ['2' '2' '1' '3']]\n", - "Local game 1 : \n", - " [['A0' 'A2' 'U0' 'U2']\n", - " ['0' '0' '2' '2']\n", - " ['0' '1' '2' '5']\n", - " ['0' '2' '4' '4']\n", - " ['1' '0' '7' '7']\n", - " ['1' '1' '9' '1']\n", - " ['1' '2' '4' '5']\n", - " ['2' '0' '5' '2']\n", - " ['2' '1' '5' '1']\n", - " ['2' '2' '5' '6']]\n", - "Local game 2 : \n", - " [['A1' 'A2' 'U1' 'U2']\n", - " ['0' '0' '9' '8']\n", - " ['0' '1' '3' '8']\n", - " ['0' '2' '4' '6']\n", - " ['1' '0' '9' '9']\n", - " ['1' '1' '5' '1']\n", - " ['1' '2' '5' '4']\n", - " ['2' '0' '9' '9']\n", - " ['2' '1' '5' '1']\n", - " ['2' '2' '4' '3']]\n", - "\n", - " Hypergraph: \n", - "[[0, 1], [0, 2], [1, 2]]\n" - ] - } - ], + "outputs": [], "source": [ "utilities = [[[8, 2, 5, 5, 1, 7, 1, 5, 1], [4, 1, 4, 5, 6, 2, 4, 7, 3]],\n", " [[2, 2, 4, 7, 9, 4, 5, 5, 5], [2, 5, 4, 7, 1, 5, 2, 1, 6]],\n", @@ -328,21 +240,9 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 64.1 ms, sys: 76.7 ms, total: 141 ms\n", - "Wall time: 17.2 ms\n", - "player 0 -> mixed strategy -> [0.0, 0.0, 1.0]\n", - "player 1 -> mixed strategy -> [0.0, 1.0, 0.0]\n", - "player 2 -> mixed strategy -> [1.0, 0.0, 0.0]\n" - ] - } - ], + "outputs": [], "source": [ "solver = LHpolymatrix(PMG(players_actions, utilities, hypergraph))\n", "omega0 = [0,0,0] # Initial joint action used to initialize the Lemke-Howson algorithm\n", @@ -361,17 +261,9 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Is it a Nash equilibrium? True\n" - ] - } - ], + "outputs": [], "source": [ "print(\"Is it a Nash equilibrium? \",current_pmg.is_equilibrium(sol_dict))" ] @@ -386,50 +278,9 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[['A0' 'A1' 'A2' 'U0' 'U1' 'U2']\n", - " ['0' '0' '0' '10' '13' '10']\n", - " ['0' '0' '1' '10' '7' '13']\n", - " ['0' '0' '2' '12' '8' '10']\n", - " ['0' '1' '0' '4' '10' '11']\n", - " ['0' '1' '1' '4' '6' '6']\n", - " ['0' '1' '2' '6' '6' '8']\n", - " ['0' '2' '0' '7' '13' '11']\n", - " ['0' '2' '1' '7' '9' '6']\n", - " ['0' '2' '2' '9' '8' '7']\n", - " ['1' '0' '0' '12' '14' '15']\n", - " ['1' '0' '1' '14' '8' '9']\n", - " ['1' '0' '2' '9' '9' '11']\n", - " ['1' '1' '0' '8' '15' '16']\n", - " ['1' '1' '1' '10' '11' '2']\n", - " ['1' '1' '2' '5' '11' '9']\n", - " ['1' '2' '0' '14' '11' '16']\n", - " ['1' '2' '1' '16' '7' '2']\n", - " ['1' '2' '2' '11' '6' '8']\n", - " ['2' '0' '0' '6' '13' '10']\n", - " ['2' '0' '1' '6' '7' '9']\n", - " ['2' '0' '2' '6' '8' '12']\n", - " ['2' '1' '0' '10' '16' '11']\n", - " ['2' '1' '1' '10' '12' '2']\n", - " ['2' '1' '2' '10' '12' '10']\n", - " ['2' '2' '0' '6' '12' '11']\n", - " ['2' '2' '1' '6' '8' '2']\n", - " ['2' '2' '2' '6' '7' '9']]\n", - "CPU times: user 1.62 s, sys: 8.84 ms, total: 1.62 s\n", - "Wall time: 1.63 s\n", - "{0: [0, 0, 1.000000000000000?], 1: [0, 1.000000000000000?, 0], 2: [1.000000000000000?, 0, 0]}\n", - "Player 0: [0, 0, 1]\n", - "Player 1: [0, 1, 0]\n", - "Player 2: [1, 0, 0]\n" - ] - } - ], + "outputs": [], "source": [ "converted_nfg = current_pmg.convert_to_NFG()\n", "print(converted_nfg)\n", @@ -457,40 +308,9 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Utilities of the hypergraphical game:\n", - "Local game 0 : \n", - " [['A0' 'A1' 'A3' 'U0' 'U1' 'U3']\n", - " ['0' '0' '0' '74' '51' '18']\n", - " ['0' '0' '1' '6' '97' '16']\n", - " ['0' '1' '0' '9' '98' '29']\n", - " ['0' '1' '1' '60' '83' '86']\n", - " ['1' '0' '0' '77' '90' '100']\n", - " ['1' '0' '1' '30' '1' '96']\n", - " ['1' '1' '0' '47' '2' '93']\n", - " ['1' '1' '1' '0' '47' '64']]\n", - "Local game 1 : \n", - " [['A0' 'A2' 'A3' 'U0' 'U2' 'U3']\n", - " ['0' '0' '0' '84' '10' '1']\n", - " ['0' '0' '1' '48' '88' '36']\n", - " ['0' '1' '0' '27' '72' '68']\n", - " ['0' '1' '1' '5' '47' '0']\n", - " ['1' '0' '0' '100' '13' '53']\n", - " ['1' '0' '1' '62' '24' '5']\n", - " ['1' '1' '0' '16' '42' '61']\n", - " ['1' '1' '1' '62' '72' '97']]\n", - "\n", - " Hypergraph: \n", - "[[0, 1, 3], [0, 2, 3]]\n" - ] - } - ], + "outputs": [], "source": [ "from gtnash.game.hypergraphicalgame import *\n", "utilities = [\n", @@ -521,25 +341,9 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 6.66 s, sys: 12.8 ms, total: 6.68 s\n", - "Wall time: 6.67 s\n", - "{0: [0.651851851851852?, 0.3481481481481481?], 1: [0.7714285714285714?, 0.2285714285714286?], 2: [0, 1.000000000000000?], 3: [1.000000000000000?, 0]}\n", - "Is this an equilibrium? True\n", - "Algebraic number representation:\n", - "Player 0: [88/135, 47/135]\n", - "Player 1: [27/35, 8/35]\n", - "Player 2: [0, 1]\n", - "Player 3: [1, 0]\n" - ] - } - ], + "outputs": [], "source": [ "%time equilibrium = wilson(current_hgg)\n", "print(equilibrium)\n", @@ -558,25 +362,9 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 428 ms, sys: 12 ms, total: 440 ms\n", - "Wall time: 442 ms\n", - "{0: [0.7666666666666667?, 0.2333333333333334?], 1: [0.5476190476190476?, 0.4523809523809524?], 2: [1.000000000000000?, 0], 3: [0, 1.000000000000000?]}\n", - "Is this an equilibrium? True\n", - "Algebraic number representation:\n", - "Player 0: [23/30, 7/30]\n", - "Player 1: [23/42, 19/42]\n", - "Player 2: [1, 0]\n", - "Player 3: [0, 1]\n" - ] - } - ], + "outputs": [], "source": [ "converted_nfg = current_hgg.convert_to_NFG()\n", "%time equilibrium_PNS = PNS_solver(converted_nfg).launch_pns()\n", @@ -596,25 +384,9 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 2.38 s, sys: 12.4 ms, total: 2.4 s\n", - "Wall time: 2.39 s\n", - "{0: [0.651851851851852?, 0.3481481481481481?], 1: [0.7714285714285714?, 0.2285714285714286?], 2: [0, 1.000000000000000?], 3: [1.000000000000000?, 0]}\n", - "Is this an equilibrium? True\n", - "Algebraic number representation:\n", - "Player 0: [88/135, 47/135]\n", - "Player 1: [27/35, 8/35]\n", - "Player 2: [0, 1]\n", - "Player 3: [1, 0]\n" - ] - } - ], + "outputs": [], "source": [ "%time equilibrium_wilson = wilson(converted_nfg)\n", "print(equilibrium_wilson)\n", @@ -636,73 +408,9 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Theta 0 = [[0 0]] and P(Theta 0 ) = 1/10 \n", - " [['A0' 'A1' 'U0' 'U1']\n", - " ['0' '0' '-3' '-3']\n", - " ['0' '1' '-7' '-7']\n", - " ['1' '0' '-10' '-1']\n", - " ['1' '1' '-1' '-5']\n", - " ['2' '0' '-5' '-10']\n", - " ['2' '1' '-9' '-9']] \n", - "\n", - "Theta 1 = [[0 1]] and P(Theta 1 ) = 1/5 \n", - " [['A0' 'A1' 'U0' 'U1']\n", - " ['0' '0' '-2' '-2']\n", - " ['0' '1' '-6' '-6']\n", - " ['1' '0' '-9' '-1']\n", - " ['1' '1' '-1' '-4']\n", - " ['2' '0' '-4' '-9']\n", - " ['2' '1' '-8' '-8']] \n", - "\n", - "Theta 2 = [[0 2]] and P(Theta 2 ) = 1/5 \n", - " [['A0' 'A1' 'U0' 'U1']\n", - " ['0' '0' '-2' '-2']\n", - " ['0' '1' '-5' '-5']\n", - " ['1' '0' '-8' '-1']\n", - " ['1' '1' '-1' '-3']\n", - " ['2' '0' '-3' '-8']\n", - " ['2' '1' '-7' '-7']] \n", - "\n", - "Theta 3 = [[1 0]] and P(Theta 3 ) = 1/5 \n", - " [['A0' 'A1' 'U0' 'U1']\n", - " ['0' '0' '-2' '-2']\n", - " ['0' '1' '-4' '-4']\n", - " ['1' '0' '-7' '-1']\n", - " ['1' '1' '-1' '-3']\n", - " ['2' '0' '-3' '-7']\n", - " ['2' '1' '-6' '-6']] \n", - "\n", - "Theta 4 = [[1 1]] and P(Theta 4 ) = 1/10 \n", - " [['A0' 'A1' 'U0' 'U1']\n", - " ['0' '0' '-2' '-2']\n", - " ['0' '1' '-4' '-4']\n", - " ['1' '0' '-6' '-1']\n", - " ['1' '1' '-1' '-3']\n", - " ['2' '0' '-3' '-6']\n", - " ['2' '1' '-5' '-5']] \n", - "\n", - "Theta 5 = [[1 2]] and P(Theta 5 ) = 1/5 \n", - " [['A0' 'A1' 'U0' 'U1']\n", - " ['0' '0' '-3' '-3']\n", - " ['0' '1' '-7' '-7']\n", - " ['1' '0' '-1' '-10']\n", - " ['1' '1' '-5' '-1']\n", - " ['2' '0' '-10' '-5']\n", - " ['2' '1' '-9' '-9']] \n", - "\n", - "\n", - " Type: \n", - "[[0, 1], [0, 1, 2]]\n" - ] - } - ], + "outputs": [], "source": [ "players_actions = [[0, 1, 2], [0, 1]]\n", "utilities = [[[-3, -7, -10, -1, -5, -9], [-3, -7, -1, -5, -10, -9]],\n", @@ -726,79 +434,9 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Local game 0 : \n", - " [['A0' 'A2' 'U0' 'U2']\n", - " ['0' '0' '-3/5' '-1']\n", - " ['0' '1' '-7/5' '-7/3']\n", - " ['1' '0' '-2' '-1/3']\n", - " ['1' '1' '-1/5' '-5/3']\n", - " ['2' '0' '-1' '-10/3']\n", - " ['2' '1' '-9/5' '-3']]\n", - "Local game 1 : \n", - " [['A0' 'A3' 'U0' 'U3']\n", - " ['0' '0' '-4/5' '-4/3']\n", - " ['0' '1' '-12/5' '-4']\n", - " ['1' '0' '-18/5' '-2/3']\n", - " ['1' '1' '-2/5' '-8/3']\n", - " ['2' '0' '-8/5' '-6']\n", - " ['2' '1' '-16/5' '-16/3']]\n", - "Local game 2 : \n", - " [['A0' 'A4' 'U0' 'U4']\n", - " ['0' '0' '-4/5' '-1']\n", - " ['0' '1' '-2' '-5/2']\n", - " ['1' '0' '-16/5' '-1/2']\n", - " ['1' '1' '-2/5' '-3/2']\n", - " ['2' '0' '-6/5' '-4']\n", - " ['2' '1' '-14/5' '-7/2']]\n", - "Local game 3 : \n", - " [['A1' 'A2' 'U1' 'U2']\n", - " ['0' '0' '-4/5' '-4/3']\n", - " ['0' '1' '-8/5' '-8/3']\n", - " ['1' '0' '-14/5' '-2/3']\n", - " ['1' '1' '-2/5' '-2']\n", - " ['2' '0' '-6/5' '-14/3']\n", - " ['2' '1' '-12/5' '-4']]\n", - "Local game 4 : \n", - " [['A1' 'A3' 'U1' 'U3']\n", - " ['0' '0' '-2/5' '-2/3']\n", - " ['0' '1' '-4/5' '-4/3']\n", - " ['1' '0' '-6/5' '-1/3']\n", - " ['1' '1' '-1/5' '-1']\n", - " ['2' '0' '-3/5' '-2']\n", - " ['2' '1' '-1' '-5/3']]\n", - "Local game 5 : \n", - " [['A1' 'A4' 'U1' 'U4']\n", - " ['0' '0' '-6/5' '-3/2']\n", - " ['0' '1' '-14/5' '-7/2']\n", - " ['1' '0' '-2/5' '-5']\n", - " ['1' '1' '-2' '-1/2']\n", - " ['2' '0' '-4' '-5/2']\n", - " ['2' '1' '-18/5' '-9/2']]\n", - "\n", - " Hypergraph: \n", - "[[0, 2], [0, 3], [0, 4], [1, 2], [1, 3], [1, 4]]\n", - "Correspondance between players in the transformed game and the (player,type) tuples of the bayesian game:\n", - "{0: (0, 0), 1: (0, 1), 2: (1, 0), 3: (1, 1), 4: (1, 2)}\n", - "Is the new game a polymatrix game? True\n", - "So, it can be solved using Lemke-Howson's algorithm:\n", - "CPU times: user 1.36 ms, sys: 31 µs, total: 1.39 ms\n", - "Wall time: 1.16 ms\n", - "player 0 -> mixed strategy -> [1.0, 0.0, 0.0]\n", - "player 1 -> mixed strategy -> [1.0, 0.0, 0.0]\n", - "player 2 -> mixed strategy -> [1.0, 0.0]\n", - "player 3 -> mixed strategy -> [1.0, 0.0]\n", - "player 4 -> mixed strategy -> [1.0, 0.0]\n", - "Is this really an equilibrium? True\n" - ] - } - ], + "outputs": [], "source": [ "hgg_from_bg,index_to_players = bg.convert_to_HGG()\n", "print(hgg_from_bg)\n", @@ -824,17 +462,9 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Bayesian game with 4 players, 2 types, 2 actions each and 2 local bayesian games.\n" - ] - } - ], + "outputs": [], "source": [ "from gtnash.game.bayesian_hypergraphicalgame import *\n", "\n", @@ -905,25 +535,9 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "We can compute first a:\n", - "Hypergraphical game with 8 players, 2 actions each and 16 local games of size 3.\n", - "Then, we compute a normal form game from this HGG.\n", - "We solve it using the PNS solver:\n", - "CPU times: user 11.4 s, sys: 621 ms, total: 12 s\n", - "Wall time: 12.2 s\n", - "The corresponding equilibrium is:\n", - "{0: [1, 0], 1: [0, 1], 2: [0, 1], 3: [1, 0], 4: [1, 0], 5: [1, 0], 6: [0, 1], 7: [0, 1]}\n", - "Solving the same NFG using Wilson's algorithm takes far more time, so we do not do it\n" - ] - } - ], + "outputs": [], "source": [ "hgg_from_bhgg,index_to_players = bhgg.convert_to_HGG()\n", "print(\"We can compute first a:\")\n", @@ -950,20 +564,9 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Bayesian game with 3 players, 2 types, 2 actions each and 2 local bayesian games.\n", - "We can compute first a:\n", - "Hypergraphical game with 6 players, 2 actions each and 8 local games of size 2.\n", - "We can solve the HGG using Lemke and Howson's algorithm, since it is a polymatrix game:\n" - ] - } - ], + "outputs": [], "source": [ "players_actions = [[0, 1], [0, 1], [0, 1]]\n", "theta = [[0, 1], [0, 1], [0, 1]]\n", @@ -995,38 +598,9 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Is the obtained hypergraphical game a polymatrix game?\n", - "True\n", - "So, we can solve it using the Lemke-Howson algorithm:\n", - "CPU times: user 10.5 ms, sys: 0 ns, total: 10.5 ms\n", - "Wall time: 9.26 ms\n", - "player 0 -> mixed strategy -> [0.0, 1.0]\n", - "player 1 -> mixed strategy -> [1.0, 0.0]\n", - "player 2 -> mixed strategy -> [0.0, 1.0]\n", - "player 3 -> mixed strategy -> [1.0, 0.0]\n", - "player 4 -> mixed strategy -> [0.0, 1.0]\n", - "player 5 -> mixed strategy -> [1.0, 0.0]\n", - "Is this an equilibrium? True\n", - "In order to solve it using Wilson's algorithm, we first transform it into a normal-form game:\n", - "We first solve it using the PNS solver:\n", - "CPU times: user 632 ms, sys: 15.7 ms, total: 648 ms\n", - "Wall time: 657 ms\n", - "{0: [0, 1], 1: [1, 0], 2: [0, 1], 3: [1, 0], 4: [0, 1], 5: [1, 0]}\n", - "Is this an equilibrium? True\n", - "Then, we solve it using Wilson's algorithm:\n", - "CPU times: user 1.7 s, sys: 11.8 ms, total: 1.71 s\n", - "Wall time: 1.71 s\n", - "Here is the Nash equilibrium: {0: [0, 1], 1: [1, 0], 2: [0, 1], 3: [1, 0], 4: [0, 1], 5: [1, 0]}\n" - ] - } - ], + "outputs": [], "source": [ "print(\"Is the obtained hypergraphical game a polymatrix game?\")\n", "print(hgg_from_bhgg.is_PMG())\n", @@ -1069,9 +643,9 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" + "display_name": "SageMath 9.5", + "language": "sage", + "name": "sagemath" }, "language_info": { "codemirror_mode": { @@ -1083,7 +657,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.10" + "version": "3.11.6" } }, "nbformat": 4, -- GitLab