Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/osxbinary.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@ jobs:
- run: make
- run: sudo make install
- run: make osx-dmg
- run: make dist
- uses: actions/upload-artifact@v7
with:
name: artifact-osx-14
path: "*.dmg"
- uses: actions/upload-artifact@v7
with:
name: artifact-source-dist
path: "*.tar.gz"
21 changes: 21 additions & 0 deletions .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,24 @@ jobs:
- uses: actions/upload-artifact@v7
with:
path: ./wheelhouse/*.whl

sdist:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v7
- name: Set up Python
uses: actions/setup-python@v7
with:
python-version: '3.x'
- name: Set up dependencies
run: |
python -m pip install --upgrade pip
pip install build
- name: Build sdist
run: |
python -m build --sdist
- uses: actions/upload-artifact@v7
with:
name: sdist
path: ./dist/*.tar.gz
35 changes: 35 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,38 @@
## [17.0.0-beta.1] - unreleased

### Added
- Added `Game.has_perfect_recall(player)`, and `GameRep::HasPerfectRecall(const GamePlayer &)`
in C++, reporting whether an individual player has perfect recall. (#1107)
- Added `Game.get_outcomes()`, returning a materialized list of outcome labels, replacing
`Game.outcomes`.
- Added `Game.get_outcome_payoffs(label)`, returning the payoff to each player at the outcome
labeled `label`.
- Added `Game.set_outcome_payoffs(label, payoffs)`, setting the payoffs at the outcome labeled
`label`; `payoffs` must be a complete mapping over the game's players, as with
`Game.make_outcome`.
- Added `Game.relabel_outcomes(labels, strict=True)`, simultaneously reassigning the labels of
the game's outcomes, following the same pattern as `Game.relabel_players`/
`Game.relabel_strategies`. Added `GameRep::RelabelOutcomes` in C++.

### Changed
- `Game.make_outcome` now returns `None` instead of the `Outcome` created; use the `label`
already passed in, together with `Game.get_outcome_payoffs`/`Game.relabel_outcomes`, to refer
to it afterward.

### Removed
- `Outcome` has been removed as a public-facing class in pygambit, following `Action`,
`Infoset`, `Player`, `Strategy`, and `Node`: no public method holds or returns a live handle
into a game's internal outcome list any longer. `Game.outcomes` has been removed; use
`Game.get_outcomes()`, `Game.get_outcome_payoffs()`, `Game.set_outcome_payoffs()`, and
`Game.relabel_outcomes()` instead.

### Fixed
- `GameTableRep`'s constructor (used by `Game.from_arrays`/`Game.from_dict`, which build a
non-sparse table with one outcome per contingency) gave every outcome the same empty label,
violating the invariant that every non-null outcome has a unique, nonempty label. Outcomes
are now labeled `"1"`, `"2"`, and so on, following the existing convention for default
player/strategy labels.

## [17.0.0-alpha.3] - 2026-08-31

### Added
Expand Down
20 changes: 19 additions & 1 deletion doc/algorithms.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ Algorithm Description
:ref:`lp` Compute equilibria in a two-player constant-sum game via linear programming :py:func:`pygambit.nash.lp_solve` :ref:`gambit-lp <gambit-lp>`
:ref:`lcp` Compute equilibria in a two-player game via linear complementarity :py:func:`pygambit.nash.lcp_solve` :ref:`gambit-lcp <gambit-lcp>`
:ref:`liap` Compute equilibria using function minimization :py:func:`pygambit.nash.liap_solve` :ref:`gambit-liap <gambit-liap>`
:ref:`logit` Trace logit QRE and approximate a Nash equilibrium at high precision :py:func:`pygambit.nash.logit_solve` :ref:`gambit-logit <gambit-logit>`
:ref:`logit` Trace logit QRE and approximate a Nash equilibrium at high precision :py:func:`pygambit.nash.logit_solve` :ref:`gambit-logit <gambit-logit>`
:ref:`simpdiv` Compute equilibria via simplicial subdivision :py:func:`pygambit.nash.simpdiv_solve` :ref:`gambit-simpdiv <gambit-simpdiv>`
:ref:`ipa` Compute equilibria using iterated polymatrix approximation :py:func:`pygambit.nash.ipa_solve` :ref:`gambit-ipa <gambit-ipa>`
:ref:`gnm` Compute equilibria using a global Newton method :py:func:`pygambit.nash.gnm_solve` :ref:`gambit-gnm <gambit-gnm>`
:ref:`hp` Compute a specific Nash equilibrium using a homotopy path-following method :py:func:`pygambit.nash.hp_solve` :ref:`gambit-hp <gambit-hp>`
================ =========================================================================== ======================================== ==========================================

.. _enumpure:
Expand Down Expand Up @@ -234,3 +235,20 @@ The algorithm takes as a parameter a mixed strategy profile. This profile is
interpreted as defining a ray in the space of games. The profile must have
the property that, for each player, the most frequently played strategy must
be unique.

.. _hp:

hp
---
Computes the Nash equilibrium selected by the tracing procedure
of Harsanyi and Selten using a homotopy path-following method. The algorithm
was first described by Herings and Peeters :cite:p:`HerPee01`.

The algorithm takes as a parameter a mixed strategy profile, which acts as
the subjective prior beliefs of the players.
The profile must have the property that, for each player,
there must only exist one best response.

For generic games, the algorithm converges to the unique Nash equilibrium selected by
the tracing procedure of Harsanyi and Selten. For non-generic games, the algorithm may
converge to a Nash equilibrium that is not selected by the tracing procedure.
1 change: 1 addition & 0 deletions doc/gui.nash.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ Method Parameters used by the graphical interface
``ipa`` One random perturbation.
``gnm`` One random perturbation; ending lambda ``-10``; 100 steps per support cell;
local Newton refinement every 3 steps, with at most 10 iterations.
``hp`` No method-specific parameters.
================ ============================================================================

For extensive games, there is an option of whether to use the
Expand Down
90 changes: 21 additions & 69 deletions doc/pygambit.api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,9 @@ Representation of games
:toctree: api/

Game
Outcome
Node
Infoset
Event
Branch
Subgame
TreeLayout
TreeLayoutCoordinates


Creating, reading, and writing games
Expand All @@ -45,6 +42,15 @@ Creating, reading, and writing games
Game.to_latex


Computing a tree layout for graphical display
..............................................

.. autosummary::
:toctree: api/

layout_tree


Transforming game trees
.......................

Expand Down Expand Up @@ -74,7 +80,6 @@ Transforming game information structure
Game.relabel_actions
Game.set_move_actions
Game.set_event_actions
Game.reveal


Transforming game components
Expand All @@ -89,6 +94,8 @@ Transforming game components
Game.set_strategies
Game.make_outcome
Game.make_outcome_null
Game.relabel_outcomes
Game.set_outcome_payoffs


Information about the game
Expand All @@ -102,86 +109,32 @@ Information about the game
Game.is_const_sum
Game.is_tree
Game.is_perfect_recall
Game.has_perfect_recall
Game.players
Game.outcomes
Game.min_payoff
Game.max_payoff
Game.get_min_payoff
Game.get_max_payoff
Game.root
Game.get_infosets
Game.get_events
Game.get_strategies
Game.get_sequences
Game.nodes
Game.contingencies
Game.get_outcome
Game.get_outcomes
Game.get_outcome_payoffs
Game.get_payoffs
Game.subgames
Game.minimal_subgame
Game.get_subgame_roots
Game.get_minimal_subgame
Game.get_strategy_unreachable

.. autosummary::
:toctree: api/

Outcome.label
Outcome.number
Outcome.game

.. autosummary::
:toctree: api/

Node.label
Node.game
Node.outcome
Node.children
Node.parent
Node.is_subgame_root
Node.is_terminal
Node.is_strategy_reachable
Node.prior_action
Node.prior_sibling
Node.next_sibling
Node.infoset
Node.event
Node.members
Node.actions
Node.action_probs
Node.player
Node.is_successor_of
Node.plays
Node.own_prior_action

.. autosummary::
:toctree: api/

Subgame.game
Subgame.root
Subgame.parent
Subgame.children

.. autosummary::

:toctree: api/

Infoset.label
Infoset.game
Infoset.is_absent_minded
Infoset.player
Infoset.actions
Infoset.members
Infoset.precedes

.. autosummary::

:toctree: api/

Event.label
Event.game
Event.is_absent_minded
Event.player
Event.actions
Event.members
Event.precedes

.. autosummary::

Expand Down Expand Up @@ -290,7 +243,6 @@ Probability distributions over behavior
MixedBehaviorProfile.realiz_probs
MixedBehaviorProfile.infoset_probs
MixedBehaviorProfile.beliefs
MixedBehaviorProfile.is_defined_at
MixedBehaviorProfile.agent_max_regret
MixedBehaviorProfile.agent_liap_value
MixedBehaviorProfile.max_regret
Expand Down Expand Up @@ -358,15 +310,15 @@ Subsets of actions
BehaviorSupportProfile.__getitem__
BehaviorSupportProfile.__setitem__
BehaviorSupportProfile.copy
BehaviorSupportProfile.is_reachable
BehaviorSupportProfile.is_infoset_reachable

BehaviorSupport
BehaviorSupport.player
BehaviorSupport.__iter__
BehaviorSupport.__getitem__

ActionSupport
ActionSupport.infoset
ActionSupport.history
ActionSupport.__iter__
ActionSupport.__contains__

Expand Down
76 changes: 76 additions & 0 deletions doc/tools.hp.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
.. _gambit-hp:

:program:`gambit-hp`
=====================

Compute a Nash equilibrium in a strategic game using the homotopy method of
:cite:t:`HerPee01`.

The algorithm finds one equilibrium starting from any given prior
distribution over strategies, which must have a unique best response for
each player. Multiple prior distributions may be generated via the `-n`
option or specified via the `-s` option; different priors may result in
different equilibria being found.


.. program:: gambit-hp

.. cmdoption:: -d

Express all output using decimal representations
with the specified number of digits.

.. cmdoption:: -h

Prints a help message listing the available options.

.. cmdoption:: -n

Randomly generate the specified number of prior distributions.
Mutually exclusive with :option:`-s`.

.. cmdoption:: -R

Seeds the random number generator used to generate prior
distributions with the specified value, so that the sequence of priors
generated by :option:`-n` can be reproduced across runs. If not
specified, the generator is seeded from system entropy. Requires
:option:`-n`.

.. cmdoption:: -q

Suppresses printing of the banner at program launch.

.. cmdoption:: -s

Specifies a file containing a list of prior distributions over
strategies. The format of the file is comma-separated values,
one mixed strategy profile per line, in the same format used for
output of equilibria (excluding the initial NE tag).
Mutually exclusive with :option:`-n`.

.. cmdoption:: -V, --verbose

Show the prior distribution itself, tagged `prior`, followed by each
point traced along the homotopy path, tagged with the homotopy
parameter t in place of the NE tag. Note that the point at t=0 is the
best response to the prior, and so is generally a pure strategy profile
even when the prior itself is not. If this option is not specified,
only the equilibrium found is reported.

.. cmdoption:: -v, --version

Prints version information and exits.


Computing an equilibrium of the reduced strategic form of the example in
Figure 2 of :cite:p:`Sel75`, starting from the prior in which player 1
plays (0.5, 0.3, 0.2) and player 2 plays (0.6, 0.4)::

$ echo "0.5,0.3,0.2,0.6,0.4" > prior.csv
$ gambit-hp -s prior.csv catalog/journals/ijgt/selten1975/fig2.efg
Compute a Nash equilibrium using the Herings-Peeters (2001) homotopy method
Gambit version |release|, Copyright (C) 1994-2026, The Gambit Project
This is free software, distributed under the GNU GPL

NE,1.000000,0.000000,0.000000,0.999976,0.000024
Loading
Loading