private double CalculateMaximumProbabilityOfCid(AutoResizeBigVector <double> cache, double[] stateProbabilities, long currentCid) { if (cache != null && HasCacheEntry(cache, currentCid)) { return(cache[(int)currentCid]); } var result = double.NaN; NestedMarkovDecisionProcess.ContinuationGraphElement cge = Nmdp.GetContinuationGraphElement(currentCid); if (cge.IsChoiceTypeUnsplitOrFinal) { var cgl = Nmdp.GetContinuationGraphLeaf(currentCid); result = stateProbabilities[cgl.ToState]; } else { var cgi = Nmdp.GetContinuationGraphInnerNode(currentCid); if (cge.IsChoiceTypeForward) { // Note, cgi.Probability is used in the branch "else if (cge.IsChoiceTypeProbabilitstic)" result = CalculateMaximumProbabilityOfCid(cache, stateProbabilities, cgi.FromCid); } if (cge.IsChoiceTypeNondeterministic) { var biggest = double.NegativeInfinity; for (var i = cgi.FromCid; i <= cgi.ToCid; i++) { var resultOfChild = CalculateMaximumProbabilityOfCid(cache, stateProbabilities, i); if (resultOfChild > biggest) { biggest = resultOfChild; } } result = biggest; } else if (cge.IsChoiceTypeProbabilitstic) { var sum = 0.0; for (var i = cgi.FromCid; i <= cgi.ToCid; i++) { var transitionProbability = Nmdp.GetContinuationGraphElement(i).Probability; var resultOfChild = CalculateMaximumProbabilityOfCid(cache, stateProbabilities, i); sum += transitionProbability * resultOfChild; } result = sum; } } if (cache != null) { cache[(int)currentCid] = result; } return(result); }
private static void ExportCid(NestedMarkovDecisionProcess nmdp, TextWriter sb, string fromNode, bool fromProbabilistic, long currentCid) { NestedMarkovDecisionProcess.ContinuationGraphElement cge = nmdp.GetContinuationGraphElement(currentCid); if (cge.IsChoiceTypeUnsplitOrFinal) { var cgl = nmdp.GetContinuationGraphLeaf(currentCid); var thisNode = $"cid{currentCid}"; sb.WriteLine($" {thisNode} [ shape=point,width=0.1,height=0.1,label=\"\" ];"); if (fromProbabilistic) { sb.WriteLine($" {fromNode}->{thisNode} [ arrowhead =\"onormal\", label=\"{cgl.Probability.ToString(CultureInfo.InvariantCulture)}\"];"); } else { sb.WriteLine($" {fromNode}->{thisNode} [ arrowhead =\"normal\"];"); } sb.WriteLine($" {thisNode} -> {cgl.ToState} [ arrowhead =\"normal\"];"); } else if (cge.IsChoiceTypeForward) { // only forward node (no recursion) // do not print thisNode var cgi = nmdp.GetContinuationGraphInnerNode(currentCid); var toNode = $"cid{cgi.ToCid}"; sb.WriteLine($" {fromNode}->{toNode} [ style =\"dashed\", label=\"{Probability.PrettyPrint(cgi.Probability)}\"];"); } else { // we print how we came to this node var cgi = nmdp.GetContinuationGraphInnerNode(currentCid); var thisNode = $"cid{currentCid}"; sb.WriteLine($" {thisNode} [ shape=point,width=0.1,height=0.1,label=\"\" ];"); if (fromProbabilistic) { sb.WriteLine($" {fromNode}->{thisNode} [ arrowhead =\"onormal\", label=\"{Probability.PrettyPrint(cgi.Probability)}\"];"); } else { sb.WriteLine($" {fromNode}->{thisNode} [ arrowhead =\"normal\"];"); } for (var i = cgi.FromCid; i <= cgi.ToCid; i++) { ExportCid(nmdp, sb, thisNode, cge.IsChoiceTypeProbabilitstic, i); } } }