private bool compute(DecisionNode node)
{
int[] indices = subsets[node].ToArray();
int[] outputSubset = outputs.Get(indices);
if (indices.Length == 0)
{
// The rule employed by this node doesn't cover
// any input points. This node could be removed.
node.Branches = null;
node.Output = null;
return true;
}
int size = indices.Length;
double baselineError = computeError();
baselineError = upperBound(baselineError, size);
int mostCommon = outputSubset.Mode();
double pruneError = computeErrorWithoutSubtree(node, mostCommon);
pruneError = upperBound(pruneError, size);
DecisionNode maxChild = getMaxChild(node);
double replaceError = computeErrorReplacingSubtrees(node, maxChild);
replaceError = upperBound(replaceError, size);
bool changed = false;
if (Math.Abs(pruneError - baselineError) < limit ||
Math.Abs(replaceError - baselineError) < limit)
{
if (replaceError < pruneError)
{
// We should replace the subtree with its maximum child
node.Branches = maxChild.Branches;
node.Output = maxChild.Output;
foreach (var child in node.Branches)
child.Parent = node;
}
else
{
// We should prune the subtree
node.Branches = null;
node.Output = mostCommon;
}
changed = true;
foreach (var child in node)
subsets[child].Clear();
double[][] inputSubset = inputs.Get(indices);
for (int i = 0; i < inputSubset.Length; i++)
trackDecisions(node, inputSubset[i], i);
}
return changed;
}