SMILE Tutorial 4: Performing Inference in Influence Diagrams
In this tutorial we will find out how to compute the expected utilities of the different policies of our influence diagram. We will show where to find and how to interpret the results.
Let us load and update the influence diagram created in the last tutorial:
DSL_network theNet;
theNet.ReadFile("tutorial.dsl");
theNet.UpdateBeliefs();
We are going to declare a bunch of variables to store some results:
int gain = theNet.FindNode("Gain");
DSL_sysCoordinates theCoordinates(*theNet.GetNode(gain)->Value());
DSL_stringArray *theOutcomes;
DSL_intArray theIndexingParents;
DSL_nodeDefinition *theDefinition;
char *hisOutcomeName;
char *hisName;
double ExpectedUtility;
int aParent;
int hisOutcome;
int x;
int result = DSL_OKAY;
Now the question is: what is the expected utility of investing? What about not investing? We will find the numbers in the value node Gain. Let us get the results in exactly the same way that we did in previous examples. One thing to notice is that, when dealing with influence diagrams, the value of every node is "indexed" by the choices of every decision node that affects it. In this case, the value of the node Gain is indexed by the choices of the node Invest (as may seem evident). We should use the DSL_nodeValue method GetIndexingParents. This will return a list with the handles of the nodes that index this value. In the present case, the list should contain only one handle: the handle of the node Invest.
theIndexingParents = theNet.GetNode(gain)->Value()->GetIndexingParents();
We are going to use theCoordinates as an "odometer". We will start our trip from mile (0,0,&ldots;,0) and we will go incrementing it until it cannot be incremented anymore (Next will return an error code). At each step, we will use the contents of our odometer to know the state of each of the indexing parents of the node Gain (in this case, just one: node Invest).
for (x=0; x<theIndexingParents.NumItems(); x++)
This loop will go through all the digits of the "odometer". We are going to need the name of each indexing parent and also the state given by the corresponding digit of the odometer. Therefore, the first thing we need to know is the handle of the current indexing parent:
aParent = theIndexingParents[x];
Now we need the name of the state that the odometer shows for him. We get the array with all the names and select the one whose index is in the current coordinates of the odometer:
theDefinition = theNet.GetNode(aParent)->Definition(); theOutcomesNames = theDefinition->GetOutcomesNames(); hisOutcome = theCoordinates[x]; hisOutcomeName = (*theOutcomesNames)[hisOutcome];
Now get the name of the indexing parent:
hisName = theNet.GetNode(aParent)->Info().Header().GetId();
printf(" Node \"%s\" = %s\n",hisName,hisOutcomeName);
And get the expected utility for that policy:
ExpectedUtility = theCoordinates.UncheckedValue();
printf(" Expected Utility = %f\n\n",ExpectedUtility);
Increment the odometer to go to the next policy:
result = theCoordinates.Next();
The best policy is, evidently, the one that yields the highest expected utility. In the next tutorial we will learn how to compute the value of information of a node.