@@ -356,138 +356,6 @@ def test_nash_strategy_solver(test_case: EquilibriumTestCase, subtests) -> None:
356356]
357357
358358
359- @pytest .mark .nash
360- @pytest .mark .nash_enumpoly_behavior
361- @pytest .mark .parametrize (
362- "game,mixed_behav_prof_data,stop_after" ,
363- [
364- # 2-player zero-sum games
365- (
366- games .create_stripped_down_poker_efg (),
367- [[[[1 , 0 ], ["1/3" , "2/3" ]], [["2/3" , "1/3" ]]]],
368- None ,
369- ),
370- # 2-player non-zero-sum games
371- pytest .param (
372- games .create_one_shot_trust_efg (),
373- [[[[0 , 1 ]], [["1/2" , "1/2" ]]], [[[0 , 1 ]], [[0 , 1 ]]]],
374- # second entry assumes we extend to Nash using only pure behaviors
375- # currently we get [[0, 1]], [[0, 0]]] as a second eq
376- None ,
377- marks = pytest .mark .xfail (reason = "Problem with enumpoly, as per issue #660" ),
378- ),
379- pytest .param (
380- games .create_one_shot_trust_efg (unique_NE_variant = True ),
381- [[[[1 , 0 ]], [[0 , 1 ]]]], # currently we get [[0, 1]], [[0, 0]]] as a second eq
382- None ,
383- marks = pytest .mark .xfail (reason = "Problem with enumpoly, as per issue #660" ),
384- ),
385- (
386- games .create_EFG_for_nxn_bimatrix_coordination_game (3 ),
387- [
388- [[["1/3" , "1/3" , "1/3" ]], [["1/3" , "1/3" , "1/3" ]]],
389- [[["1/2" , "1/2" , 0 ]], [["1/2" , "1/2" , 0 ]]],
390- [[["1/2" , 0 , "1/2" ]], [["1/2" , 0 , "1/2" ]]],
391- [[[1 , 0 , 0 ]], [[1 , 0 , 0 ]]],
392- [[[0 , "1/2" , "1/2" ]], [[0 , "1/2" , "1/2" ]]],
393- [[[0 , 1 , 0 ]], [[0 , 1 , 0 ]]],
394- [[[0 , 0 , 1 ]], [[0 , 0 , 1 ]]],
395- ],
396- None ,
397- ),
398- (
399- games .create_EFG_for_nxn_bimatrix_coordination_game (4 ),
400- [[[["1/4" , "1/4" , "1/4" , "1/4" ]], [["1/4" , "1/4" , "1/4" , "1/4" ]]]],
401- 1 ,
402- ),
403- # 3-player game
404- # (
405- # games.read_from_file("mixed_behavior_game.efg"),
406- # [
407- # [[["1/2", "1/2"]], [["2/5", "3/5"]], [["1/4", "3/4"]]],
408- # [[["2/5", "3/5"]], [["1/2", "1/2"]], [["1/3", "2/3"]]],
409- # ],
410- # 2, # 9 in total found by enumpoly (see unordered test)
411- # ),
412- ##############################################################################
413- ##############################################################################
414- (
415- games .read_from_file ("3_player.efg" ),
416- [
417- [[[1 , 0 ], [1 , 0 ]], [[1 , 0 ], ["1/2" , "1/2" ]], [[1 , 0 ], [0 , 1 ]]],
418- [[[1 , 0 ], [1 , 0 ]], [[1 , 0 ], [0 , 1 ]], [[1 , 0 ], ["1/3" , "2/3" ]]],
419- ],
420- 2 ,
421- ),
422- (
423- games .read_from_file ("3_player_with_nonterm_outcomes.efg" ),
424- [
425- [[[1 , 0 ], [1 , 0 ]], [[1 , 0 ], ["1/2" , "1/2" ]], [[1 , 0 ], [0 , 1 ]]],
426- [[[1 , 0 ], [1 , 0 ]], [[1 , 0 ], [0 , 1 ]], [[1 , 0 ], ["1/3" , "2/3" ]]],
427- ],
428- 2 ,
429- ),
430- ##############################################################################
431- ##############################################################################
432- (
433- games .read_from_file ("2_player_non_zero_sum.efg" ),
434- [[[["1/3" , "2/3" ]], [["1/2" , "1/2" ]]]],
435- 1 ,
436- ),
437- (
438- games .read_from_file ("2_player_non_zero_sum_missing_term_outcome.efg" ),
439- [[[["1/3" , "2/3" ]], [["1/2" , "1/2" ]]]],
440- 1 ,
441- ),
442- ##############################################################################
443- ##############################################################################
444- (
445- games .read_from_file ("chance_in_middle.efg" ),
446- [
447- [[["3/11" , "8/11" ], [1 , 0 ], [1 , 0 ], [1 , 0 ], [1 , 0 ]], [[1 , 0 ], ["6/11" , "5/11" ]]],
448- ], # [[[1, 0], [1, 0], [1, 0], [0, 0], [0, 0]], [[0, 1], [1, 0]]],
449- # [[[0, 1], [0, 0], [0, 0], [1, 0], [1, 0]], [[1, 0], [0, 1]]],
450- 1 , # subsequent eqs have undefined infosets; include after #issue 660
451- ),
452- (
453- games .read_from_file ("chance_in_middle_with_nonterm_outcomes.efg" ),
454- [
455- [[["3/11" , "8/11" ], [1 , 0 ], [1 , 0 ], [1 , 0 ], [1 , 0 ]], [[1 , 0 ], ["6/11" , "5/11" ]]],
456- ], # [[[1, 0], [1, 0], [1, 0], [0, 0], [0, 0]], [[0, 1], [1, 0]]],
457- # [[[0, 1], [0, 0], [0, 0], [1, 0], [1, 0]], [[1, 0], [0, 1]]],
458- 1 ,
459- ),
460- ],
461- )
462- def test_enumpoly_ordered_behavior (
463- game : gbt .Game , mixed_behav_prof_data : list , stop_after : None | int
464- ):
465- """Test calls of enumpoly for mixed behavior equilibria,
466- using max_regret and agent_max_regret (internal consistency); and
467- comparison to a set of previously computed equilibria with this function (regression test).
468- This set will be the full set of all computed equilibria if stop_after is None,
469- else the first stop_after-many equilibria.
470-
471- """
472- if stop_after :
473- result = gbt .nash .enumpoly_solve (
474- game , use_strategic = False , stop_after = stop_after , maxregret = 0.00001
475- )
476- assert len (result .equilibria ) == stop_after
477- else :
478- # compute all
479- result = gbt .nash .enumpoly_solve (game , use_strategic = False )
480- assert len (result .equilibria ) == len (mixed_behav_prof_data )
481- for eq , exp in zip (result .equilibria , mixed_behav_prof_data , strict = True ):
482- assert abs (eq .max_regret ()) <= TOL
483- assert abs (eq .agent_max_regret ()) <= TOL
484- expected = game .mixed_behavior_profile (rational = True , data = exp )
485- for p in game .players :
486- for i in p .infosets :
487- for a in i .actions :
488- assert abs (eq [p ][i ][a ] - expected [p ][i ][a ]) <= TOL
489-
490-
491359ENUMPOLY_AGENT_CASES = [
492360 # #############################################################
493361 # Examples where Nash pure behaviors and agent-form pure equillibrium behaviors coincide
0 commit comments