// // For all given nodes in this problem, generate the single maximal problem // // This is done is a convluted way to speed up execution since we need to combine in the size of the powerset of cardinality of givens // private void GenerateMaximalProblemFromSingleEdge(ProblemHashMap <Hypergraph.EdgeAnnotation> memoizedProblems, HyperEdgeMultiMap <Hypergraph.EdgeAnnotation> edgeDatabase, Problem <Hypergraph.EdgeAnnotation> baseProblem) { // Create all simple problems by pursuing only a single path backward in the givens: append // all problems from a given to the base problem // // | // v // given __ // | | // v | baseProblem // goal __| // // Acquire all of the problems for the singleton sets of the powerset for all of the givens of this problem List <Problem <Hypergraph.EdgeAnnotation> >[] singletonMapToNewProblems = new List <Problem <Hypergraph.EdgeAnnotation> > [baseProblem.givens.Count]; List <Problem <Hypergraph.EdgeAnnotation> >[] singletonMapToOriginalProblems = new List <Problem <Hypergraph.EdgeAnnotation> > [baseProblem.givens.Count]; bool generatedNewProblems = false; for (int g = 0; g < baseProblem.givens.Count; g++) { // Acquire the original problems and save them singletonMapToOriginalProblems[g] = GenerateAllMaximalProblemsFrom(memoizedProblems, edgeDatabase, baseProblem.givens[g]); if (singletonMapToOriginalProblems[g] == null) { singletonMapToOriginalProblems[g] = new List <Problem <Hypergraph.EdgeAnnotation> >(); } // Using the original problems, append them to the base problem singletonMapToNewProblems[g] = new List <Problem <Hypergraph.EdgeAnnotation> >(); // Append all of these given problems to the base problem foreach (Problem <Hypergraph.EdgeAnnotation> problem in singletonMapToOriginalProblems[g]) { Problem <Hypergraph.EdgeAnnotation> baseProblemCopy = new Problem <Hypergraph.EdgeAnnotation>(baseProblem); baseProblemCopy.Append(graph, edgeDatabase, problem); //memoizedProblems.Put(baseProblemCopy); singletonMapToNewProblems[g].Add(baseProblemCopy); generatedNewProblems = true; } } if (baseProblem.goal == 98) { //Debug.WriteLine("98NO-OP"); } // If we did not perform any appending, we have reached a maximal situation // Add the maximal problem to the database if (!generatedNewProblems) { // Determine suppression now to mitigate number of problems added baseProblem.DetermineSuppressedGivens(graph); memoizedProblems.Put(baseProblem); return; } // // Stitch together all of the possible combinations of maximal problems // // | | | // | | | // v v v // g_1 g_2 ... g_n __ // | | baseProblem // v | // target __| // // // We are looking for the maximal set of problems; therefore, we don't need all combinations. // What we do require is the combining of all generated problems with the base problem. // // Find all the sets of populated new problems List <int> populatedIndices = new List <int>(); for (int index = 0; index < singletonMapToNewProblems.Length; index++) { if (singletonMapToNewProblems[index].Any()) { populatedIndices.Add(index); } } List <Problem <Hypergraph.EdgeAnnotation> > maximalProblems = new List <Problem <Hypergraph.EdgeAnnotation> >(singletonMapToNewProblems[populatedIndices[0]]); populatedIndices.RemoveAt(0); foreach (int index in populatedIndices) { //int count = 0; List <Problem <Hypergraph.EdgeAnnotation> > tmpMaximalProbs = new List <Problem <Hypergraph.EdgeAnnotation> >(); foreach (Problem <Hypergraph.EdgeAnnotation> singleton in singletonMapToOriginalProblems[index]) { foreach (Problem <Hypergraph.EdgeAnnotation> problem in maximalProblems) { //if (baseProblem.goal == 98) //{ // Debug.WriteLine(count++); //} Problem <Hypergraph.EdgeAnnotation> problemCopy = new Problem <Hypergraph.EdgeAnnotation>(problem); // It is possible for a problem to have been created which deduced further information with an additional edge; // that is, a given node was pushed into the path of the problem. Hence, no need to append in this situation if (problem.givens.Contains(singleton.goal)) { problemCopy.Append(graph, edgeDatabase, singleton); } tmpMaximalProbs.Add(problemCopy); } } maximalProblems = tmpMaximalProbs; } // Add all the maximal problems to the database foreach (Problem <Hypergraph.EdgeAnnotation> problem in maximalProblems) { // Determine suppression now to mitigate number of problems added problem.DetermineSuppressedGivens(graph); memoizedProblems.Put(problem); } }
// // For all given nodes in this problem, generate all problems // // This is done is a convluted way to speed up execution since we need to combine in the size of the powerset of cardinality of givens // private void GenerateAllProblemsFromSingleEdge(ProblemHashMap <Hypergraph.EdgeAnnotation> memoizedProblems, HyperEdgeMultiMap <Hypergraph.EdgeAnnotation> edgeDatabase, Problem <Hypergraph.EdgeAnnotation> baseProblem) { // Create all simple problems by pursuing only a single path backward in the givens: append // all problems from a given to the base problem // // | // v // given __ // | | // v | baseProblem // goal __| // // Acquire all of the problems for the singleton sets of the powerset for all of the givens of this problem List <Problem <Hypergraph.EdgeAnnotation> >[] singletonMapToNewProblems = new List <Problem <Hypergraph.EdgeAnnotation> > [baseProblem.givens.Count]; List <Problem <Hypergraph.EdgeAnnotation> >[] singletonMapToOriginalProblems = new List <Problem <Hypergraph.EdgeAnnotation> > [baseProblem.givens.Count]; for (int g = 0; g < baseProblem.givens.Count; g++) { // Acquire the original problems and save them singletonMapToOriginalProblems[g] = GenerateAllProblemsFrom(memoizedProblems, edgeDatabase, baseProblem.givens[g]); if (singletonMapToOriginalProblems[g] == null) { singletonMapToOriginalProblems[g] = new List <Problem <Hypergraph.EdgeAnnotation> >(); } // Using the original problems, append them to the base problem singletonMapToNewProblems[g] = new List <Problem <Hypergraph.EdgeAnnotation> >(); // Append all of these given problems to the base problem foreach (Problem <Hypergraph.EdgeAnnotation> problem in singletonMapToOriginalProblems[g]) { Problem <Hypergraph.EdgeAnnotation> baseProblemCopy = new Problem <Hypergraph.EdgeAnnotation>(baseProblem); baseProblemCopy.Append(graph, edgeDatabase, problem); memoizedProblems.Put(baseProblemCopy); singletonMapToNewProblems[g].Add(baseProblemCopy); } } // If there was only 1 given, we need to perform a powerset combining if (baseProblem.givens.Count == 1) { return; } // // Stitch together all of the possible combinations of problems that will result; // note this is a POWERSET construction of all possible problems; hence, note exponential explosion in number of problems // // | | // | | // v v // g_1 g_2 ... g_n __ // | | baseProblem // v | // target __| // // | | // | | // v v // g_1 g_2 ... g_n __ // | | baseProblem // v | // target __| // // | | | // | | | // v v v // g_1 g_2 ... g_n __ // | | baseProblem // v | // target __| // // Acquire an encoded list of subsets: the powerset for the number of givens in this problem List <string> powerset = Utilities.ConstructPowerSetStringsWithNoEmpty(baseProblem.givens.Count, baseProblem.givens.Count); // <-- We avoid generating singleton sets // Maps a subset string representation (from the powerset) to the list of problems that it results in. Dictionary <string, List <Problem <Hypergraph.EdgeAnnotation> > > powersetMapToProblems = new Dictionary <string, List <Problem <Hypergraph.EdgeAnnotation> > >(powerset.Count); // // For every combination of possible problems (a subset of the powerset), we combine problems // // Note, the Utilities generated the powerset in the specific sorted ordering of lower cardinality sets first (also values in subset are increasing) // So a typical subset string is given by 012 or 023 foreach (string subset in powerset) { // Break the subset string into its constituent elements: <Arbitrary subset, singleton> KeyValuePair <string, int> splitSubset = Utilities.SplitStringIntoKnownToProcess(subset); // Subset Problems; given the subset {012}: {01} List <Problem <Hypergraph.EdgeAnnotation> > subsetProblems; if (!powersetMapToProblems.TryGetValue(splitSubset.Key, out subsetProblems)) { // Use the singleton list; ASCII conversion of char to int subsetProblems = singletonMapToNewProblems[Convert.ToInt32(splitSubset.Key)]; } // Singleton tails; given the subset {012}: {2} List <Problem <Hypergraph.EdgeAnnotation> > singletonProblems = singletonMapToOriginalProblems[splitSubset.Value]; // Combine the precomputed powerset subset (.Key) guiding the appending of the singleton (.Value) problems List <Problem <Hypergraph.EdgeAnnotation> > combinedSubsetProblems = new List <Problem <Hypergraph.EdgeAnnotation> >(); foreach (Problem <Hypergraph.EdgeAnnotation> subsetProblem in subsetProblems) { foreach (Problem <Hypergraph.EdgeAnnotation> singletonProb in singletonProblems) { // It is possible for a problem to have been created which deduced further information with an additional edge; // that is, a given node was pushed into the path of the problem. Hence, no need to append in this situation if (subsetProblem.givens.Contains(singletonProb.goal)) { // Combine the two problems and record Problem <Hypergraph.EdgeAnnotation> subsetProblemCopy = new Problem <Hypergraph.EdgeAnnotation>(subsetProblem); subsetProblemCopy.Append(graph, edgeDatabase, singletonProb); memoizedProblems.Put(subsetProblemCopy); combinedSubsetProblems.Add(subsetProblemCopy); } } } // We have calculated the problems for this subset, keep track of them powersetMapToProblems.Add(subset, combinedSubsetProblems); } }