- elif soln_dict['status'] == 'unknown':
- # When we get a status of "unknown", we may still be able
- # to salvage a solution out of the returned
- # dictionary. Often this is the result of numerical
- # difficulty and we can simply check that the primal/dual
- # objectives match (within a tolerance) and that the
- # primal/dual optimal solutions are within the cone (to a
- # tolerance as well).
- #
- # The fudge factor of two is basically unjustified, but
- # makes intuitive sense when you imagine that the primal
- # value could be under the true optimal by ``ABS_TOL``
- # and the dual value could be over by the same amount.
- #
- if abs(p1_value - p2_value) > tolerance:
- raise GameUnsolvableException(self, soln_dict)
- if (p1_optimal not in self._K) or (p2_optimal not in self._K):
- raise GameUnsolvableException(self, soln_dict)
-
- return Solution(p1_value, p1_optimal, p2_optimal)
-
-
- def solution(self):
- """
- Solve this linear game and return a :class:`Solution`.
-
- Returns
- -------
-
- :class:`Solution`
- A :class:`Solution` object describing the game's value and
- the optimal strategies of both players.
-
- Raises
- ------
- GameUnsolvableException
- If the game could not be solved (if an optimal solution to its
- associated cone program was not found).
-
- PoorScalingException
- If the game could not be solved because CVXOPT crashed while
- trying to take the square root of a negative number.
-
- Examples
- --------
-
- This example is computed in Gowda and Ravindran in the section
- "The value of a Z-transformation"::
-
- >>> from dunshire import *
- >>> K = NonnegativeOrthant(3)
- >>> L = [[1,-5,-15],[-1,2,-3],[-12,-15,1]]
- >>> e1 = [1,1,1]
- >>> e2 = [1,1,1]
- >>> SLG = SymmetricLinearGame(L, K, e1, e2)
- >>> print(SLG.solution())
- Game value: -6.1724138
- Player 1 optimal:
- [ 0.551...]
- [-0.000...]
- [ 0.448...]
- Player 2 optimal:
- [0.448...]
- [0.000...]
- [0.551...]
-
- The value of the following game can be computed using the fact
- that the identity is invertible::