private GameValue Solve(TestParams testParams, bool visualize, ConfigureSolver configureSolver) { if (visualize) { VisActionTree.Show(testParams.ActionTree, Path.Combine(_outDir, String.Format("{0}-at.gv", testParams.Name))); VisChanceTree.Show(testParams.ChanceTree, Path.Combine(_outDir, String.Format("{0}-ct.gv", testParams.Name))); for (int p = 0; p < testParams.StrategyTrees.Length; ++p) { VisStrategyTree.Show(testParams.StrategyTrees[p], Path.Combine(_outDir, string.Format("{0}-st-{1}.gv", testParams.Name, p))); } } // Make sure input is correct. for (int p = 0; p < testParams.ChanceTree.Nodes[0].Position; ++p) { string errorText; Assert.IsTrue(VerifyAbsStrategy.Verify(testParams.StrategyTrees[p], p, 0.000001, out errorText), errorText); } GameValue gv = new GameValue { ChanceTree = testParams.ChanceTree, ActionTree = testParams.ActionTree, Strategies = testParams.StrategyTrees }; gv.PrepareVis = visualize; if (configureSolver != null) { configureSolver(gv); } gv.Solve(); if (visualize) { for (int p = 0; p < testParams.ChanceTree.PlayersCount; ++p) { GameValue.Vis.Show(gv, p, Path.Combine(_outDir, String.Format("{0}-{1}-val.gv", testParams.Name, p))); } } Assert.AreEqual(2, gv.Values.Length); for (int p = 0; p < testParams.ChanceTree.PlayersCount; ++p) { Console.WriteLine("Game value pos {0}: {1}", p, gv.Values[p]); Assert.AreEqual(testParams.ExpectedResult[p], gv.Values[p], testParams.Epsilon); } return(gv); }
private void Solve(TestParams testParams, bool visualize, ConfigureSolver configureSolver) { if (visualize) { VisActionTree.Show(testParams.ActionTree, Path.Combine(_outDir, String.Format("{0}-at.gv", testParams.Name))); VisChanceTree.Show(testParams.ChanceTree, Path.Combine(_outDir, String.Format("{0}-ct.gv", testParams.Name))); } StrategyTree [] eqStrategies = new StrategyTree[testParams.ChanceTree.PlayersCount]; string error; for (int heroPos = 0; heroPos < testParams.ChanceTree.PlayersCount; ++heroPos) { // Create and configure EqLp solver EqLp solver = new EqLp { HeroPosition = heroPos, ChanceTree = testParams.ChanceTree, ActionTree = testParams.ActionTree, }; if (configureSolver != null) { configureSolver(solver); } // Solve EqLp solver.Solve(); eqStrategies[heroPos] = solver.Strategy; if (visualize) { VisStrategyTree.Show(solver.Strategy, Path.Combine(_outDir, string.Format("{0}-eq-{1}.gv", testParams.Name, heroPos))); } // Verify the eq value and strategy Assert.AreEqual(testParams.ExpectedResult[heroPos], solver.Value, testParams.Epsilon, "Wrong eq value"); Assert.IsTrue(VerifyAbsStrategy.Verify(solver.Strategy, solver.HeroPosition, 1e-7, out error), error); } // Verify eq, use another (better) epsilon because EqLp and VerifyEq have better precision // than most of the reference game solvers like OCFR. Assert.IsTrue(VerifyEq.Verify(testParams.ActionTree, testParams.ChanceTree, eqStrategies, 1e-7, out error), error); }
/// <summary> /// Runs the solver with the specified parameters.. /// </summary> /// <param name="iterCounts">Number of iterations for each run, -1 - unlimited.</param> private StrategyTree RunSolver(TestParams testParams, bool visualize, bool trace, int [] iterCounts, ConfigureSolver configureSolver) { int playersCount = testParams.ChanceTree.PlayersCount; string baseDir = Path.Combine(_outDir, testParams.Name); DirectoryExt.Delete(baseDir); Directory.CreateDirectory(baseDir); string inputDir = Path.Combine(baseDir, "input"); Directory.CreateDirectory(inputDir); string traceDir = Path.Combine(baseDir, "trace"); if (trace) { Directory.CreateDirectory(traceDir); } string chanceTreeFile = Path.Combine(inputDir, "ct.dat"); string actionTreeFile = Path.Combine(inputDir, "at.dat"); testParams.ChanceTree.Write(chanceTreeFile); testParams.ActionTree.Write(actionTreeFile); if (visualize) { VisActionTree.Show(testParams.ActionTree, actionTreeFile + ".gv"); VisChanceTree.Show(testParams.ChanceTree, chanceTreeFile + ".gv"); } int runs = iterCounts.Length; Breb solver = null; for (int r = 0; r < runs; ++r) { // Create and configure a solver solver = new Breb { GameDef = testParams.GameDef, ActionTreeFile = actionTreeFile, ChanceTreeFile = chanceTreeFile, OutputPath = baseDir, SnapshotsCount = 2, Epsilon = testParams.Epsilon, ThreadsCount = DEFAULT_THREADS_COUNT, }; if (trace) { solver.TraceDir = traceDir; } solver.MaxIterationCount = iterCounts[r]; if (configureSolver != null) { configureSolver(solver); } solver.Solve(); } string fileName = solver.CurrentSnapshotInfo.StrategyFile; StrategyTree eqStrategy = StrategyTree.Read <StrategyTree>(fileName); if (visualize) { VisStrategyTree.Show(eqStrategy, fileName + ".gv"); } return(eqStrategy); }
/// <summary> /// Solves the game by fictitious play and verifies the solution. /// </summary> /// <param name="snapshotAfter">Number of iterations to make an intermediate snapshot after. -1 for no intermediate snapshot.</param> /// <param name="configureSolver"></param> private void SolveAndVerifyVerifySolution(TestParams testParams, bool visualize, bool trace, int[] iterCounts, ConfigureSolver configureSolver) { int playersCount = testParams.ChanceTree.PlayersCount; StrategyTree eqStrategy = RunSolver(testParams, visualize, trace, iterCounts, configureSolver); string error; // Verify consistency of strategies for (int p = 0; p < 2; ++p) { Assert.IsTrue(VerifyAbsStrategy.Verify(eqStrategy, p, 1e-7, out error), string.Format("Pos {0}: {1}", p, error)); } // Run VerifyEq on the computed strategies. StrategyTree[] strategies = new StrategyTree[] { eqStrategy, eqStrategy }; Assert.IsTrue(VerifyEq.Verify(testParams.ActionTree, testParams.ChanceTree, strategies, 3 * testParams.Epsilon, out error), error); // // Do a redundant test with EqLp // // Find game values for our solution GameValue gv = new GameValue { ActionTree = testParams.ActionTree, ChanceTree = testParams.ChanceTree, Strategies = new StrategyTree[] { eqStrategy, eqStrategy } }; gv.Solve(); // Solve eq with EqLp double[] expEqValues; StrategyTree[] expStrategies = EqLp.Solve(testParams.ActionTree, testParams.ChanceTree, out expEqValues); // Verify the eq value and strategy for (int p = 0; p < 2; ++p) { if (visualize) { Console.WriteLine("Expected eq value pos {0}: {1}", p, expEqValues[p]); } Assert.AreEqual(expEqValues[p], gv.Values[p], testParams.Epsilon, "Eq value differs from EqLp solution"); } }
private void Solve(TestParams testParams, bool visualize, ConfigureSolver configureSolver) { if (visualize) { VisActionTree.Show(testParams.ActionTree, Path.Combine(_outDir, String.Format("{0}-at.gv", testParams.Name))); VisChanceTree.Show(testParams.ChanceTree, Path.Combine(_outDir, String.Format("{0}-ct.gv", testParams.Name))); for (int p = 0; p < testParams.StrategyTrees.Length; ++p) { VisStrategyTree.Show(testParams.StrategyTrees[p], Path.Combine(_outDir, string.Format("{0}-st-{1}.gv", testParams.Name, p))); } } // Make sure input is correct. for (int p = 0; p < testParams.ChanceTree.Nodes[0].Position; ++p) { string errorText; Assert.IsTrue(VerifyAbsStrategy.Verify(testParams.StrategyTrees[p], p, 0.000001, out errorText), errorText); } for (int heroPos = 0; heroPos < testParams.ChanceTree.PlayersCount; ++heroPos) { // Create and configure Br solver Br br = new Br { HeroPosition = heroPos, ChanceTree = testParams.ChanceTree, ActionTree = testParams.ActionTree, }; br.Strategies = new StrategyTree[testParams.ChanceTree.PlayersCount]; for (int opp = 0; opp < testParams.ChanceTree.PlayersCount; ++opp) { if (opp == heroPos) { continue; } br.Strategies[opp] = testParams.StrategyTrees[opp]; } br.PrepareVis = visualize; if (configureSolver != null) { configureSolver(br); } // Solve Br br.Solve(); if (visualize) { Br.Vis.Show(br, Path.Combine(_outDir, String.Format("{0}-br-{1}.gv", testParams.Name, heroPos))); } // Verify the Br value and strategy Assert.AreEqual(testParams.ExpectedResult[heroPos], br.Value, testParams.Epsilon, "Wrong BR value"); string error; Assert.IsTrue(VerifyAbsStrategy.Verify(br.Strategies[br.HeroPosition], br.HeroPosition, out error), error); // Verify Br strategy has the expected value by running an independent GameValue algo on it. GameValue gv = new GameValue { ActionTree = br.ActionTree, ChanceTree = br.ChanceTree, Strategies = br.Strategies }; gv.Solve(); Assert.AreEqual(testParams.ExpectedResult[heroPos], gv.Values[br.HeroPosition], testParams.Epsilon, "Wrong GameValue value"); } }