double percentageDone = 0;
double valueDone = 0;
double maxToDo = 0;
List<Distribution> valueDistributions = new ArrayList<Distribution>(children.size());
for (Pair<ActionWrapper, WeightedNode> pair : children) {
WeightedNode child = pair.getRight();
double prob = child.getWeight();
double upperWinBound = child.getNode().getUpperWinBound();
maxToDo += prob*upperWinBound;
}
for (int i=0;i<children.size();i++) {
Pair<ActionWrapper, WeightedNode> pair = children.get(i);
WeightedNode child = pair.getRight();
double upperWinBound = child.getNode().getUpperWinBound();
double prob = child.getWeight();
maxToDo -= prob*upperWinBound;
int requiredFromSubtree = (int)((lowerBound-valueDone-maxToDo)/prob);
if(config.isUseAlphaBetaPruning() && requiredFromSubtree>upperWinBound){
//prune
for(int j=i;j<children.size();j++){
for (NodeVisitor visitor : visitors) {
Pair<ActionWrapper,WeightedNode> skipped = children.get(j);
Pair<ActionWrapper, GameTreeNode> node = new Pair<ActionWrapper, GameTreeNode>(skipped.getLeft(), skipped.getRight().getNode());
visitor.pruneSubTree(node, new Distribution(node.getRight().getUpperWinBound(),0,true), requiredFromSubtree);
}
}
valueDistribution = new Distribution(valueDone+prob*upperWinBound+maxToDo,0.0, true);
//forget last game state!
config.getOpponentModel().forgetLastAssumption();
return valueDistribution;
}
percentageDone += prob;
for (NodeVisitor visitor : visitors) {
visitor.enterNode(new Pair<ActionWrapper, GameTreeNode>(pair.getLeft(), pair.getRight().getNode()), requiredFromSubtree);
}
Distribution valueDistribution = child.getNode().getValueDistribution(requiredFromSubtree);
for (NodeVisitor visitor : visitors) {
visitor.leaveNode(new Pair<ActionWrapper, GameTreeNode>(pair.getLeft(), pair.getRight().getNode()), valueDistribution);
}
valueDone += prob*valueDistribution.getMean();
valueDistributions.add(valueDistribution);