private static GamePlayerBenchmark.SampleState SelectOrCreateChildAtRandom(Random r, GraphicalModel model, int[] variables, int[] variableSizes, IList <GamePlayerBenchmark.SampleState> children, ConcatVector[] humanFeatureVectors) { int i = r.NextInt(variables.Length); int variable = variables[i]; int observation = r.NextInt(variableSizes[i]); foreach (GamePlayerBenchmark.SampleState s in children) { if (s.variable == variable && s.observation == observation) { return(s); } } int humanObservationVariable = 0; foreach (GraphicalModel.Factor f in model.factors) { foreach (int j in f.neigborIndices) { if (j >= humanObservationVariable) { humanObservationVariable = j + 1; } } } GraphicalModel.Factor f_1 = model.AddFactor(new int[] { variable, humanObservationVariable }, new int[] { variableSizes[i], variableSizes[i] }, null); model.factors.Remove(f_1); GamePlayerBenchmark.SampleState newState = new GamePlayerBenchmark.SampleState(f_1, variable, observation); children.Add(newState); return(newState); }
////////////////////////////////////////////////////////////// // This is an implementation of something like MCTS, trying to take advantage of the general speed gains due to fast // CliqueTree caching of dot products. It doesn't actually do any clever selection, preferring to select observations // at random. ////////////////////////////////////////////////////////////// private static void Gameplay(Random r, GraphicalModel model, ConcatVector weights, ConcatVector[] humanFeatureVectors) { IList <int> variablesList = new List <int>(); IList <int> variableSizesList = new List <int>(); foreach (GraphicalModel.Factor f in model.factors) { for (int i = 0; i < f.neigborIndices.Length; i++) { int j = f.neigborIndices[i]; if (!variablesList.Contains(j)) { variablesList.Add(j); variableSizesList.Add(f.featuresTable.GetDimensions()[i]); } } } int[] variables = variablesList.Stream().MapToInt(null).ToArray(); int[] variableSizes = variableSizesList.Stream().MapToInt(null).ToArray(); IList <GamePlayerBenchmark.SampleState> childrenOfRoot = new List <GamePlayerBenchmark.SampleState>(); CliqueTree tree = new CliqueTree(model, weights); int initialFactors = model.factors.Count; // Run some "samples" long start = Runtime.CurrentTimeMillis(); long marginalsTime = 0; for (int i_1 = 0; i_1 < 1000; i_1++) { log.Info("\tTaking sample " + i_1); Stack <GamePlayerBenchmark.SampleState> stack = new Stack <GamePlayerBenchmark.SampleState>(); GamePlayerBenchmark.SampleState state = SelectOrCreateChildAtRandom(r, model, variables, variableSizes, childrenOfRoot, humanFeatureVectors); long localMarginalsTime = 0; // Each "sample" is 10 moves deep for (int j = 0; j < 10; j++) { // log.info("\t\tFrame "+j); state.Push(model); System.Diagnostics.Debug.Assert((model.factors.Count == initialFactors + j + 1)); /////////////////////////////////////////////////////////// // This is the thing we're really benchmarking /////////////////////////////////////////////////////////// if (state.cachedMarginal == null) { long s = Runtime.CurrentTimeMillis(); state.cachedMarginal = tree.CalculateMarginalsJustSingletons(); localMarginalsTime += Runtime.CurrentTimeMillis() - s; } stack.Push(state); state = SelectOrCreateChildAtRandom(r, model, variables, variableSizes, state.children, humanFeatureVectors); } log.Info("\t\t" + localMarginalsTime + " ms"); marginalsTime += localMarginalsTime; while (!stack.Empty()) { stack.Pop().Pop(model); } System.Diagnostics.Debug.Assert((model.factors.Count == initialFactors)); } log.Info("Marginals time: " + marginalsTime + " ms"); log.Info("Avg time per marginal: " + (marginalsTime / 200) + " ms"); log.Info("Total time: " + (Runtime.CurrentTimeMillis() - start)); }