@@ -40,19 +40,48 @@ def test_enummixed_double():
4040
4141@pytest .mark .nash
4242@pytest .mark .nash_enummixed_strategy
43- def test_enummixed_rational ():
44- """Test calls of enumeration of mixed strategy equilibria, rational precision."""
45- game = games .read_from_file ("poker.efg" )
43+ @pytest .mark .parametrize (
44+ "game,mixed_strategy_prof_data" ,
45+ [
46+ # Zero-sum games
47+ (games .create_1_card_poker_efg (), [[["1/3" , "2/3" , 0 , 0 ], ["2/3" , "1/3" ]]]),
48+ (games .create_myerson_2_card_poker_efg (), [[["1/3" , "2/3" , 0 , 0 ], ["2/3" , "1/3" ]]]),
49+ # Non-zero-sum games
50+ (games .create_one_shot_trust_efg (), [[[0 , 1 ], ["1/2" , "1/2" ]],
51+ [[0 , 1 ], [0 , 1 ]]]),
52+ (
53+ games .create_EFG_for_nxn_bimatrix_coordination_game (3 ),
54+ [
55+ [[1 , 0 , 0 ], [1 , 0 , 0 ]],
56+ [["1/2" , "1/2" , 0 ], ["1/2" , "1/2" , 0 ]],
57+ [["1/3" , "1/3" , "1/3" ], ["1/3" , "1/3" , "1/3" ]],
58+ [["1/2" , 0 , "1/2" ], ["1/2" , 0 , "1/2" ]],
59+ [[0 , 1 , 0 ], [0 , 1 , 0 ]],
60+ [[0 , "1/2" , "1/2" ], [0 , "1/2" , "1/2" ]],
61+ [[0 , 0 , 1 ], [0 , 0 , 1 ]],
62+ ],
63+ ),
64+ (
65+ games .create_EFG_for_6x6_bimatrix_with_long_LH_paths_and_unique_eq (),
66+ [
67+ [["1/30" , "1/6" , "3/10" , "3/10" , "1/6" , "1/30" ],
68+ ["1/6" , "1/30" , "3/10" , "3/10" , "1/30" , "1/6" ]],
69+ ],
70+ ),
71+ ]
72+ )
73+ def test_enummixed_rational (game : gbt .Game , mixed_strategy_prof_data : list ):
74+ """Test calls of enumeration of extreme mixed strategy equilibria, rational precision
75+
76+ Tests max regret being zero (internal consistency) and compares the computed sequence of
77+ extreme equilibria to a previosuly computed sequence (regression test)
78+ """
4679 result = gbt .nash .enummixed_solve (game , rational = True )
47- assert len (result .equilibria ) == 1
48- expected = game .mixed_strategy_profile (
49- rational = True ,
50- data = [
51- [gbt .Rational (1 , 3 ), gbt .Rational (2 , 3 ), gbt .Rational (0 ), gbt .Rational (0 )],
52- [gbt .Rational (2 , 3 ), gbt .Rational (1 , 3 )],
53- ],
54- )
55- assert result .equilibria [0 ] == expected
80+ assert len (result .equilibria ) == len (mixed_strategy_prof_data )
81+ for eq , exp in zip (result .equilibria , mixed_strategy_prof_data ):
82+ assert eq .max_regret () == 0
83+ expected = game .mixed_strategy_profile (rational = True , data = exp )
84+ assert eq == expected
5685
5786
5887@pytest .mark .nash
@@ -219,19 +248,65 @@ def test_lcp_strategy_double():
219248
220249@pytest .mark .nash
221250@pytest .mark .nash_lcp_strategy
222- def test_lcp_strategy_rational ():
223- """Test calls of LCP for mixed strategy equilibria, rational precision."""
224- game = games .read_from_file ("poker.efg" )
225- result = gbt .nash .lcp_solve (game , use_strategic = True , rational = True )
226- assert len (result .equilibria ) == 1
227- expected = game .mixed_strategy_profile (
228- rational = True ,
229- data = [
230- [gbt .Rational (1 , 3 ), gbt .Rational (2 , 3 ), gbt .Rational (0 ), gbt .Rational (0 )],
231- [gbt .Rational (2 , 3 ), gbt .Rational (1 , 3 )],
232- ],
233- )
234- assert result .equilibria [0 ] == expected
251+ @pytest .mark .parametrize (
252+ "game,mixed_strategy_prof_data,stop_after" ,
253+ [
254+ # Zero-sum games
255+ (games .create_1_card_poker_efg (), [[["1/3" , "2/3" , 0 , 0 ], ["2/3" , "1/3" ]]], None ),
256+ (games .create_myerson_2_card_poker_efg (), [[["1/3" , "2/3" , 0 , 0 ], ["2/3" , "1/3" ]]], None ),
257+ (games .create_kuhn_poker_efg (), [games .kuhn_poker_lcp_first_mixed_strategy_prof ()], 1 ),
258+ # Non-zero-sum games
259+ (games .create_one_shot_trust_efg (), [[[0 , 1 ], ["1/2" , "1/2" ]]], None ),
260+ (
261+ games .create_EFG_for_nxn_bimatrix_coordination_game (3 ),
262+ [
263+ [[1 , 0 , 0 ], [1 , 0 , 0 ]],
264+ [["1/2" , "1/2" , 0 ], ["1/2" , "1/2" , 0 ]],
265+ [[0 , 1 , 0 ], [0 , 1 , 0 ]],
266+ [[0 , "1/2" , "1/2" ], [0 , "1/2" , "1/2" ]],
267+ [["1/3" , "1/3" , "1/3" ], ["1/3" , "1/3" , "1/3" ]],
268+ [["1/2" , 0 , "1/2" ], ["1/2" , 0 , "1/2" ]],
269+ [[0 , 0 , 1 ], [0 , 0 , 1 ]],
270+ ],
271+ None ,
272+ ),
273+ (
274+ games .create_EFG_for_nxn_bimatrix_coordination_game (4 ),
275+ [[[1 , 0 , 0 , 0 ], [1 , 0 , 0 , 0 ]]],
276+ 1 ,
277+ ),
278+ (
279+ games .create_EFG_for_6x6_bimatrix_with_long_LH_paths_and_unique_eq (),
280+ [
281+ [["1/30" , "1/6" , "3/10" , "3/10" , "1/6" , "1/30" ],
282+ ["1/6" , "1/30" , "3/10" , "3/10" , "1/30" , "1/6" ]],
283+ ],
284+ None
285+ ),
286+ ]
287+ )
288+ def test_lcp_strategy_rational (game : gbt .Game , mixed_strategy_prof_data : list ,
289+ stop_after : typing .Union [None , int ]):
290+ """Test calls of LCP for mixed strategy equilibria, rational precision
291+ using max_regret (internal consistency); and comparison to a set of previously
292+ computed equilibria using this function (regression test).
293+
294+ This sequence will correspond to the full set of all computed equilibria if stop_after
295+ is None, else the first stop_after-many equilibria.
296+ """
297+ result = gbt .nash .lcp_solve (game , use_strategic = True , rational = True , stop_after = stop_after )
298+
299+ if stop_after :
300+ result = gbt .nash .lcp_solve (game , use_strategic = True , stop_after = stop_after )
301+ assert len (result .equilibria ) == stop_after
302+ else :
303+ # compute all
304+ result = gbt .nash .lcp_solve (game , use_strategic = True )
305+ assert len (result .equilibria ) == len (mixed_strategy_prof_data )
306+ for eq , exp in zip (result .equilibria , mixed_strategy_prof_data ):
307+ assert eq .max_regret () == 0
308+ expected = game .mixed_strategy_profile (rational = True , data = exp )
309+ assert eq == expected
235310
236311
237312def test_lcp_behavior_double ():
0 commit comments